A尋路看似簡單,但實際專案中的各種應用是有一定難度的,需要較強的演算法功底,不過,幸運的是,Unity Asset Store中已經有了現成的A尋路插件"A* Pathfinding Project"(作者:Aron Granberg),它有免費版和收費兩個版本,不過一般免費版足以讓我們使用,
下載鏈接1:http://arongranberg.com/astar/download
下載鏈接2:https://download.csdn.net/download/qq_42434073/15116553
-
先演示下效果:

-
插件的匯入:
常規方法:Asset-Import Package-Custom Package 選擇我們下載好的插件,打開即可:

匯入后可以在[Component]工具中看到多出了“Pathfinding”選項:

-
場景的搭建:
3.1 新建兩個Layer:
單機[Edit] - [Project Setting] - [Tags and Layers], 創建一個Obstacles 與一個Ground層:

3.2
(1)在場景中新建一個平面,設定Scale:10,1,10,并在Inspector中將Layer改為“Ground”:

(2)動手搭建我們的若干障礙體,然后將這些障礙的Layer全部設定為Obstacles:

3.3 創建一個Cube 或者Sphere 代替玩家;
在地圖上某一位置新建一個物體,作為尋路的終點;
創建一個空物體,命名為A*,作為A的管理器;
3.4 選擇A物體,然后單擊[Component] - [Pathfinding] - [Pathfinder] 這時可以看到Inspector面板中出現了一個Astar Path的代碼組件:

單擊Graphs,提示添加新的Graph,這里的Graph種類包括Grid Graph、Layered Grid Graph、NavMeshGraph、RecastGraph,可以選擇不同的導航圖型別;
3.5 先創建一個基于單元的導航圖
(1)單擊Grid Graph,會生成一個Widthdepth(設定為100100)的規則網格,將Node Size設定為1,Center設定為0,-0.1,0(Y坐標設定為-0.1是為了避免浮點數帶來的誤差)

(2)碰撞測驗:

碰撞測驗通常都選擇膠囊體,
半徑與高度根據玩家物體的尺寸調節,最好設定略大一點,保證安全,
碰撞測驗的Mask 選擇“Obstacles”層
(3)高度測驗

第一個是檢測射線投射的高度,第二個選擇“Ground”層
(4)Scan瀏覽一下網格劃分
4. 給角色添加代碼:
首先選中玩家物體后,選擇[Component] - [Pathfinding] - [Seeker] ,這樣才能獲取到路徑
代碼的思路:
(1)使用插件的內置函式Seeker.StartPath(起點,終點),尋找路徑
(2)當路徑搜索結束后,會自動將路點存盤起來,我們不斷的朝向下一個路點,便可以一步步走到終點;
給玩家添加C#Script 命名為AstarAI,編輯如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
using System;
public class AstarAI : MonoBehaviour
{
//目標物體與目標位置
public GameObject targetObject;
private Vector3 targetPosition;
private Seeker seeker;
//存盤路徑
public Path path;
//角色移動速度
public float speed = 100.0f;
public float turnSpeed = 5f;
//判斷玩家與航點的距離
public float nextWaypointDistance = 3;
//對當前的航點進行編號
private int currentWaypoint = 0;
// Start is called before the first frame update
void Start()
{
seeker = GetComponent<Seeker>();
//注冊回呼函式,在Astar Path完成后呼叫此函式
seeker.pathCallback += OnPathComplete;
}
// Update is called once per frame
void FixedUpdate()
{
targetPosition = targetObject.transform.position;
//開始尋路
seeker.StartPath(transform.position, targetPosition);
if (path==null)
{
return;
}
//當前搜索點編號大于等于路徑存盤的總點數時,路徑搜索結束
if (currentWaypoint>=path.vectorPath.Count)
{
Debug.Log("路徑搜索結束");
return;
}
Vector3 dir = (path.vectorPath[currentWaypoint+1] - transform.position);//.normalized;
dir *= speed * Time.fixedDeltaTime;
//玩家轉向
transform.Translate(Vector3.forward*Time.fixedDeltaTime*speed);
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * turnSpeed);
//玩家當前位置與當前的航向點距離小于一個給定值后,轉向下一個航向點
if (Vector3.Distance(transform.position,path.vectorPath[currentWaypoint])<nextWaypointDistance)
{
currentWaypoint++;
return;
}
}
/// <summary>
/// 當尋路結束后呼叫這個函式
/// </summary>
/// <param name="p"></param>
private void OnPathComplete(Path p)
{
Debug.Log("發現這個路線"+p.error);
if (!p.error)
{
path = p;
currentWaypoint = 0;
}
}
private void OnDisable()
{
seeker.pathCallback -= OnPathComplete;
}
}
- 路徑的平滑,在Path Modifiiers中包含了路徑平滑和簡化腳本,也可以直接選中玩家,然后單擊[Component] - [Pathfinding] - [Modifiers] - [Simple Smooth],便會生成路線的平滑效果,在Inspector面板中可以修改引數,出現不同的平滑效果,
- 開始運行啦,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/257741.html
標籤:AI
上一篇:錐體鏈視點|區塊鏈成多省市作業關注點,山西如何發展區塊鏈?
下一篇:2021年美賽C題思路
