Hello, I am currently writing a system to allow moving platforms to follow a series of waypoints. Part of my needs for the system is for the platforms to be able to rotate according to the orientation of the waypoint.
The platform, as you could guess, is entirely physics based, and I have made it a point to only use physics objects to act on it.
That being said, the meat of my problem is this:
For a given two angles and rotational speed variable, how can I get a vector that describes an angular velocity for one of these angles rotating towards the other?
This is what I have tried so far:
-- Get the difference between the two angles
local getAngleDelta = function(cf1, cf2)
local diff = cf1:Inverse() * cf2
local x, y, z = diff:ToEulerAnglesYXZ()
local eulers = Vector3.new(x, y, z)
return eulers
end
-- Get the desired velocity, given the delta angle and the turn speed.
local getAngVel = function(deltaAngle)
local turnSpeed = ride.Model.TurnSpeed.Value
local dir = deltaAngle.Unit
local turnVel = dir * turnSpeed
return turnVel
end
local deltaAng = getAngleDelta(modelRoot.CFrame, targetCf) -- The change in angle between the ride and the target
local newAngVel = getAngVel(deltaAng) -- The angular velocity towards the change
local turnEst = deltaAng.Magnitude/newAngVel.Magnitude -- The estimate, in seconds, to get to the location
The “newAngVel” variable is then applied to the angular velocity instance.
This seems to work in very select situations with very particular rotational values. I haven’t pinned down exactly what causes the inconsistencies, but it never produces the desired effect 100% of the time.
This is the code that defines this debugging:
Summary
for x = 1,10 do
local pos = Vector3.new(0 + x * 5, 30, 0)
local part = Instance.new("Part", game.Workspace)
part.Anchored = true
local per = x/10
local effectiveVel = newAngVel
effectiveVel = newAngVel * turnEst * x
part.CFrame = CFrame.new(pos) * (modelRoot.CFrame - modelRoot.CFrame.p) * CFrame.Angles(effectiveVel.X, effectiveVel.Y, effectiveVel.Z)
table.insert(parts, part)
end
coroutine.resume(coroutine.create(function()
wait(updateRate)
for i,v in pairs(parts) do
v:Destroy()
end
end))
Here is a video of what I have in action, with some debug parts I have created. These parts represent, from right to left, 10 states of rotation, from the current rotation of the ride, to the desired rotation, based on my code from earlier. Ideally, there would be a linear progression from the current state of the ride to the final rotation of the waypoint.
As you can see, the various states are all over the place in terms of accuracy. Sometimes it shows a linear progression, sometimes it doesn’t. This is how I know that there has to be something I’m doing fundamentally wrong.
I hope there comes to be a solution to this. I was never the best with trig nor angles and general. A trigonometric explanation would be great!