Unity中的旋转分为四元数(x,y,z,w)和欧拉角。
使用transform.rotation.z获取到的是一个Cos,Sin的值,而不是面板中的值。
而使用transform.localEulerAngles.z是一个0-360的值,当正向旋转时可以获取到面板上对应的数值,但反向旋转时数值就会从360一直往下减少。
这部分涉及到数学知识,我也不是太懂。以后再进行补充!
利用Unity的反射可以获取到unity面板中对应的Rotation数值:
//获取到旋转的正确数值
public Vector3 GetInspectorRotationValueMethod(Transform transform)
{
// 获取原生值
System.Type transformType = transform.GetType();
PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
string temp = value.ToString();
//将字符串第一个和最后一个去掉
temp = temp.Remove(0, 1);
temp = temp.Remove(temp.Length - 1, 1);
//用‘,’号分割
string[] tempVector3;
tempVector3 = temp.Split(',');
//将分割好的数据传给Vector3
Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));
return vector3;
}
——————————小案例:让一个钩子左右来回摇摆
一:方法1
利用反射得到面板中的Rotation值,直接判断Rotation值的范围就可以
using System.Reflection;
using UnityEngine;
//摇摆方向
public enum SwingDir
{
RIGHT,
LEFT,
}
public class Hook : MonoBehaviour
{
public float swingSpeed;//摇摆的速度
private SwingDir swingDir;//摇摆方向
private void Update()
{
//判断旋转方向
switch (swingDir)
{
case SwingDir.RIGHT:
transform.Rotate(Vector3.forward * Time.deltaTime * swingSpeed);
if (GetInspectorRotationValueMethod(transform) > 90)
{
swingDir = SwingDir.LEFT;
}
break;
case SwingDir.LEFT:
transform.Rotate(Vector3.forward * Time.deltaTime * -swingSpeed);
if (GetInspectorRotationValueMethod(transform) < -90)
{
swingDir = SwingDir.RIGHT;
}
break;
}
}
//获取到面板上对应的Rotation数值
public float GetInspectorRotationValueMethod(Transform transform)
{
// 获取原生值
System.Type transformType = transform.GetType();
PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
string temp = value.ToString();
//将字符串第一个和最后一个去掉
temp = temp.Remove(0, 1);
temp = temp.Remove(temp.Length - 1, 1);
//用‘,’号分割
string[] tempVector3;
tempVector3 = temp.Split(',');
//将分割好的数据传给Vector3
Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));
return vector3.z;
}
}
二:方法2
声明一个float类型的变量(充当累加器的功能),将这个值一直赋给旋转的角度
using UnityEngine;
//摇摆方向
public enum SwingDir
{
RIGHT,
LEFT,
}
public class Hook : MonoBehaviour
{
private float currentAngle;//角度
public float swingSpeed;//摇摆的速度
private SwingDir swingDir;//摇摆方向
private void Update()
{
//判断旋转方向
switch (swingDir)
{
case SwingDir.RIGHT:
currentAngle += Time.deltaTime * swingSpeed;
transform.rotation = Quaternion.Euler(0, 0, currentAngle);
if (currentAngle > 90)
{
swingDir = SwingDir.LEFT;
}
break;
case SwingDir.LEFT:
currentAngle -= Time.deltaTime * swingSpeed;
transform.rotation = Quaternion.Euler(0, 0, currentAngle);
if (currentAngle < -90)
{
swingDir = SwingDir.RIGHT;
}
break;
}
}
}
三:方法3
利用向量的点乘获取到夹角,用夹角判断是否到达边界
public class Hook: MonoBehaviour
{
int unit = 1;//判断正负的一个数值
void Update()
{
float dot = Vector3.Dot(-transform.up, Vector3.down);
if (dot < 0.707f)
{
unit = -unit;
}
transform.Rotate(Vector3.forward, dot * unit);
}
}