想实现的效果:
刀尖朝向Z轴正方向,刀刃朝向X轴正方向,使得刀刃的方向随鼠标移动而改变,鼠标向左移动刀刃向左,鼠标向上移动刀刃向上,鼠标向右上移动刀刃向右上,其他任何方向也一样
思路:
1.根据鼠标上一帧和当前帧的点得出鼠标的移动方向向量P
2.获取刀刃方向
3.两向量点乘得出旋转角度
4.两向量叉乘得出旋转方向
5.由当前Rotation 围绕旋转轴的指定方向旋转指定角度 得到新的Rotation,也就是,使刀从刀刃方向旋转到P方向
6.记得使用插值,这样会旋转得比较平滑
ps:附加刀绕着某个点移动的效果(通过控制父节点的旋转达到围绕某个点移动的效果)
实例代码
if (Input.GetMouseButton(0))
{
var newMousePos = Input.mousePosition;
if (m_oldMousePos == Vector3.zero)
{
m_oldMousePos = newMousePos;
return;
}
//鼠标移动方向
var targetDir = newMousePos - m_oldMousePos;
//刀刃方向 默认刀刃向右
var fromDir = trans_Sword.localRotation * Vector3.right;
if (targetDir != Vector3.zero)
{
//两个向量叉乘 得出旋转方向
var axis = Vector3.Cross(fromDir, targetDir).normalized;
var angle = Vector3.Angle(fromDir, targetDir);
//根据旋转方向决定旋转角的正负
if (axis.z > 0)
{
//逆时针
//用插值来做 不然会鬼畜
trans_Sword.localRotation = Quaternion.Lerp(trans_Sword.localRotation, Quaternion.AngleAxis(angle, Vector3.forward) * trans_Sword.localRotation, m_DeltaTime * gameData.m_SwordTurnSpeed);
}
else if (axis.z < 0)
{
//顺时针
trans_Sword.localRotation = Quaternion.Lerp(trans_Sword.localRotation, Quaternion.AngleAxis(-angle, Vector3.forward) * trans_Sword.localRotation, m_DeltaTime * gameData.m_SwordTurnSpeed);
}
}
//下面代码为通过控制父节点的X和Y轴的旋转来达到绕着某个点移动的效果
var dis = Vector3.Distance(newMousePos, m_oldMousePos);
if (dis > 2)
{
var turnInX = Input.GetAxis("Mouse Y") * -gameData.m_SwordTurnFactor;
var turnInY = Input.GetAxis("Mouse X") * gameData.m_SwordTurnFactor;
var eulerAngles = trans_Pivot.localEulerAngles;
var _x = CheckAngle(eulerAngles.x);
var _y = CheckAngle(eulerAngles.y);
var _z = CheckAngle(eulerAngles.z);
if (_x > 60 && turnInX > 0)
turnInX = 0;
if (_x < -60 && turnInX < 0)
turnInX = 0;
if (_y > 60 && turnInY > 0)
turnInY = 0;
if (_y < -60 && turnInY < 0)
turnInY = 0;
Vector3 temp = new Vector3(turnInX, turnInY, 0);
var targetEuler = new Vector3(_x, _y, _z) + temp;
targetEuler.x = Mathf.Clamp(targetEuler.x, -60, 60);
targetEuler.y = Mathf.Clamp(targetEuler.y, -60, 60);
trans_Pivot.localEulerAngles = targetEuler;
//trans_Pivot.Rotate(temp, Space.World);
}
m_oldMousePos = newMousePos;
}
if (Input.GetMouseButtonUp(0))
{
m_oldMousePos = Vector3.zero;
}