zoukankan      html  css  js  c++  java
  • Unity自动寻路Navmesh之高级

    • 隔离层自动生成寻路网格

    (源码scene1.unity)
    1.创建Plane实例P1,P2,两者之间出现一条鸿沟。直接控制角色位移是无法通过的。
    2.打开Navigation窗口,分别选中P1,P2,分别设置Navigation Static 和OffMeshLink Generatic

    3.保存场景,点击场景烘焙按钮Bake。结束后我们可以看到P1,P2除了自身生产寻路网格外,它们直接还生成了连接纽带。
    4.添加角色模型Solder,为其添加NavMeshAgent(Component->Navigation->NavMeshAgent)
    5.给Solder添加PlayerController脚本

        using UnityEngine;  
        using System.Collections;  
          
        public class PlayerController : MonoBehaviour  
        {  
            private NavMeshAgent agent;  
          
            public bool setAgentWalkMask;//是否需要动态修改寻路层,在scene4的实例中要用到  
          
            void Start()  
            {  
                //获取寻路组件  
                agent = GetComponent<NavMeshAgent>();  
            }  
          
            void Update()  
            {  
                //鼠标左键点击  
                if (Input.GetMouseButtonDown(0))  
                {  
                    //摄像机到点击位置的的射线  
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  
                    RaycastHit hit;  
                    if (Physics.Raycast(ray, out hit))  
                    {  
                        //判断点击的是否地形  
                        if (!hit.collider.tag.Equals("Plane"))  
                        {  
                            return;  
                        }  
                        //点击位置坐标  
                        Vector3 point = hit.point;  
                        //转向  
                        transform.LookAt(new Vector3(point.x, transform.position.y, point.z));  
                        //设置寻路的目标点  
                        agent.SetDestination(point);  
                    }  
                }  
          
                //播放动画  
                if (agent.remainingDistance == 0)  
                {  
                    animation.Play("Idle");  
                }  
                else  
                {  
                    animation.Play("Run");  
                }  
                  
            }  
        }  

    5.点击任意的位置,可以看到角色都能自动寻路过去
    效果图

    • 手动指定寻路网格方向

    源码scene2.unity
    1.scene1.unity的基础上,将P1,P2的OffMeshLink Generatic去除
    2.在P1上新建一个空的GameObject Start,P2上新建一个空的GameObject End
    3.选中start,为它添加Off Mesh Link组件 Component->Navigation->OffMeshLink
    4.设置Off Mesh Link组件的属性,Start Point 为 start,End Point为end
    5.烘焙场景。我们可以看到有一条纽带从start指向end
    点击地图,可以看到角色如果要跨越P1和P2,一定是沿着我们手动创建的路径

    • 导航网格障碍物 Navmesh Obstacle

    之前我们都是用固定的物体作为障碍物,然后烘焙场景。Unity还提供了动态的障碍物。任何一个GameObject都可以添加Navmesh Obstacle组件,变成一个障碍物。具体步骤是Component->Navigation->Navmesh Obstacle.它有两个属性:半径和高度,可以设置跟你的物品差不多的体积大小。

    • 寻路网格层的应用

    源码scene3.unity
    玩过“3c”,“dota”这类游戏的同学都知道:地图上有上中下三条大道,不同的兵可能去的路不同。今天我们也做个类似的实例。
    1.新建P1,P2,P3,P4等4个Plane,具体摆设形状见效果图
    2.在Navigation窗口中,添加两个层Layers:Blue层和Red层
    3.P1,P2的Navigation Layer设置为Default,P4的Navigation层设置为Red,P3设置为Blue
    4.添加两个角色,设置他们的NavMeshAgent寻路层(NavMesh Walkable)。一个将Red层去掉,一个将Blue层去掉
    5.点击P2的坐标,可以看到他们沿着不同的路径去目标点,一个走上层路线,一个走下层路线了。
    效果图

    • 动态改变寻路网格层

    源码scene4.unity
    在游戏中,我们很多时候都是需要根据不同的条件,选择不同的寻路路径。
    1.在scene3.unity基础上做一下修改。只保留一个角色
    2.新增两个按钮,“走上层”和“走下层”,在游戏运行时,可以改变Agent的寻路层。

        //动态设置寻路路径层  
           void OnGUI()  
           {  
               if (!setAgentWalkMask)  
               {  
                   return;  
               }  
               if (GUI.Button(new Rect(0, 0, 100, 50), "走下层"))  
               {  
                   agent.walkableMask = 65;  
               }  
          
               if (GUI.Button(new Rect(0, 100, 100, 50), "走上层"))  
               {  
                   agent.walkableMask = 129;  
               }  
           }  

    3.重新点击寻路,可以看到,选择不同的寻路层,角色的寻路路径也不同


    看到代码中的agent.walkableMask = 65和129,大家会比较迷惑,其实寻路层每一层都是2的幂,见下图

    所以上层的mask = Default(1)+Blue(128) = 129,下层的mak = Default(1)+Red(64) = 65

  • 相关阅读:
    STS IDE 个性化修改
    tomcat发布web项目,支持域名
    执行 maven 命令 报错Unable to add module to the current project as it is not of packaging type 'pom'[转]
    从数组中返回最大长度的所有子数组
    springboot 1.5.x 使用tomcat8设置cookie的domain以dot开头报错
    tomcat服务器配置字符集为utf-8-彻底解决中文乱码问题
    通配符的匹配很全面, 但无法找到元素 'mvc:annotation-driven' 的声明
    Java原理之HashMap
    你应该知道的JAVA面试题
    sql 置顶功能的查询
  • 原文地址:https://www.cnblogs.com/jiangshuai52511/p/5775632.html
Copyright © 2011-2022 走看看