- Home /
Figured it finally myself out
Mathf.Atan changes instantly even with a slow lerped value
I have two scripts. One is for the players x position and the other one is for the players y rotation. The position script acts like a one dimensional joystick, that goes to its original position over time. Im using Mathf.Atan(), to rotate the player based on the x axis of my "joystick". I used lerp, so the joystick goes slowly into his original position. With the lerp changed, so changes its rotation. But there is a problem. I have a currentPos (the updating mouse position) and a StartPos2 (the mouse position that sets if you click). The StartPos2 goes slowly to the position of currentPos (the distance will be 0 then). The rotation somhow changes instantly, but it should change slowly because of the lerp.
Rotation script (if i remove the * 20, value will be lower but problem doesnt go away):
Quaternion GetQuaternion()
{
Quaternion rot;
float angle;
angle = Mathf.Atan(GetLerpedMoveDist() * Mathf.Rad2Deg / 2) * 20;
rot = Quaternion.Euler(0, -angle, 0);
return rot;
}
"Joystick" script:
float GetLerpedMoveDist()
{
float lerpDist = startPos2.x - currentPos.x;
startPos2 = Vector2.Lerp(startPos2, currentPos, Time.deltaTime * rotSmooth);
return lerpDist;
}
Answer by andrew-lukasik · Apr 08, 2021 at 02:43 PM
startPos2.x - currentPos.x;
is not a valid input for arc tangens ( y/x is ).To smoothly rotate something - you need to interpolate between angles or quaternions, not position vectors.
You may want to use
atan2
as it require a bit less understanding of basic trigonometry.
using UnityEngine;
public class FabulousAdventuresInBasicTrigonometry : MonoBehaviour
{
[SerializeField] float _rotationSpeed = 11;
Vector2 mousePos = Vector2.zero;
Vector2 mouseClickPos = Vector2.zero;
Quaternion _rot = Quaternion.Euler( 0 , 0 , 0 );
void Update ()
{
mousePos = Input.mousePosition;
if( Input.GetMouseButtonDown(0) )
mouseClickPos = Input.mousePosition;
Vector2 dir = mousePos - mouseClickPos;
Quaternion targetRot = Quaternion.Euler( 0 , -Mathf.Atan2(dir.y,dir.x)*Mathf.Rad2Deg , 0 );
// Note: atan gives you counter-clockwise rotation from {y=0,x=1} (right dir vec)
// where Unity uses clockwise rotation starting at {y=1,x=0} (up dir vec)
// so compensate for that accordingly
_rot = Quaternion.Lerp( _rot , targetRot , Time.deltaTime * _rotationSpeed );
Debug.DrawLine( Vector3.zero , _rot*Vector3.right );
}
}
Thanks for helping me, but i actually figured out myself. I had a very very very mistypen thing in the code. I only need Atan and not Atan2, because im working only with the X axis and need to rotate the player based on his direction of swipes. Interpolating between vectors worked and was the only solution for me. I very appreciate your help.