I try to "limit" the amount of angular movement my character is able to "show". I'm using Unity.
I have 3 components in my player entity as below:
The "Player" contains a Rigidbody2D
responsible for the movement. The "Body" is an animated sprite that (up to now) moves alongside the Player entity. So it is able to move the sprite around the "full circle".
My main problem is, that once it crosses the y-Axis (z-Axis rotation > Abs(90)
), the "Body" is upside down which is really looking weird. Furthermore, it the "style" of my game does not really support the player "visually" going directly upward or downward the y-Axis. That's why I want to do 2 things:
- "Flip" the "body" (mirror on the y-Axis) once the z-Axis rotation is above/below 90.
- Limit the visual (just the visual) representation of the player's facing direction - see image below red area - so the player is never shown going directly up or down (the Rigidbody2D still can move in this direction, it's just not visualized that way).
My current rotation logic is quite simple:
var angle = Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg;
var angular = Mathf.LerpAngle(transform.rotation.eulerAngles.z, angle, this._behaviorBase.MaxAngularAcceleration * Time.deltaTime);
angular = (angular + DEG_IN_2PI) % DEG_IN_2PI;
var angularDirection = Quaternion.Euler(0f, 0f, angular);
this._body.SetRotation(angularDirection);
This just rotates the player's Rigidbody2D into the movement direction. I'm also able to "counter-rotate" the "Body" component inside the "Player" component so that it always looks in the same direction (unaffected by the Rigidbody movement) with this:
var angle = Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg;
var angular = Mathf.LerpAngle(transform.rotation.eulerAngles.z, angle,
this._behaviorBase.MaxAngularAcceleration * Time.deltaTime);
angular = (angular + DEG_IN_2PI) % DEG_IN_2PI;
var angularDirection = Quaternion.Euler(0f, 0f, angular);
this._body.SetRotation(angularDirection);
// new code for counter rotation
var counterDirection = Quaternion.Euler(0f, 0f, this._body.transform.rotation.z * 1f);
this._bodyTransform.rotation = counterDirection;
But whatever I try to flip the Body at the y-Axis, does not work and only rotated by 90 degrees instead of the full 180. Furthermore, I have quite some problems figuring out how to correctly "clamp" the rotation between -45 < rotation < 45
and 135 < rotation < 225
because the rotation could be either in the positive or negative rotation representation.
Any tips on how to solve this would be highly appreciated.
EDIT 1:
@Kevin: This is the player:
I want to make sure that it can never look like this
The "visible rotation" should never exceed z-Axis angles of +-45 degree (but the Rigidbody should be able to rotate further)
Also, in case the rotation is in the other direction it should be flipped like this
In all cases, the rotation along the z-Axis should be between -45/+45 degrees.