当玩家接近航路点时,他会减速然后再次加速,我怎样才能做到这一点?

How can i make that when the player is getting close to a waypoint he will slow down and then will speed up again?

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class WayPoints : MonoBehaviour {

    public GameObject[] waypoints;
    public Transform target;
    public float moveSpeed = 1f;
    public float rotationSpeed = 1f;
    private Transform myTransform;
    private int targetsIndex = 0;
    private Vector3 originalPosition;

    public float walkSpeed = 15f;

    void Awake()
    {
        myTransform = transform;
    }
    // Use this for initialization
    void Start()
    {
        waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");

        originalPosition = myTransform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if (MyCommands.walkbetweenwaypoints == true)
        {
            WayPointsAI();
        }

        DrawLinesInScene();
    }

    private void WayPointsAI()
    {
        if (targetsIndex == waypoints.Length)
            targetsIndex = 0;
        target = waypoints[targetsIndex].transform;
        float distance = Vector3.Distance(myTransform.position, target.transform.position);
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed * Time.deltaTime);

        //move towards the player
        myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
        if (distance < 2f)
            targetsIndex++;

        if (distance < 5f)
        {
            moveSpeed = 5;
        }
        else
        {

        }
    }

    void DrawLinesInScene()
    {
        // draw lines between each checkpoint //
        for (int i = 0; i < waypoints.Length - 1; i++)
        {
            Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
        }

        // draw a line between the original transform start position 
        // and the current transform position //
        Debug.DrawLine(originalPosition, transform.position, Color.red);

        // draw a line between current transform position and the next waypoint target
        // each time reached a waypoint.
        if (target != null)
            Debug.DrawLine(target.transform.position, myTransform.position, Color.green);
    }
}

我希望当 player/gameobject 接近下一个航路点时他会减速,然后当他通过航路点时然后旋转到下一个航路点速度 uo 到原来的速度在减速之前。

所以我补充说:

if (distance < 5f)
            {
                moveSpeed = 5;
            }
            else
            {

            }

但首先我不确定 < 5 是否足够远以使其变慢但让我们说一秒钟它已经足够远我如何让它在到达航路点并旋转到后加速下一个 ?我可以将原始速度存储在 Start 函数中的某个变量中,但可能会出现用户在游戏已经 运行 时更改速度的情况,因此将原始速度存储在 Start 函数中不会一直在工作。

我如何找到数组 waypoints 半径中的每个航路点? 现在我将它设置为距离 < 2

if (distance < 2f)
    targetsIndex++;

但是如果路点对象半径大于2,玩家将卡在这个路点。所以我认为而不是检查 2f 它应该是 distance < waypoints[i].radius 或如何找到半径之类的东西。逻辑是找到每个路径点的半径并检查它的半径而不是 2f。

编辑

现在这是我的 WayPoints 脚本。我正在向 waypoints 数组中的每个航路点添加一个碰撞器和 SlowDown 脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class WayPoints : MonoBehaviour {

    //setters for setting everything in Unity editor
    public float moveSpeedWalkSetter = 10f;
    public float moveSpeedSlowedWalkSetter = 3f;

    //static objects changeable via any script
    public static float moveSpeedWalk;
    public static float moveSpeedSlowedWalk;
    static ThirdPersonCharacter thirdperson;


    public GameObject[] waypoints;
    public Transform target;
    public float rotationSpeed = 1f;
    private Transform myTransform;
    private int targetsIndex = 0;
    private Vector3 originalPosition;
    private GameObject[] robots;

    public Transform reverseTarget;
    private int reverseTargetsIndex = 0;
    private Vector3 reverseOriginalPosition;

    //public float walkSpeed = 15f;

    void Awake()
    {
        myTransform = transform;
    }
    // Use this for initialization
    void Start()
    {
        thirdperson = new ThirdPersonCharacter();

        moveSpeedWalk = moveSpeedWalkSetter;
        moveSpeedSlowedWalk = moveSpeedSlowedWalkSetter;
        thirdperson.ChangeSpeed(moveSpeedWalk);

        waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");
        robots = GameObject.FindGameObjectsWithTag("Robots");

        AddColliderToWaypoints();
        AddSlowdownScriptToWaypoints();

        originalPosition = robots[0].transform.position;
        reverseOriginalPosition = robots[1].transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if (MyCommands.walkbetweenwaypoints == true)
        {
            WayPointsAI();
            ReverseWayPointsAI();
        }

        DrawLinesInScene();
    }

    public static void SetSpeed(float move)
    {
        thirdperson.ChangeSpeed(move);
    }


    private void WayPointsAI()
    {
        if (targetsIndex == waypoints.Length)
            targetsIndex = 0;
        target = waypoints[targetsIndex].transform;
        float distance = Vector3.Distance(robots[0].transform.position, target.transform.position);
        robots[0].transform.rotation = Quaternion.Slerp(robots[0].transform.rotation, Quaternion.LookRotation(target.position - robots[0].transform.position), rotationSpeed * Time.deltaTime);

        //move towards the player
        robots[0].transform.position += robots[0].transform.forward * moveSpeedWalk * Time.deltaTime;
        if (distance < 2f)
            targetsIndex++;


    }

    private void ReverseWayPointsAI()
    {
        if (reverseTargetsIndex == 0)
            reverseTargetsIndex = waypoints.Length -1;
        reverseTarget = waypoints[reverseTargetsIndex].transform;
        float distance = Vector3.Distance(robots[1].transform.position, reverseTarget.transform.position);
        robots[1].transform.rotation = Quaternion.Slerp(robots[1].transform.rotation, Quaternion.LookRotation(reverseTarget.position - robots[1].transform.position), rotationSpeed * Time.deltaTime);

        //move towards the player
        robots[1].transform.position += robots[1].transform.forward * moveSpeedWalk * Time.deltaTime;
        if (distance < 2f)
            reverseTargetsIndex--;


    }

    void RandomWayPointsAI()
    {

    }

    void DrawLinesInScene()
    {
        // draw lines between each checkpoint //
        for (int i = 0; i < waypoints.Length - 1; i++)
        {
            Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
        }

        // draw a line between the original transform start position 
        // and the current transform position //
        Debug.DrawLine(originalPosition, robots[0].transform.position, Color.red);
        Debug.DrawLine(originalPosition, robots[1].transform.position, Color.red);

        // draw a line between current transform position and the next waypoint target
        // each time reached a waypoint.
        if (target != null)
            Debug.DrawLine(target.transform.position, robots[0].transform.position, Color.green);
        if (reverseTarget != null)
            Debug.DrawLine(reverseTarget.transform.position, robots[1].transform.position, Color.green);
    }

    void AddColliderToWaypoints()
    {
        foreach (GameObject go in waypoints)
        {
            SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
            sc.isTrigger = true;
        }
    }

    void AddSlowdownScriptToWaypoints()
    {
        foreach (GameObject go in waypoints)
        {
            go.AddComponent<SlowDown>();
        }
    }
}

然后是 SlowDown 脚本

using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;

class SlowDown : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("Object " + other.name + " entered " + name);
        WayPoints.SetSpeed(WayPoints.moveSpeedSlowedWalk);
    }

    private void OnTriggerExit(Collider other)
    {
        Debug.Log("Object " + other.name + " exited " + name);
        WayPoints.SetSpeed(WayPoints.moveSpeedWalk);
    }
}

然后在 ThirdPersonController 脚本中添加这个

public void ChangeSpeed(float move)
        {
            m_MoveSpeedMultiplier = move;
        }

现在我只使用移动速度变量而不是步行速度。所以我现在只使用移动,因为它是 ThirdPersonController 而不是 FirstPersonController。

但在任意点输入 OnTriggerEnter 时它仍然没有减速。

我的想法是你可以检查 2 个检查点之间的距离,如果它是内嵌的,然后计算速度。

var distanceCheckpoint = Vector3.Distance(checpoint_1.position, checpoint_2.position);
var distance = Vector3.Distance(myTransform.position, target.transform.position);
var thresholdSpeed = distance / distanceCheckpoint * moveSpeed;

假设玩家的移动速度由浮动改变,并且您使用的是统一标准资产第 3 第一人称控制器。您可以将其调整为您的自定义播放器控制器。无论如何,此脚本需要您在编辑器中设置 moveSpeedSetter、moveSpeedSlowedSetter 和 motorSetter。你可以把这个脚本放在任何你喜欢的地方。

using UnityEngine;

public class WayPoints : MonoBehaviour
{
    //setters for setting everything in Unity editor
    public float moveSpeedSetter = 1f;
    public float moveSpeedSlowedSetter = 0.5f;
    public CharacterMotor motorSetter;

    //static objects changeable via any script
    public static float moveSpeed;
    public static float moveSpeedSlowed;
    public static CharacterMotor motor;

    public static void SetSpeed(float speed)
    {
        motor.movement.maxForwardSpeed = speed;
    }

    private void Start()
    {
        moveSpeed = moveSpeedSetter;
        moveSpeedSlowed = moveSpeedSlowedSetter;
        motor = motorSetter;
        motor.movement.maxForwardSpeed = moveSpeed;
    }
}

之后在所有 waypoints 中创建空对象并向它们添加触发器。然后将此脚本放在带有触发器的新创建的对象上。

using UnityEngine;

class SlowDown : MonoBehaviour
{ 
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("Object " +other.name+" entered "+ name);
        WayPoints.SetSpeed(WayPoints.moveSpeedSlowed);
    }

    private void OnTriggerExit(Collider other)
    {
        Debug.Log("Object " + other.name + " exited " + name);
        WayPoints.SetSpeed(WayPoints.moveSpeed);
    }
}

---编辑下面的 UNITY 5---

因此,为了从 Unity 标准资产中默认访问 gameObject FPSController 中对象 FirstPersonController 的浮动 WalkSpeed 和 RunSpeed,您必须对其进行修改或创建自己的方法来访问它们,就像这样。 (你可以把它放在 FirstPersonController 脚本中的任何地方)。

 public void ChangeSpeed(float walk,float run)
        {
            m_WalkSpeed = walk;
            m_RunSpeed = run;
        }

这里是控制移动速度的脚本

using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;

public class WayPoints : MonoBehaviour
{
    //setters for setting everything in Unity editor
    public float moveSpeedRunSetter = 10f;
    public float moveSpeedSlowedRunSetter = 6f;
    public float moveSpeedWalkSetter = 5f;
    public float moveSpeedSlowedWalkSetter = 3f;
    public FirstPersonController motorSetter;

    //static objects changeable via any script
    public static float moveSpeedRun;
    public static float moveSpeedSlowedRun;
    public static float moveSpeedWalk;
    public static float moveSpeedSlowedWalk;
    public static FirstPersonController motor;

    public static void SetSpeed(float walk, float run)
    {
        motor.ChangeSpeed(walk, run);
    }

    private void Start()
    {
        moveSpeedWalk = moveSpeedWalkSetter;
        moveSpeedSlowedWalk = moveSpeedSlowedWalkSetter;
        moveSpeedRun = moveSpeedRunSetter;
        moveSpeedSlowedRun = moveSpeedSlowedRunSetter;
        motor = motorSetter;
        motor.ChangeSpeed(moveSpeedWalk, moveSpeedRun);
    }
}

这是 waypoints

的脚本
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;

class SlowDown : MonoBehaviour
{ 
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("Object " +other.name+" entered "+ name);
        WayPoints.SetSpeed(WayPoints.moveSpeedSlowedWalk, WayPoints.moveSpeedSlowedRun);
    }

    private void OnTriggerExit(Collider other)
    {
        Debug.Log("Object " + other.name + " exited " + name);
        WayPoints.SetSpeed(WayPoints.moveSpeedWalk, WayPoints.moveSpeedRun);
    }
}