I have Lifters that “carry” an object. I want the object to move and rotate based on how those Lifters move.
I have the object move by setting its velocity to the average of the Lifters’ velocity.
Now, if not all of them move (or if there’s a disparity in their velocities), I want the object to rotate, like so:
This is done by keeping track of how much an individual lifter has moved in a frame from the Object’s position, and calculating the angle via
m_Angle += Vector3.SignedAngle(lastPos - transform.position, currentPos - transform.position). This “movement angle” I add up for every Lifter and then at the end, Rotate the Object via
However, this approach has some problems:
- Calculations are done along the Y axis and therefore does not angle the Object up or down if the Lifters have different vertical positions,
m_Angle actually overshoots, but I found simply dividing
m_Angle by the
number of Lifters made it perfectly accurate. I do not know why this works.
Because I want this to rotate the object in “3 dimensions”, I have attempted to calculate the “euler angles” of each Lifters’ movement via:
Vector3 oldDisplacement = lastPos - transform.position;
Vector3 newDisplacement = currentPos - transform.position;
Quaternion rotation = Quaternion.FromToRotation(oldDisplacement, newDisplacement);
m_EulerAngles += rotation.eulerAngles;
And then at the end, I rotate the Object based on these “movement angles”:
This works in three dimensions, however it is off in the same way that
m_Angle was before I divided it. It rotates the object too far. On top of that it seems to produce rotations along axes that have no displacement.
When I check how much rotation Blue is adding per frame, I get an output like so:
Blue is adding (0.000, 359.507, 0.066); on movement (-0.015, 0.000, 0.000)
The only issue I can perceive is that since the Object’s position is also moved at the end, the angle calculation assumes it is not moving and generates a larger angle (e.g., perhaps
newDisplacement should be something like
currentPos - (transform.position - m_Body.velocity * Time.deltaTime) ). However, removing the Object’s movement from the finalPosition of the Lifter seemingly has no effect.
I’d love a sanity check on the code or approach or if I should approach this problem from a different perspective.