I am really bad at math(s), and just had a unsuccessful day trying to recreate the transform.RotateAround functionality in ECS. Through my research I found this thread , which includes the function for the translation; but I couldn’t figure out how to make it rotate (for my needs) as well.
What I want is:
player can rotate about local y axis using mouse
players rotation stays “in sync” with position around sphere
Maybe this gif can better illustrate:
InsignificantMindlessBluegill
In this case, the rotation veers “off course” (while just holding down one button, no mouse input) as soon as you start moving in any second axis (here is image of the path in a separate run).
I suspect the solution will be embarrassingly easy, just my poor brain could not get with it ;(. It’s the end of the day for me, thank you all in advanced; here is the code I left off with:
First of all you should do all that in a Bursted Job so you can take advantage of multi-threading and burst compiler.
This is what i use to rotate around a center point in a certain axis.
public static float4x4 RotateAround(LocalToWorld localToWorld, float3 center, float3 axis, float angle) {
var initialRot = quaternion.LookRotationSafe(localToWorld.Forward, localToWorld.Up);
var rotAmount = quaternion.AxisAngle(axis, angle);
var finalPos = center + math.mul(rotAmount, localToWorld.Position - center);
var finalRot = math.mul(math.mul(initialRot, math.mul(math.inverse(initialRot), rotAmount)), initialRot);
return new float4x4(finalRot, finalPos);
}
In my case use mouse input to rotate the camera around another object.
Hope this helps you going forward.
Hi GilCat,
In order to rotate this in two dimensions, how do you get the float3 axis to rotate about? Or do you call this function twice in in separate axis?
I’m still not sure how to rotate about “local y axis” while keeping orientation with the sphere.
Also I am unsure if this functionality deserves to be put in a job, since it will only be applying to one entity I think it would be overkill. I will probably use PostUpdateCommands once I get it working.
Anyways, I’ll be sure to keep your function in mind while experimenting today, hopefully more luck this morning.
Thanks
Actually you got me interested in: var finalRot = math.mul(math.mul(initialRot, math.mul(math.inverse(initialRot), rotAmount)), initialRot);
Perhaps this is the key, could you explain how it works or maybe point to where I can read more about it?
Unfortunately I’m really bad a math so I can’t figure it out haha.
It’s got me interested since I’m just used to seeing (using) something like:
Ahh nevermind… that’s exactly what I needed! Thank you very much GilCat it works perfect :). If you dont mind I’ve got a couple of questions I would like to ask:
Is there a way to directly convert a float4 to a float3, right now I am using a Matrix4x4 and a Vector3 to convert so I assume it must be possible?
Do you know a way to get up, forward, right etc… directions from a float4x4 representing rotation and translation? Right now I am using a “temp” LocalToWorld.Value
Here is working code for anyone who wants it in future, probably will need fixing:
No problem. Glad I could help.
About your questions:
Yes. float4 has a xyz property that gives you a float3.
LocalToWorld has a Position, Forward and Up properties but you can also get that from float4x4.
In float4x4, c0 is Right vector, c1 is Up vector, c2 is Forward vector and c3 is Position.
You should use JobComponentSystem instead alongside with bursted jobs.
The way i would do it would be to have a system to collect player input and another to process that input.
In DOD concerns should be separated as much as possible.