Microgame代码解析——自动寻路

1. NavMesh Surface

  • 得先添加Navmesh的组件,应该是在包管理器导入。
  • 创建一个空物体,添加脚本Nav Mesh Surface。
  • Bake即可获得区域。
  • 设置如下图:
    在这里插入图片描述

2. 在目标上挂上NavMeshAgent

在这里插入图片描述

3. 设置路径

  • 设置了三个点当做范围,目标会依次到达这三个点。
  • 都是空物体。
    在这里插入图片描述

4. PatrolPath.cs

  • 可以把enemy的List改成gameObject。
    在这里插入图片描述
using System.Collections.Generic;
using UnityEngine;

namespace Unity.FPS.AI
{
   
    public class PatrolPath : MonoBehaviour
    {
   
        [Tooltip("Enemies that will be assigned to this path on Start")]
        public List<EnemyController> EnemiesToAssign = new List<EnemyController>();

        [Tooltip("The Nodes making up the path")]
        public List<Transform> PathNodes = new List<Transform>();

        void Start()
        {
   
            foreach (var enemy in EnemiesToAssign)
            {
   
                enemy.PatrolPath = this;
            }
        }

        public float GetDistanceToNode(Vector3 origin, int destinationNodeIndex)
        {
   
            if (destinationNodeIndex < 0 || destinationNodeIndex >= PathNodes.Count ||
                PathNodes[destinationNodeIndex] == null)
            {
   
                return -1f;
            }

            return (PathNodes[destinationNodeIndex].position - origin).magnitude;
        }

        public Vector3 GetPositionOfPathNode(int nodeIndex)
        {
   
            if (nodeIndex < 0 || nodeIndex >= PathNodes.Count || PathNodes[nodeIndex] == null)
            {
   
                return Vector3.zero;
            }

            return PathNodes[nodeIndex].position;
        }

        void OnDrawGizmosSelected()
        {
   
            Gizmos.color = Color.cyan;
            for (int i = 0; i < PathNodes.Count; i++)
            {
   
                int nextIndex = i + 1;
                if (nextIndex >= PathNodes.Count)
                {
   
                    nextIndex -= PathNodes.Count;
                }

                Gizmos.DrawLine(PathNodes[i].position, PathNodes[nextIndex].position);
                Gizmos.DrawSphere(PathNodes[i].position, 0.1f);
            }
        }
    }
}

5. EnemyController的脚本设置

  • 利用PatrolPath函数,设置一个Patrol变量:
public PatrolPath PatrolPath {
    get; set; }
public NavMeshAgent NavMeshAgent {
    get; private set; }
public DetectionModule DetectionModule {
    get; private set; }
int m_PathDestinationNodeIndex;
//获取组件模块
NavMeshAgent = GetComponent<NavMeshAgent>();

  • 设置导航模式:
var navigationModules = GetComponentsInChildren<NavigationModule>();
            DebugUtility.HandleWarningIfDuplicateObjects<DetectionModule, EnemyController>(detectionModules.Length,
                this, gameObject);
            // Override navmesh agent data
            if (navigationModules.Length > 0)
            {
   
                m_NavigationModule = navigationModules[0];
                NavMeshAgent.speed = m_NavigationModule.MoveSpeed;
                NavMeshAgent.angularSpeed = m_NavigationModule.AngularSpeed;
                NavMeshAgent.acceleration = m_NavigationModule.Acceleration;
            }
  • 先设置bool值判断目标点位置是否为0,然后进行目标点的更新。
 bool IsPathValid()
        {
   
            return PatrolPath && PatrolPath.PathNodes.Count > 0;
        }

        public void ResetPathDestination()
        {
   
            m_PathDestinationNodeIndex = 0;
        }

        public void SetPathDestinationToClosestNode()
        {
   
            if (IsPathValid())
            {
   
                int closestPathNodeIndex = 0;
                for (int i = 0; i < PatrolPath.PathNodes.Count; i++)
                {
   
                    float distanceToPathNode = PatrolPath.GetDistanceToNode(transform.position, i);
                    if (distanceToPathNode < PatrolPath.GetDistanceToNode(transform.position, closestPathNodeIndex))
                    {
   
                        closestPathNodeIndex = i;
                    }
                }

                m_PathDestinationNodeIndex = closestPathNodeIndex;
            }
            else
            {
   
                m_PathDestinationNodeIndex = 0;
            }
        }

        public Vector3 GetDestinationOnPath()
        {
   
            if (IsPathValid())
            {
   
                return PatrolPath.GetPositionOfPathNode(m_PathDestinationNodeIndex);
            }
            else
            {
   
                return transform.position;
            }
        }

        public void SetNavDestination(Vector3 destination)
        {
   
            if (NavMeshAgent)
            {
   
                NavMeshAgent.SetDestination(destination);
            }
        }

        public void UpdatePathDestination(bool inverseOrder = false)
        {
   
            if (IsPathValid())
            {
   
                // Check if reached the path destination
                if ((transform.position - GetDestinationOnPath()).magnitude <= PathReachingRadius)
                {
   
                    // increment path destination index
                    m_PathDestinationNodeIndex =
                        inverseOrder ? (m_PathDestinationNodeIndex - 1) : (m_PathDestinationNodeIndex + 1);
                    if (m_PathDestinationNodeIndex < 0)
                    {
   
                        m_PathDestinationNodeIndex += PatrolPath.PathNodes.Count;
                    }

                    if (m_PathDestinationNodeIndex >= PatrolPath.PathNodes.Count)
                    {
   
                        m_PathDestinationNodeIndex -= PatrolPath.PathNodes.Count;
                    }
                }
            }
        }

6. Agent移动速度设置:

using UnityEngine;

namespace Unity.FPS.AI
{
   
    // Component used to override values on start from the NavmeshAgent component in order to change
    // how the agent  is moving
    public class NavigationModule : MonoBehaviour
    {
   
        [Header("Parameters")] [Tooltip("The maximum speed at which the enemy is moving (in world units per second).")]
        public float MoveSpeed = 0f;

        [Tooltip("The maximum speed at which the enemy is rotating (degrees per second).")]
        public float AngularSpeed = 0f;

        [Tooltip("The acceleration to reach the maximum speed (in world units per second squared).")]
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值