Unity Navigation寻路系统并画出指引线

前言

寻路系统是游戏中很常用的一个功能,角色要达到某一点,需要系统给出一个路径,这样可以帮助玩家规划出路径,提示玩家到达,这种功能在各种类型的游戏中都有大量的应用

本案例通过Navigation实现寻路系统的同时使用Line Renderer组件标识出指示线,最终完成效果图为:

在这里插入图片描述

实现过程

1,利用Navigation烘培场景

为了实现自动寻路的功能,首先需要对场景进行基本的设置,以便让系统识别哪些判断哪些是可运动区域,而哪些又是不可运动区域,Navigation导航系统的判断条件是基于静态物体进行的,如果想对于动态物体进行判断,则需要添加响应的组件。

要将物体设为静态,首先在场景中选中静止地面和障碍物,在Unity编辑器Inspector面板的左上角选择Static选项的倒三角并将Navigation Static勾选上:
在这里插入图片描述
接下来进入Navigation面板,进行场景的烘培,从上到下依次点击两个Bake即可,图中的蓝色区域即为角色可移动区域,而非蓝色区域则是不可跨越区域,就是相关的障碍物:

而关于烘培的具体细节可以查看之间的文章:

在这里插入图片描述

2,为角色添加响应组件

为了保证角色可以实现寻路和指示线功能,需要添加Nav Mesh AgentLine Renderer两个组件:

首先对于Nav Mesh Agent的参数调整,要实现可角色的路径设置,本案例而对于该组件的参数调整主要是两方面,第一是其速度Speed,设置数值大小可以改变移动速度的大小,另一点则是加速度,在目标发生改变时,速度改变的大小

对于第二个组件Line Renderer是本案例的重点,其主要功能就是用来在三维场景中画出线条,通过使用这一特性,可以描绘出角色将要移动的路径,这样就可以实现物体的导航功能

关于LIne Randerer

  • Line Renderer 组件在三维空间中接受两个或多个点的数组,并在每个点之间绘制一条直线。你可以使用直线渲染器绘制任何东西,从简单的直线到复杂的螺旋线。线总是连续的; 如果你需要画两个或更多完全独立的线,你应该使用多个游戏对象,每个都有自己的线渲染器。线条渲染器不呈现像素宽度的线条。它渲染的多边形有一个世界单位宽度。线条渲染器使用与 Trail 渲染器相同的线条渲染算法。

在本案例中,我们在添加该组件后,首先需要为其添加材质,可以在Materials设置材质的数量,并为其添加材质,并在width中调整其宽度,具体调整如图:
在这里插入图片描述

3,编写脚本调用两个组件实现导航

通过脚本调用连个组件,首先使用各自的方法完成各自的功能,使用Navigation结合射线检测碰撞来完成角色移动到点击的位置,而Line Renderer组件则在获取的一系列的点之间画出线,而完成两者之间的结合则是需要通过Navigation组件的指定函数来获取到导航时转弯的一系列的点位,并将其指定给Line Renderer,这样就完成了画线功能:

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

public class FindRode : MonoBehaviour
{
    
    
    private NavMeshAgent agent;
    private LineRenderer line;
    // Start is called before the first frame update
    void Start()
    {
    
    
        agent = GetComponent<NavMeshAgent>();
        line = GetComponent<LineRenderer>();        
    }
    // Update is called once per frame
    void Update()
    {
    
    
        if(Input.GetMouseButtonDown(1))
        {
    
    
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if(Physics.Raycast(ray,out hit,500))
            {
    
    
                if(hit.transform.tag=="ground")
                {
    
    
                    agent.SetDestination(hit.point);
                }
            }
            
        }
        //如果导航里面的点大于1
        if(agent.path.corners.Length>1)
        {
    
    
        	//画线的点位等于导航的点位
            line.positionCount = agent.path.corners.Length;
            line.SetPositions(agent.path.corners);
        }
    }
}

两者之间的结合在If判断里面,我们可以通过agent.path.corners.Length属性来知道需要画出线的点位个数,并通过SetPositions()可以获取所有坐标的数组,这样就可以实现在相邻两个点之间进行画线

猜你喜欢

转载自blog.csdn.net/xinzhilinger/article/details/113540207