private float rotSpeed = 1000; //旋转速度
private float rotState = -1; //旋转状态 -1 停止 0 开始 1 结束
private float endAngle = 0; //结束角度
private readonly float AcceleateTime = 1f; //加速度持续时间
private float rotTime = 0f; //旋转持续时间
private float rotFactor = 0f; //旋转速度变化因子
private float minTime = 3f; //旋转最小持续时间
private float _tmpAngle = 0f; //开始减速物体的角度
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
RotMath();
}
/// <summary>
/// 旋转方法 再update里面更新
/// </summary>
public void RotMath()
{
if(rotState == -1)
{
return;
}
rotTime += Time.deltaTime; //记录时间
if (rotState == 0)
{
//开始旋转 先加速计算速度
rotFactor = rotTime / AcceleateTime;
rotFactor = rotFactor > 1 ? 1 : rotFactor;
transform.Rotate(Vector3.back, -rotFactor * rotSpeed * Time.deltaTime, Space.Self);
}
else
{
//减速旋转一段时间再慢慢变停止
//通过差值运算实现精准地旋转到指定角度(球型插值无法实现大于360°的计算)
float k = 1f; //如果嫌减速太慢,可以加个系数修正一下
_tmpAngle = Mathf.Lerp(_tmpAngle, endAngle, Time.deltaTime * k);
//这里只存在一个方向的旋转,所以不存在欧拉角万向节的问题,所以使用欧拉角和四元数直接赋值都是可以的
transform.rotation = Quaternion.Euler(0, 0, -_tmpAngle);
//node.eulerAngles = new Vector3(0, 0, _tmpAngle);
if (1 >= Mathf.Abs(_tmpAngle - endAngle))
{
//重新设置状态 数据 显示奖励等
rotState = -1;
endAngle = 0;
rotTime = 0;
}
}
//修改旋转状态
if(rotState == 0 && rotTime > minTime && endAngle !=0 )
{
rotState = 1;
// 将当前指针的欧拉角转换成顺时针统计角度
//由于读取到的值是[0, 180] U [-180, 0],左边由0至180递增,右边由180转变成-180,然后递增至0,所以需要转相应的转换
_tmpAngle = (1) * (360 - transform.eulerAngles.z) % 360;
}
}
public void OnStartRot()
{
rotState = 0;
rotTime = 0;
endAngle = UnityEngine.Random.Range(0f, 360f);
endAngle = Mathf.Abs(endAngle);
print("End Angle: " + endAngle);
endAngle = endAngle % 360; //将角度限定在[0, 360]这个区间
endAngle = -endAngle - 360 * 4; //多N圈并取反,圈数能使减速阶段变得更长,显示更自然,逼真
}