navmeshagent角色移动对象

时间:2018-08-01 08:51:31

标签: c# navmesh

我试图控制游戏中的对象(例如立方体),并使用由导航网格物体代理控制的第三人称角色与它们一起移动。主要目的是能够在某种程度上抓住立方体(或使立方体与玩家互动时紧贴玩家)并随其移动,最后将立方体放置在卡车后面。当玩家在放置积木时与立方体互动(在卡车后面)时,应出于优化目的而破坏或隐藏该立方体。就像我之前说过的,我的播放器由导航网格物体控制,并具有胶囊和刚性容器,并且我现在有一个交互脚本附加到其他对象上,玩家可以在其中拾取/收集物品,这些物品在我的库存中隐藏并显示插槽。但是与我要实现的目标不同,这些目标是不可动摇的。在此先感谢我希望我能理解(我正在使用Unity 2018.2)。以下是相关代码:

[Code = CSharp]

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

[RequireComponent(typeof(NavMeshAgent))]
public class PlayerMotor : MonoBehaviour
{

    Transform target;           //Target to follow
    NavMeshAgent agent;         //Referance to agent
    // Use this for initialization
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        if(target != null)
        {
            agent.SetDestination(target.position);
            FaceTarget();
        }
    }

    public void MoveToPoint(Vector3 point)
    {
        agent.SetDestination(point);
    }

    public void FollowTarget(Interactable newTarget)
    {
        agent.stoppingDistance = newTarget.radius * .8f;
        agent.updateRotation = false;

        target = newTarget.interactionTransform;
    }

    public void StopFollowingTarget()
    {
        agent.stoppingDistance = 0f;
        agent.updateRotation = true;

        target = null;
    }

    void FaceTarget()
    {
        Vector3 direction = (target.position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0f, direction.z));

        if(direction != Vector3.zero)
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f);
        }

    }

} [/代码]

[Code = CSharp]

using UnityEngine.EventSystems;
using UnityEngine;

[RequireComponent(typeof(PlayerMotor))]
public class PlayerController : MonoBehaviour
{
    Camera cam;
    PlayerMotor motor;

    public Interactable focus;

    public LayerMask movementMask;     //Filter out everything not walkable

    // Use this for initialization
    void Start()
    {
        cam = Camera.main;                   //Referance to camera
        motor = GetComponent<PlayerMotor>(); //Referance to motor
    }

    // Update is called once per frame
    void Update()
    {
        if (EventSystem.current.IsPointerOverGameObject())
            return;


        //If we left click on mouse
        if (Input.GetMouseButtonDown(0))
        {
            //We create a ray
            Ray ray = cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            //If the ray hits
            if (Physics.Raycast(ray, out hit, 100, movementMask))
            {

                motor.MoveToPoint(hit.point);   // Move to where we hit
                RemoveFocus();

            }
        }

        //If we right click on mouse
        if (Input.GetMouseButtonDown(1))
        {
            //We create a ray
            Ray ray = cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            //If the ray hits
            if (Physics.Raycast(ray, out hit, 100))
            {
                Interactable interactable = hit.collider.GetComponent<Interactable>();
                if (interactable != null)
                {
                    SetFocus(interactable);
                }

            }

        }

    }

    void SetFocus(Interactable newFocus)
    {
        if(newFocus != focus)
        {
            if(focus != null)
             focus.OnDefocused();

            focus = newFocus;
            motor.FollowTarget(newFocus);

        }

        newFocus.OnFocused(transform);
        }

    void RemoveFocus()
    {
        if(focus != null)
         focus.OnDefocused();

        focus = null;
        motor.StopFollowingTarget();
    }
}

[/代码]

[Code = CSharp]

using UnityEngine;

public class Interactable : MonoBehaviour
{
    public float radius = 2f;
    public Transform interactionTransform;

    bool isFocus = false;

    Transform player;

    bool hasInteracted = false;

    public virtual void Interact()
    {
        //This method is meant to be overwritten
        Debug.Log("Interacting with" + transform.name);
    } 

    void Update()
    {
        if (isFocus && !hasInteracted)
        {
            float distance = Vector3.Distance(player.position, interactionTransform.position);
            if(distance <= radius)
            {
                Interact();
                hasInteracted = true;
            }
        }
    }

    public void OnFocused(Transform playerTransform)
    {
        isFocus = true;
        player = playerTransform;
        hasInteracted = false;
    }

    public void OnDefocused()
    {
        isFocus = false;
        player = null;
        hasInteracted = false;
    }

    private void OnDrawGizmosSelected()
    {
        if (interactionTransform == null)
            interactionTransform = transform;
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(interactionTransform.position, radius);
    }
}

[/代码]

0 个答案:

没有答案