Tanks turret rotate, not snap.
Hi! im pretty new to making games in unity, and im kinda stuck.
Im making a 2D pixelart game where you fight as Tanks, using a controller. Im struggling with the rotation of the turret. (i have it so it will only aim in 8 directions)
As i have it now, it works. But i want to stop it from snapping over to the new controller angle. I want it to go around, as in over the other angles before its where its supposed to be. Like it would if it was a real one.
Is there an easy solution to make it rotate around like in the sketch i have?
The aiming script im using now is:
_rotXMove = Input.GetAxisRaw(HorizontalInput);
_rotYMove = Input.GetAxisRaw(VerticalInput);
_angle = Mathf.Atan2(_rotYMove, _rotXMove) * Mathf.Rad2Deg + 90f;
if (_rotXMove != 0 && _rotYMove != 0)
{
transform.localEulerAngles = new Vector3(0f, 0f, Mathf.Round(_angle / _SnapAngles) * _SnapAngles);
}
I really hope someone can help me.
Thanks!
Answer by unity_ek98vnTRplGj8Q · Mar 11, 2020 at 05:05 PM
So if you want a smooth rotation you can use either Quaternion.Slerp or Quaternion.RotateTowards --
private Quaternion targetRotation;
void Start () {
targetRotation = transform.localRotation;
}
void Update () {
//blah blah blah
if (_rotXMove != 0 && _rotYMove != 0) {
targetRotation = new Vector3 (0f, 0f, Mathf.Round (_angle / _SnapAngles) * _SnapAngles);
}
transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, speed*Time.deltaTime);
//OR
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, targetRotation, speed*Time.deltaTime);
}
Where RotateTowards will move at a constant speed while Slerp will move faster at the beginning and slower as it approaches the target rotation.
If you want it to not rotate perfectly smooth but instead just snap to all the intermediate angles, there isn't really a clean helper function that I can think of off the top of my head, but it should be relatively easy to calculate out the intermediate angles by hand and snap over timer sequentially
Thank you!
that helped a lot! it didnt give me the complete answer, but at least i got the rotation working! :)
i just made the shooting point a seperate object (empty) on the tank's wheels, move it with the rotation of the tank body and make that snap to those angles. then another point to work with the different angles of the tank in an animation blend tree. (hasnt caused any problems yet.)
if (this.transform.parent.rotation != _body.transform.rotation)
{
//using the parents rotation, mid point, picking up the body's rotation
this.transform.parent.localEulerAngles = _body.transform.localEulerAngles;
//setting the rotation of the point to match the rotation of the midpoint, but snaps to closest 45 degree.
if (this.transform.parent.localEulerAngles != new Vector3(0f, 0f, $$anonymous$$athf.Round(this.transform.parent.localEulerAngles.z / _snapAngle) * _snapAngle))
{
this.transform.parent.localEulerAngles = new Vector3(0f, 0f, $$anonymous$$athf.Round(this.transform.parent.localEulerAngles.z / _snapAngle) * _snapAngle);
}
}
^ for the rotation of the shooting point.
_myOffset = Vector3.Distance(_animationPoint.transform.position, this.gameObject.transform.position);
if (_animationPoint.transform.position != _shootPoint.transform.position)
{
_animationPoint.transform.position = _shootPoint.transform.position;
}
_direction.x = _animationPoint.transform.localPosition.x + _myOffset - 2.5f;
_direction.y = _animationPoint.transform.localPosition.y + _myOffset - 2.5f;
//_animator.SetBool("Shoot", _shooting);
if (_direction.x != 0 || _direction.y != 0)
{
_animator.SetFloat("Horizontal", _direction.x);
_animator.SetFloat("Vertical", _direction.y);
}
^ for it to work with the animator :3
again! thank you so much!