2016-07-05 101 views
0

我一直在尝试一段时间,并找不出为什么它不工作。 我有一个PathHolder父项中的空对象的简单路径,它跟随该路径并顺利旋转以面对它将要前进的点。我的问题是,有一半的时间,角色对象并没有一直旋转,而是仍然朝着应有的方向前进。 另一个奇怪的是,将点移近会减少物体的旋转量,并且进一步移动它会使角色面对点。但是,在任何情况下工作路径都需要灵活,所以我不能让距离影响旋转。Quaternion.LookRotation角度不能正常工作

理想情况下,我希望角色可以完全顺畅地朝向箭头键按下的位置旋转,以便角色在玩家释放按键时不会卡在游戏中途。这里是我的代码至今:

using UnityEngine; 
using System.Collections; 

public class CharacterControllerPath : MonoBehaviour 
{ 
    enum Direction {Forward, Backward}; 
    Direction charDirection; 

    public PathEditor pathToFollow; 

    private Vector3 targetPosition; 

    public string pathName; 
    public int wayPointID = 0; 
    public float speed; 
    public float rotationSpeed = 7.0f; 

    private float reachDistance = 1.0f; 
    private float distanceX; 
    private float distanceY; 

    void Start() 
    { 
     transform.position = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID].transform.position.z); 
     charDirection = Direction.Forward; 
     Vector3 targetPosition = new Vector3(pathToFollow.pathObj[wayPointID + 1].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID + 1].transform.position.z); 
     transform.LookAt(targetPosition); 
    } 

    void FixedUpdate() 
    { 
     Movement(); 
    } 

    void Movement() 
    { 
     if(Input.GetKey(KeyCode.RightArrow)) 
     { 
      charDirection = Direction.Forward; 

      //Move 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID].transform.position.z); 
      transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime); 

      //Rotate 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, 0, pathToFollow.pathObj[wayPointID].transform.position.z); 
      var rotation = Quaternion.LookRotation(targetPosition); 
      transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime); 

      if(transform.position.x == targetPosition.x && transform.position.z == targetPosition.z) 
       wayPointID++; 
     } 
     else if(Input.GetKey(KeyCode.LeftArrow)) 
     { 
      charDirection = Direction.Backward; 

      //Move 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID - 1].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID - 1].transform.position.z); 
      transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime); 

      //Rotate 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID - 1].transform.position.x, 0, pathToFollow.pathObj[wayPointID - 1].transform.position.z); 
      var rotation = Quaternion.LookRotation(targetPosition); 
      transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime); 

      if(transform.position.x == targetPosition.x && transform.position.z == targetPosition.z) 
       wayPointID--; 
     } 

     if(wayPointID >= pathToFollow.pathObj.Count) 
     { 
      //Put code to finish the level 
      wayPointID = (pathToFollow.pathObj.Count - 1); 
     } 
     else if(wayPointID <= 0) 
      wayPointID = 0; 
    } 
} 
+0

我假设'pathToFollow'中的点与世界相对?如果你想让角色朝这个方向看,你需要确保你给出了一个与该角色相关的向量。 – rutter

+0

感谢您的快速回答!但是,我不确定自己完全明白你在说什么,你有没有想过的例子? – Septos

+0

因Unity在任何情况下都不会使用四元数。只需使用“LookAt”https://docs.unity3d.com/ScriptReference/Transform.LookAt.html – Fattie

回答

0

如果你想两个向量之间平滑移动载体,应用

Vector3.Lerp(firstPosOrRotation, secondPosOrRotation, Time.deltaTime*Input.GetInputRaw("Horizontal")*speed); 

Input.GetInputRaw(“水平”)只是之间的值 - 1和1取决于正在按下的方向键。 现在只需获取路径中的每个点和下一个点以及它们之间的Lerp。

  • 编辑 对于旋转,代替Time.deltaTime和所有,为此

    旋转= Vector3.Lerp(rotationA,rotationB,Mathf.Clamp(DIST(POS, finalPos), 0,1);

    DIST(POS, finalPos)=量在点A和B之间行进

我希望这是清楚的烯ough, 我不确定你的意思,或者你希望对象在路径上向前。

+0

谢谢你的回答,但正如所提到的,移动工作得很好,我可以从一个点移动到另一个点,问题在于,即使使用我的quaternion.LookRotation(),该角色有时也不会面对正确的方式。我有一条直线,然后是右,然后离开的路径,然后只需按下右箭头就可以跟随它,但是当朝第一个点移动时,角色不会一直旋转,并且角度为232.52度角度,然后越过那个点,当它转向下一个点时,它完全面对它。 – Septos

+0

好的,对于位置做我说的,但对于旋转做Vector3.Lerp,但替换Time.deltaTime和所有其他东西与对象已在两个路径点之间移动多远,并将其夹在0和1之间 –