P1L1——路点和寻路

塔防游戏的敌人需要沿着固定的路线行走,因此敌人需要沿着路点进行寻路
在场景上设置一些路点,敌人会主动向路点直线移动,走到路点后就转向另一个路点移动,直到遍历所有路点

例如下面的场景,Cube需要沿着这几个路点依次进行移动:

image

这里的实现思路是:

  • 所有的路点被一个父对象管理,路点父对象挂载一个获取节点位置和节点数量的脚本Path
  • Cube挂载寻路脚本PathFind​,寻路脚本和路点父对象的Path​关联,
    通过得到的路点位置移动,到达点就切换到下一个路点,直至遍历所有路点

Path.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System.Collections.Generic;
using UnityEngine;

//管理所有路点,对外提供其位置,以及管理的路点数量
public class Path : MonoBehaviour
{
//通过列表管理各个路点
List<Transform> nodeList = new List<Transform>();

void Start()
{
//遍历子对象,将所有的路点加入到列表
foreach (Transform node in transform)
{
nodeList.Add(node);
}
}

//通过索引获取某个路点位置的方法,供PathFind移动使用
public Vector3 GetNodePos(int i)
{
return nodeList[i].position;
}

//获取管理的所有的路点数量,供PathFind确认是否已经走完所有的路点
public int GetMaxNodeNum()
{
return nodeList.Count;
}
}

PathFind.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;

public class PathFind : MonoBehaviour
{
public Path path; //当前寻路所用的父对象的Path脚本,通过它获取路点信息
public int curPathNodeIndex = 0; //当前寻路目标路点的索引

void Update()
{
//通过当前索引与Path路点数量比较确认是否到达终点
if (curPathNodeIndex >= path.GetMaxNodeNum())
{
print("到达终点");
return;
}
//获取当前寻路的目标位置
Vector3 curNodePos = path.GetNodePos(curPathNodeIndex);
float dis = Vector3.Distance(curNodePos, transform.position);
//当距离小于一定值时,认为到达了路点,切换下一个路点
if (dis < 0.1f)
curPathNodeIndex++;
//获取方向
Vector3 dir = (curNodePos - transform.position).normalized;
//位移,假设速度是6
transform.position += dir * 6 * Time.deltaTime;
}
}