如果在中间有一个非常大的航路点,我如何让敌人移动到下一个航点?

时间:2017-03-02 08:32:39

标签: c# unity3d unity5

如果航路点尺寸较小,例如尺寸为0.1或1的立方体,则可以。 当我将立方体尺寸改为20-30时,如果有一种情况是在途中有两个航路点但是敌人应该到达第二个航路点,他将卡在第一个航路点的墙上将摇晃/断断续续并将尝试去其中一方然后最后他将通过这个航点,并继续前往他应该得到目标的航点。

只有当航点(立方体)非常大并且航点阻挡了敌人应该获得的航点时才会发生。

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 = 10f;
    public float moveSpeed1 = 10f;
    public float slowDownSpeed = 3f;
    public float reverseSlowDownSpeed = 3f;
    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 bool random = false;

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

        AddColliderToWaypoints();
        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();
    }

    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
        if (distance < 30)
        {
            robots[0].transform.position += robots[0].transform.forward * slowDownSpeed * Time.deltaTime;
        }
        else
        {
            robots[0].transform.position += robots[0].transform.forward * moveSpeed * Time.deltaTime;
        }
        if (distance < target.transform.localScale.magnitude)
        {
            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
        if (distance < 30)
        {
            robots[1].transform.position += robots[1].transform.forward * reverseSlowDownSpeed * Time.deltaTime;
        }
        else
        {
            robots[1].transform.position += robots[1].transform.forward * moveSpeed1 * Time.deltaTime;
        }
        if (distance < reverseTarget.transform.localScale.magnitude)
        {
            reverseTargetsIndex--;
        }
    }

    void RandomWayPointsAI()
    {
        if (random == true)
        {
            int index = Random.Range(0, waypoints.Length);
            target = waypoints[index].transform;
        }
    }

    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(reverseOriginalPosition, 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;
        }
    }
}

我试图制作

if (distance < reverseTarget.transform.localScale.magnitude)

我在它之前尝试过制作

if (distance < reverseTarget.tranform.localscale.x)

或者

if (distance < reverseTarget.tranform.localscale.x / 2)

与目标和第一个AI功能相同。 但没有任何工作。也许我应该找到航点半径? 不知道如何解决它。

1 个答案:

答案 0 :(得分:0)

OP似乎想要的是一种给出AI寻路的方法,这样当AI想要从(动态/代码生成的)A点到B点出现并且存在障碍时,AI就不会这样做了。卡在障碍物中。

Unity提供NavMeshNavMesh Obstacle,这是一个简单的寻路工具,Unity让我们可以轻松实现智能AI。