为什么在使用navmeshagent并用鼠标单击时,播放器会一直指向某个点并继续移动?

时间:2018-07-30 05:38:44

标签: c# unity3d

我附有一个FPSControllerRigidBodyAnimatorNavMeshAgent和两个脚本:PlayerControllerAgentController。 / p>

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 10.0f;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        float translatioin = Input.GetAxis("Vertical") * speed;
        float straffe = Input.GetAxis("Horizontal") * speed;
        translatioin *= Time.deltaTime;
        straffe *= Time.deltaTime;

        transform.Translate(straffe, 0, translatioin);

        if (Input.GetKeyDown("escape"))
            Cursor.lockState = CursorLockMode.None;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentController : MonoBehaviour
{
    public Camera camera;
    public NavMeshAgent agent;
    public bool agentControl = false;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update ()
    {
     if (Input.GetMouseButtonDown(0) && agentControl == true)
        {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                agent.SetDestination(hit.point);
            }
        }
    }
}

使用PlayerController,我可以使用WSAD键移动,使用AgentController,我可以单击地形上的某个点,Agent将会在那走过去。

例如,当我单击其中一个大立方体时,玩家将在其上方行走并停在其附近。但后来当我使用WSAD键从立方体的球员将继续automaticaly回移动到立方体背面移开。

就像磁铁一样,可以使玩家不断移动到我之前单击的那个点。

FPSCamera上有一个脚本:只是使用鼠标环顾四周。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class camMouseLook : MonoBehaviour
{
    Vector2 mouseLook;
    Vector2 smoothV;

    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;

    GameObject character;

    // Use this for initialization
    void Start ()
    {
        character = this.transform.parent.gameObject;
    }

    // Update is called once per frame
    void Update ()
    {
         Cursor.visible = false;
            Cursor.lockState = CursorLockMode.Locked;

            var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

            md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
            smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
            smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
            mouseLook += smoothV;

            mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);

            transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
            character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, Vector3.up);
 }
}

我发现,在游戏运行时,如果我取消选中NavMeshAgent的话,我将能够再次用键四处走动,但是当NavMeshAgent打开时,我单击某个立方体即使我将键移到其他地方,也将继续移至该立方体。

我希望能够在游戏运行时使用AgentController和/或PlayerController

NavMeshAgent

更新:

我尝试使用OnCollisionEnter和OnCollisionExit 但是一旦我将OnCollisionExit上的移动设置为false,我就会遇到同样的问题。原因是我将OnCollisionExit中的移动再次设置为true是为了能够单击鼠标并再次移动。

所以我又被困住了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentController : MonoBehaviour
{
    public Camera camera;
    public NavMeshAgent agent;
    public bool move = true;

    // Use this for initialization
    void Start ()
    {
    }

    // Update is called once per frame
    void Update ()
    {
     if (Input.GetMouseButtonDown(0) && move == true)
        {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                    agent.SetDestination(hit.point);
            }
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "HitPoint")
        {
            move = false;
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        move = true;
    }
}

1 个答案:

答案 0 :(得分:3)

这可能是由于您将目标设置为多维数据集内的位置而发生的,因此即使不可能,您的代理也会继续尝试到达它们。

首先,您可能希望告诉您的座席一旦按下任一移动键就停止操作以避免冲突。您可以使用它来停止:

agent.isStopped = true;
agent.velocity = Vector3.zero;

如果这不足以解决问题,则一种解决方法是将Nav Mesh Obstacle组件放入多维数据集中,选中Carve并重新烘烤Nav Mesh。这样,代理将停在距您设置的那个点最近的位置,即多维数据集之外。

第二种选择是检查与多维数据集的碰撞,并告诉您的代理一旦与单击的代理碰撞,就停止。

希望其中之一对您有用!