【问题标题】:Player traces waypoints differently depending on speed玩家根据速度不同地追踪航路点
【发布时间】:2016-07-27 18:01:12
【问题描述】:

我猜问题出在某处的航点脚本中。

如果我让玩家走慢,比如说速度 1 或 2,他会走到第一个航路点,然后当他到达第二个航路点时转向下一个航路点,而不是回到原来的位置,他会绕圈走,然后走回第一个航路点。我想要它做的不是走到第一个航路点,而是走到它原来的起始位置。

另一件事,如果我将玩家速度更改为 7,当他到达第二个航路点时,我看到它走得很快,他左转并不停地向左走。就像根据玩家的速度他的表现不同。

这是一个视频剪辑,展示了速度为 2 的播放器: 第二个走得更快的玩家在速度 2 上,看看当他到达第二个路点时会发生什么:

video clip speed 2

这是速度 7 的第二个玩家

video clip speed 7

这是 c# 中的航点脚本

using UnityEngine;
using System.Collections;

public class Waypoints : MonoBehaviour {

    public Transform[] waypoint;
    public float patrolSpeed;
    public bool loop = true;
    public int dampingLook = 4;
    public float pauseDuration;
    private float curTime;
    private int currentWaypoint = 0;
    public CharacterController character;

    // Use this for initialization
    void Start () {


    }

    void LateUpdate(){

        if(currentWaypoint < waypoint.Length){
            patrol();
        }else{    
            if(loop){
                currentWaypoint=0;
            } 
        }
    }

    void patrol(){

        Vector3 nextWayPoint = waypoint[currentWaypoint].position;

        // Keep waypoint at character's height
        nextWayPoint.y = transform.position.y; 

        // Get the direction we need to move to
        // reach the next waypoint
        Vector3 moveDirection = nextWayPoint - transform.position;


        if(moveDirection.magnitude < 1.5){
            Debug.Log("enemy is close to nextwaypoint");


            // This section of code is called only whenever the enemy
            // is very close to the new waypoint 
            // so it is called once after 4-5 seconds.

            if (curTime == 0)
                // Pause over the Waypoint 
                curTime = Time.time; 

            if ((Time.time - curTime) >= pauseDuration){
                Debug.Log("increasing waypoint");

                currentWaypoint++;
                curTime = 0;
            }
        }
        else
        {     
            Debug.Log("reaching in rotation " + moveDirection.magnitude);
            // This code gets called every time update is called
            // while the enemy if moving from point 1 to point 2.
            // so it gets called 100's of times in a few seconds  

            // Now we need to do two things
            // 1) Start rotating in the desired direction
            // 2) Start moving in the desired direction 

            // 1) Let' calculate rotation need to look at waypoint
            // by simply comparing the desired waypoint & current transform
            var rotation = Quaternion.LookRotation(nextWayPoint - transform.position);

            // A slerp function allow us to slowly start rotating 
            // towards our next waypoint 
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, 
                Time.deltaTime * dampingLook);

            // 2) Now also let's start moving towards our waypoint
            character.Move(moveDirection.normalized * patrolSpeed * Time.deltaTime);
        }  
    }
}

也许玩家的这种奇怪行为在物理上是可以的?那么如果它太快了,它会产生这种行为吗?但这很奇怪。我认为无论在航路点之间行走的速度如何,都不是?

【问题讨论】:

    标签: c# unity3d unityscript unity5


    【解决方案1】:

    如果我让玩家走慢,比如说速度 1 或 2,他会走到第一个航路点,然后当他到达第二个航路点时转向下一个航路点,而不是回到原来的位置,他会绕圈走,然后走回第一个航路点。我想要它做的不是走到第一个航路点,而是走到它原来的起始位置。

    这是因为当敌人到达你的最后一个检查点时,你将currentWaypoint 设置为 0。所以下一帧敌人将寻找那个路点。而且由于您的起始位置不是航路点,因此他将永远不会再走到那个位置。您可以做的是在与敌人起始位置相同的位置创建另一个航路点。这样它就会回到原来的位置。

    另一件事,如果我将玩家速度更改为 7,当他到达第二个航路点时,我看到它走得很快,他左转并不停地向左走。就像根据玩家的速度他的表现不同。

    这是因为移动(位置)和旋转与您的巡逻速度不同步。你只是增加步行速度而不是旋转速度。所以每次你的敌人走了一段距离,它就需要重新开始旋转。尝试旋转你的敌人:

    transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * patrolSpeed);
    

    如果还是很慢,请尝试增加旋转的速度调节器。

    【讨论】:

    • 如何设置角色起始位置的航点?我将脚本添加到每个第三人称控制器中,因此我将向层次结构的另外两个航点添加每个玩家起始位置的航点。但是在我使用球体的前两个航点中,有没有办法在不添加游戏对象的情况下将航点设置为位置?例如告诉玩家作为路点去 0,0,0
    • 并且在行 currentWaypoint= 0;我应该删除这条线还是保持这种方式?
    • 好的,我添加了两个新的空对象并设置了每个字符的起始位置。问题在于我更改了 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * orbitSpeed);这使角色直接移动而不是任何航路点。旧线路使他们以奇怪的方式前往航路点,就像我问题中的视频剪辑一样。
    【解决方案2】:

    至于第一个问题,你永远不会存储“原始”位置——你只有航路点。因此,当实体到达最后一个航路点时,它会为第一个航路点 waypoint[0] 设置航向,因为这就是 LateUpdate() 设置 currentWaypoint 的原因。

    至于基于速度的实体改变行为,需要检查两件事——它是否真的到达了if(moveDirection.magnitude &lt; 1.5) 块内?如果不是,它在一帧中移动得太快而无法检测到。但看起来你总是在moveDirection 中移动,这实际上不受你计算的旋转的影响,除非你的Move() 函数的工作方式与我预期的不同,因此实体很可能会因为以下原因一直朝一个方向前进那个。

    【讨论】:

    • 我如何存储角色的原始位置我有两个角色并且在两个角色中我都添加了脚本每个角色的起始位置有点不同第一个玩家在 x = -0.066 ,y = 0 ,z = 0 第二个 x = -1.53​​9 ,y = 0 ,z = 0 那么我如何在脚本中存储位置并将两个新检查点设置为起点?
    • 啊,好的,我将在层次结构中创建两个新的航点,然后我将每个航点拖到检查器中的特定字符作为脚本中的起始位置,我将更改行 currentWaypoint= 0;到 currentWaypoint=2;那正确吗 ?我如何在层次结构中的航点中设置起始位置?
    • 如果实体总是需要回到那个(特定的)位置,那么一定要把它添加到变换数组中。但是你肯定仍然希望这条线将 currentWaypoint 重置为 0(否则它会在它为 3 时继续重置为 2)。所以,只需让实体转换数组的第一个成员而不是最后一个。
    • 好的,我添加了两个新的空对象并设置了每个字符的起始位置。问题在于我在 WHQ 答案中更改的行: transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * policeSpeed);这使角色直接移动而不是任何航路点。旧线路使他们以奇怪的方式前往航路点,就像我问题中的视频剪辑一样。
    • 我认为那条线看起来不对,但我没有时间考虑四元数(我对它们仍然很慢)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2019-10-23
    • 1970-01-01
    相关资源
    最近更新 更多