Is there a way to calculate the Euler angle based on a vector? In another engine there is a vec_to_angle(Angle *ang, Vector *dir) function to return the pan and tilt of an Euler angle.
Yes, it is called Vector3.Angle, and it works on the premise that one vector is based on another vector in a zero world environment. This means that Vector3.Angle(transform.forward, transform.InverseTransformPoint(target.position)); would give you the angle from the forward direction to the localized position of a target point. Observe code: Code (csharp): //overall angle from the forward direction var angle=Vector3.Angle(transform.forward, transform.InverseTransformPoint(target.position)); // angle aligned to the X/Z plane (With a Dot gauging if it is positive or negative) var angle=Vector3.Angle(transform.forward, Vector3.Scale(transform.InverseTransformPoint(target.position), Vector3(1,0,1)); angle=Vector3.Dot(Vector3.right, transform.InverseTransformPoint(target.position)) >0.0 ? angle : -angle;
I found that Vector3.Angle only return positive angle. Here is my another thread on this problem. http://forum.unity3d.com/threads/92157-Object-turning-with-joystick-problem
/poke /poke I did provide a piece of code that gives you a negative angle... You have to calculate the negative from one of the values. I gave a Vector3.Dot, but you could easily say that if the transform.InverseTransformPoint(target.position).x is negative, so is the angle. So in your other code, you would test the joystick's y position and see if it is negative. (since you are testing the angle from the X direction) Code (csharp): var turret : Transform; var joystick : Joystick; var turnSpeed: float = 500; // Turret movement parameter private var joystickAngle : float; function Update() { joystickAngle = Vector2.Angle( Vector2(1,0), Vector2(-joystick.position.x, joystick.position.y) ); joystickAngle = joystick.position.y > 0.0 ? joystickAngle :-joystickAngle; Debug.Log(joystickAngle); turret.transform.rotation = Quaternion.Slerp(turret.transform.rotation, Quaternion.Euler(Vector3(0, joystickAngle - 90, 0)), turnSpeed * Time.deltaTime); }
Another simple way of doing this is with Mathf.Atan2(); Just takes the X and Y and calculates the angle. Returns a negative and positive number.
For some reason I got this post mixed up with another (similar) question.. Code (csharp): public float GetYRotFromVec(Vector2 v1, Vector2 v2) { float _r = Mathf.Atan2(v1.x - v2, v1.y - v2.y); float _d = (_r / Mathf.PI) * 180; return _d; } so then you can do something like: Code (csharp): float _yRot = GetYRotFromVec(transform.position, target.transform.position); Quaternion _targetRot = Quaternion.Euler(0, _yRot, 0); I guess you can then slerp between the two. Hope this helps!
Create a function to pass 2 vectors in really help, never think that before. Because the Angle *ang in the vec_to_angle like a vector to store pan and tilt. So if I want to have pan, and tilt, should I build separate function for pan and tilt?
public static float PosNegAngle(Vector3 a1, Vector3 a2, Vector3 n) { float angle = Vector3.Angle(a1, a2); float sign = Mathf.Sign(Vector3.Dot(n, Vector3.Cross(a1, a2))); return angle*sign; } This an all purpose version of the positive-negative angle dilemma. "n" is the normal of the reference plane. For rotations around the Y axis you would use Vector3.up. But there are times when you want to find the pos-neg rotation in different planes. PosNegAngle(Vector3.forward,Vector3.right, Vector3.up) =90 PosNegAngle(Vector3.right, Vector3.forward, Vector3.up)= -90 PosNegAngle(Vector3.up, Vector3.forward, Vector3.right) = 90 PosNegAngle(Vector3.forward, Vector3.up, Vector3.right) = -90
Unity also already has a property for that so you don't have to convert the rotation from radians to degrees; Code (csharp): float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
Would this solve his problem then? Code (csharp): float angle = Mathf.Atan2(joystick.position.x, joystick.position.y) * Mathf.Rad2Deg;
Yes, that is what I am using now. Thanks everyone for help. I am thinking how to remake the vec_to_angle function, which return pan and tilt at the same time.
You could have it return a vector2, x = pan, y = tilt. Or if you wanted to, you could make a struct that does essentially the same thing.