元のリンク: http://arongranberg.com/astar/docs/getstarted.php
プラグインのダウンロードアドレス: http://pan.baidu.com/s/1eROqaB4
余談:最近A*プラグインについて勉強したいのですが、ネット上に詳しいチュートリアルが見つからないので、公式サイトに行くしかありません。こんなに長い英語の記事を読むのは初めてなので、翻訳は良くありませんが、ご容赦ください。
概要:
A* プラグインのコア スクリプトは「astarpath.cs」であるため、パス検索に A* プラグインを使用する場合は、シーン内に「astarpath.cs」が 1 つ (シーンも 1 つだけ) 存在する必要があります。「astarpath.cs」は、コンポーネント -> パスファインディング -> パスファインダーから追加できます。
2 番目に重要なスクリプトは「seeker.cs」です。パス検索が必要なすべてのオブジェクトにこのスクリプトを用意するのが最善です (追加する必要はありませんが、追加するとパス検索が容易になります)。
次に、パスをよりスムーズかつシンプルにする「SimpleSmoothModifier.cs」というスクリプトがあり、これを「seeker」スクリプトと同じオブジェクトに追加する必要があります。
1. 新しいシーンを作成し、平面、位置 (0,0,0)、スケール (10,10,10) を作成します。新しいレイヤーを作成し (編集 -> プロジェクト設定 -> タグとレイヤー)、「Ground」という名前を付け、平面を「Ground」に設定し、障害物としていくつかの立方体を作成し、これらの立方体を新しいレイヤー「Obstacles」に設定します。
2. 新しいゲームオブジェクトを作成し、A* という名前を付け、「AstarPath」スクリプトを追加します。スクリプト内で最も重要な 2 つの項目は、以下の「グラフ」ボタンと「スキャン」ボタンです。「グラフ」にはすべての経路探索グラフが含まれており、最大 16 個まで存在できますが、通常は 1 つまたは 2 つで十分です。主なものは、「グリッド グラフ」(グリッド内にノードを生成) と「ナビメッシュ」(歩行可能な領域にメッシュを生成) の 2 つです。「スキャン」ボタンは、経路探索マップを更新するために使用されます。
3. 「グリッド グラフ」をクリックすると、幅 * 高さのサイズの一連のグリッドが生成されます。このグリッドはシーン内の任意の場所に配置でき、回転することもできます。「Node Size」はグリッドのサイズを設定できます。ここでは最初に1に設定します。5 つの点で構成される正方形のアイコンがあることに注意してください。その左下をクリックすると、アイコンの行の前のテキストが「左下」に変わり、(-50,-0.1,- に設定されます) 50)。浮動小数点エラーを避けるために、y 方向は -0.1 に設定されます。これは、地面の y 座標が 0 であり、パス探索マップも 0 である場合、高さ検出レイキャストを実行するときに問題が発生するためです。したがって、経路探索マップの y が地面の y よりわずかに小さいことを確認してください。グリッドをシーンに適応させるには、幅と深さを 100 に調整します。(実際の設定には問題があるようです。要するに、グリッドを面のサイズに合わせれば十分であり、「スキャン」で更新できます)
高さ検出
4. シーン内の正しい高さに経路探索ノードを配置するために、通常、検出のために光線が下向きに放射され、経路探索ノードが衝突点に配置されます。パスファインディング ノードのみが Ground で検出されるようにしたいため、マスクを Ground に設定します。光線が衝突しない場合は、検出されたオブジェクトが「Ground」に設定されていないか、上記の 3 番目の点で y が 0 に設定されていることを意味します。
衝撃チェック
5. ノードが配置されると、歩行できるかどうかの検出に使用されます。一般に、衝突検出には球、カプセル、またはレイが使用されます (ここでは、Physics.CapsuleCast または Physics.SphereCast を使用して AI オブジェクトをシミュレートすることを指します)。カプセルは、衝突に AI オブジェクトと同じ半径と高さを使用します。AI オブジェクトと障害物にエッジを持たせるために、ここではカプセルの半径を 2 に設定します。また、地面を障害物にしたくないため、衝突検出のレイヤーを障害物に設定します。下部にある「スキャン」をクリックすると、グリッドグラフの生成が確認できます。
AIを追加する
6. カプセルを作成し、「Character Controller」コンポーネントを追加して、平面上に配置します。「Seeker」コンポーネントを追加します。Seeker スクリプトは、他のスクリプトからのパス検索リクエストを処理するために使用されるヘルパー スクリプトです。パス修飾子 (通常、パス検索結果をスムーズに処理するスクリプト) も処理できます。次に、パス探索用のスクリプトを作成します。もちろん、プラグインの組み込みスクリプトを使用することもできます。A* プラグインには、経路探索のためにオブジェクトにフックするための 2 つの AI スクリプトが付属しています: AIPah はあらゆる種類の経路探索マップに適用でき、RichAI は主に NavMesh タイプに適用できます。
オブジェクトが道を見つけられるようにする
7. シーク スクリプトには重要なメソッドがあります: function StartPath (Vector3 start, Vector3 end, OnPathDelegate callback = null) : Path。パラメータは開始位置、終了位置、コールバック関数です。OnPathDelegate がデリゲートである場合、呼び出される関数は「void SomeFunction (Path p)」に似ています。
スクリプトは次のとおりです。
-
using UnityEngine;
-
using System.Collections;
-
//Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
-
//This line should always be present at the top of scripts which use pathfinding
-
using Pathfinding;
-
public class AstarAI : MonoBehaviour
-
{
-
public Transform target;
-
public void Start()
-
{
-
//Get a reference to the Seeker component we added earlier
-
Seeker seeker = GetComponent<Seeker>();
-
//Start a new path to the targetPosition, return the result to the OnPathComplete function
-
seeker.StartPath(transform.position, target.position, OnPathComplete);
-
}
-
public void OnPathComplete(Path p)
-
{
-
Debug.Log("Yay, we got a path back. Did it have an error? " + p.error);
-
}
-
}
このスクリプトをオブジェクトに追加してパスを検索し、ターゲットに値を割り当てて、「再生」をクリックすると、パス検索用のパスである緑色の線が表示されます。この時点ではオブジェクトは移動しません。
緑色の線が表示されない場合は、「Seek」スクリプトの「Gizmos を表示」にチェックが入っているかどうかを確認してください。それともUnity版のせいでGizmosで描いた線が平面の下に隠れてしまうのかもしれません。
描かれた線が滑らかではないことがわかりますが、後で美化されます。
コールバックを設定する方法は次のようにすることもできます。
-
//OnPathComplete will be called every time a path is returned to this seeker
-
seeker.pathCallback += OnPathComplete;
-
//So now we can omit the callback parameter
-
seeker.StartPath (transform.position,targetPosition);
上記のメソッドにコールバックを追加した後、スクリプトを削除または破棄する場合は、次の操作を行う必要があることに注意してください。
-
public void OnDisable () {
-
seeker.pathCallback -= OnPathComplete;
-
}
コールバックの後、Path p を通じて計算されたパスを取得できます。これで何ができるでしょうか?
計算されたパスには 2 つの重要なリストがあります。
1.Path.vectorPath は、各パス ポイントの位置を保存する Vector3 リストです。
2.Path.path はノードリストであり、各パスポイントのノードを保存します。
次に、上記のスクリプトを展開します。
-
using UnityEngine;
-
using System.Collections;
-
//Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
-
//This line should always be present at the top of scripts which use pathfinding
-
using Pathfinding;
-
public class AstarAI : MonoBehaviour
-
{
-
//The point to move to
-
public Transform target;
-
private Seeker seeker;
-
private CharacterController controller;
-
//The calculated path
-
public Path path;
-
//The AI's speed per second
-
public float speed = 100;
-
//The max distance from the AI to a waypoint for it to continue to the next waypoint
-
public float nextWaypointDistance = 3;
-
//The waypoint we are currently moving towards
-
private int currentWaypoint = 0;
-
public void Start()
-
{
-
seeker = GetComponent<Seeker>();
-
controller = GetComponent<CharacterController>();
-
//Start a new path to the targetPosition, return the result to the OnPathComplete function
-
seeker.StartPath(transform.position, target.position, OnPathComplete);
-
}
-
public void OnPathComplete(Path p)
-
{
-
Debug.Log("Yay, we got a path back. Did it have an error? " + p.error);
-
if (!p.error)
-
{
-
path = p;
-
//Reset the waypoint counter
-
currentWaypoint = 0;
-
}
-
}
-
public void FixedUpdate()
-
{
-
if (path == null)
-
{
-
//We have no path to move after yet
-
return;
-
}
-
if (currentWaypoint >= path.vectorPath.Count)
-
{
-
Debug.Log("End Of Path Reached");
-
return;
-
}
-
//Direction to the next waypoint
-
Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
-
dir *= speed * Time.fixedDeltaTime;
-
controller.SimpleMove(dir);
-
//Check if we are close enough to the next waypoint
-
//If we are, proceed to follow the next waypoint
-
if (Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]) < nextWaypointDistance)
-
{
-
currentWaypoint++;
-
return;
-
}
-
}
-
}
次にゲームを実行するとオブジェクトが動きます。ウェイポイントは連続的ではないことに注意してください。オブジェクトが次のウェイポイントから nextWaypointDistance よりも小さい場合、オブジェクトは先に進みます。最後に、オブジェクトはターゲットからある程度の距離で停止します。これは、終点に特別な処理が必要であるためですが、スクリプトはまだそれを処理していません。
滑らかな道
8. このとき、組み込みスクリプト「Path Modifiers」を使用し、「seeker」スクリプトでオブジェクトに追加する必要があります。(ただし、この名前のスクリプトは見つからないようです。コンポーネント –> パスファインディング –> モディファイア –> シンプル スムーズからスクリプトを追加することもできます)。スムージングの原理は、パス ポイント間の距離が小さくなるように、小さなパスのセクションを引き続き細分化することです。ここではまず、[最大セグメント長] を 1、[反復] を 5、[強度] を 0.25 に設定します。走行後は緑のラインが滑らかになっていることがわかります。
最後に: 上記のスクリプトを使用したパスファインディングは完璧ではなく、毎回スクリプトを記述するのは面倒なので、パスファインディングするオブジェクトに「AIPath」スクリプトを直接追加してターゲットを割り当てると、より効果的です。上記のスクリプトの内部を理解するだけです。
- いいね 4
- コメント1
- お気に入り 4
- 携帯電話で見る
- 記事レポート
1503
パスファインディングプラグインA * パスファインディング プロジェクト_Proシステム学習(2) _AIPathコンポーネント_Seekerコンポーネント_パスファインディング機能