沿对角线旋转物体并防止其返回90,180,0,360度

时间:2016-11-01 06:45:05

标签: c# unity3d

按住AS,SD,DW或WA的组合键移动我的物体后,它会成功对角移动并旋转到正确位置,但释放按键后,它会旋转回0,90,180或者360取决于释放我的键后最近的旋转,我想这是因为我离开了键的那一帧,所以它运行该代码并将其移动到0,90,180,360。但我不知道如何解决它。

我希望我提供了足够的信息,并感谢您的帮助。 enter image description here

我一起按下AW键 enter image description here

释放按键后,它不会保持这种状态,而是向左或向上移动

PlayerMovement.cs

 using UnityEngine;
 using System.Collections;

 public class playerMovement : MonoBehaviour {

     private float speedWalk = 7.5f;
     private float speedRotate = 7.5f;
     private GameObject raycastObject;

     // Update is called once per frame
     void FixedUpdate ()
     {
         //Non-Diagonal Movements
         if (Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) //player movement up
         {
             transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.D)) //player movement down
         {
             transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement right
         {
             transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
         }
         if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement left
         {
             transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
         }

         //Diagonal Movements **@@@@@@@@** I think this is the problem.
         if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.W)) //player movement Top Left
         {
             transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
             transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D)) //player movement Top Right
         {
             transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
             transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
         }
         if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.S)) //player movement Bottom Right
         {
             transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
             transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A)) //player movement Bottom Left
         {
             transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
             transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
         }
     }
 }

playerRotateMouse.cs

using UnityEngine;
 using System.Collections;

 public class playerRotateMouse : MonoBehaviour
 {
     public Transform Player;
     private float speed = 7.5f;
     Quaternion targetRotation;

     void FixedUpdate()
     {
         Plane playerPlane = new Plane(Vector3.up, transform.position);

         // Generates a ray from cursor
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

         float hitdist = 0.0f;

         if (Input.GetButtonDown("Fire1") || Input.GetButtonDown("Fire2"))
         {
             if (playerPlane.Raycast(ray, out hitdist))
             {
                 Vector3 targetPoint = ray.GetPoint(hitdist);
                 Debug.DrawRay(transform.position, targetPoint, Color.green);
                 targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
             }
         }
         // Smooth rotation towards point.
         transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);

         //Rotate base on key pressed
         if (Input.GetKey(KeyCode.W) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate up
         {
             targetRotation = Quaternion.LookRotation(Vector3.forward);
             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.S) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate down
         {
             targetRotation = Quaternion.LookRotation(Vector3.forward * -1);
             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.D) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate right
         {
             targetRotation = Quaternion.LookRotation(Vector3.right);
             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
         }
         if (Input.GetKey(KeyCode.A) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate left
         {
             targetRotation = Quaternion.LookRotation(Vector3.left);
             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
         }
     }
 }

1 个答案:

答案 0 :(得分:0)

我会保存最后一个时间戳,并检查第二个密钥释放是否在特定时间范围内。如果它在(例如)20ms内释放,请不要重置它。

例如:(伪)

private bool[] _directionKeysPressed = new bool[4];
private DateTime _previousKeyRelease;

private void KeyDown(object sender, EventArgs e)
{
    _keyPressedCount++;

    switch(keys)
    {
       case(W): _directionKeysPressed[0] = true;
       case(D): _directionKeysPressed[1] = true;
       // .................
    }
}

private void KeyUp(object sender, EventArgs e)
{
    _keyPressedCount--;

    if(_keyPressedCount == 0)
    {
        // all keys released
        _directionKeysPressed[] <--- last direction...

        // reset all bools
        return;
    }

    // ONLY if the key is released outside the 20 ms, reset the key.
    if(_previousKeyRelease.AddMilliseconds(20) < DateTime.UTCNow)
    {  // RESET KEY
        switch(keys)
        {
            case(W): _directionKeysPressed[0] = false;
            case(D): _directionKeysPressed[1] = false;
            // .................
        }
    }

    _previousKeyRelease = DateTime.UTCNow;
}

我个人会用Int32中的一个位域来做这个,但是对于一个bool数组来说更清楚。