Lee*_*son 6 c# unity-game-engine
我试图绕X,Y和Z轴旋转播放器。Y轴不应从最后一个角度移动。例如,如果我向左旋转45度,则播放器不应旋转回0。播放器的X和Z轴最多旋转30度,然后在不再使用Input时,将其稳定为0。
经过反复试验,我终于使我的Y角不再Slerp回到0。但是,X和Z仍然认为Y是0度。播放器旋转(假定向左旋转45度),但沿X和Z的移动就好像Y为0度。
我一直在阅读文章和主题,并观看多个领域的视频,包括但不限于StackOverflow,Unity论坛,Unity API和YouTube视频。
当前游戏的视频 -注意引擎排气-X和Z永远不会更改为“相机”视图/“播放器” Y方向的新法线。
void Update()
{
if(!controller.isGrounded)
{
//Three degree's
moveDirection = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Thrust"), Input.GetAxis("Vertical"));
moveDirection *= speed;
//rotate around Y-Axis
transform.Rotate(0, Input.GetAxis("Yaw") * rotationSpeed, 0);
float currentY = transform.eulerAngles.y; //save Y for later
//rotation around X and Z
float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
float tiltAroundZ = -1 * (Input.GetAxis("Horizontal") * tiltAngle);
Quaternion targetRotation = Quaternion.Euler(tiltAroundX, currentY, tiltAroundZ);
Vector3 finalRotation = Quaternion.Slerp(transform.rotation, targetRotation, smooth).eulerAngles;
finalRotation.y = currentY; //reintroduce Y
transform.rotation = Quaternion.Euler(finalRotation);
controller.Move(moveDirection * Time.deltaTime);
}
Run Code Online (Sandbox Code Playgroud)
经过进一步的研究,我走上了不同的道路,我发现存在两个问题。这两个问题都围绕着这样一个事实:旋转后 Z 轴从未标准化为新的 Y 轴度数。@Ruzihm,解决了旋转问题。我解决了当时可见的运动问题。一旦旋转正常工作,这一点就变得显而易见。
transform.forward本质上,在 Y 轴旋转 ( ) 发生任何变化后,必须重新计算Z 轴( Vector3.up)。一旦有了新的法线 ( transform.forward),运动矢量就需要展平到平面,以防止玩家潜入世界表面。感谢@Ruzihm 的所有帮助。
这是新代码:
//Three degree's
moveDirection = new Vector3(Input.GetAxis("Horizontal"),
Input.GetAxis("Thrust"),
Input.GetAxis("Vertical"));
//Normalize the movement direction and flatten the Plane
moveDirection = transform.TransformDirection(moveDirection);
moveDirection = Vector3.ProjectOnPlane(moveDirection, Vector3.up);
moveDirection *= speed;
// collect inputs
float yaw = Input.GetAxis("Yaw") * rotationSpeed;
float pitch = Input.GetAxis("Vertical") * tiltAngle;
float roll = -1 * (Input.GetAxis("Horizontal") * tiltAngle);
// Get current forward direction projected to plane normal to up (horizontal plane)
Vector3 forwardCurrent = transform.forward
- Vector3.Dot(transform.forward, Vector3.up) * Vector3.up;
// Debug to view forwardCurrent
Debug.DrawRay(transform.position, forwardCurrent * 2, Color.white);
// create rotation based on forward
Quaternion targetRotation = Quaternion.LookRotation(forwardCurrent);
// rotate based on yaw, then pitch, then roll.
// This order prevents changes to the projected forward direction
targetRotation = targetRotation * Quaternion.AngleAxis(yaw, Vector3.up);
// Debug to see forward after applying yaw
Debug.DrawRay(transform.position, targetRotation * Vector3.forward, Color.red);
targetRotation = targetRotation * Quaternion.AngleAxis(pitch, Vector3.right);
targetRotation = targetRotation * Quaternion.AngleAxis(roll, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, smooth);
controller.Move(moveDirection * Time.deltaTime);
Run Code Online (Sandbox Code Playgroud)