※ これは 2021/03/05 時点の Unity 2020.2.7f1 の情報です
最新版では動作が異なる可能性がありますのでご注意ください
前回は Tilemap
に応じて NavMesh
を生成してみたので、さっそくこれにしたがってねこキャラを動かしてみたい
キャラの中心点が NavMesh
の範囲を通るので、こんな感じに前回生成したものより細い道になるよう、まずは Navigation
の Agents
タブの Radius
を大きな値にした
スポンサードリンク
次に Hierarchy
上の ‘Catと
Chaserと
Gridの GameObkect を
MainView` という名前の GameObject の子どもになるように変更
Cat
の GameObject の Component から下記のように Player Input
を削除し、Tap Effect
の参照もなくす
代わりに MainView
の方に Player Input
を追加し、後述する MainView
の Script を追加し、Tap Effect
の Prefab と Cat
の参照を設定
Player Input
の中の Fire
イベントハンドラも指定する
MainView.cs
は下記の通り
using UnityEngine; using UnityEngine.InputSystem; public class MainView : MonoBehaviour { [SerializeField] private GameObject tapEffect = null; [SerializeField] private Cat cat = null; public void OnFire(InputAction.CallbackContext context) { this.cat.Target = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue()); // タップ跡を表示 var effect = Instantiate(this.tapEffect, this.cat.Target, Quaternion.identity, this.transform); // 1秒後に消滅 Destroy(effect, 1f); } }
マウスクリック地点を受け取って Cat
の Target
プロパティに代入する
Cat.cs
の方はこんな感じに修正
using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; public class Cat : MonoBehaviour { /// <summary> /// 最終目的地 /// </summary> public Vector2 Target { get => this.target; set { if (this.target == value) { return; } this.target = value; this.Calculate(); } } private Vector2 target = Vector2.zero; private Animator animator = null; private Queue<Vector3> corners = new Queue<Vector3>(); private Vector2 next = default; public void Awake() { this.animator = this.GetComponent<Animator>(); this.next = (Vector2)this.transform.position; this.Target = this.next; } private void Calculate() { // NavMesh に応じて経路を求める NavMeshPath path = new NavMeshPath(); if (NavMesh.CalculatePath(this.transform.position, this.target, NavMesh.AllAreas, path)) { this.corners = new Queue<Vector3>(path.corners); this.next = (Vector2)this.transform.position; } } private void GoNext() { // 次の目的地を取得する if (this.corners.Count < 1) { return; } this.next = this.corners.Dequeue(); } public void Update() { // 目的地に近づいたら次の目的地を目指す var current = (Vector2)this.transform.position; if (Vector2.Distance(this.next, current) < 0.2f) { this.GoNext(); } var direction = this.next - current; if (direction != Vector2.zero) { var normalized = new Vector3(Mathf.Round(direction.normalized.x), Mathf.Round(direction.normalized.y), 0); // 斜め方向も許容 if (normalized != Vector3.zero) { this.animator.SetFloat("x", normalized.x); this.animator.SetFloat("y", normalized.y); } this.transform.Translate(direction.normalized * Time.deltaTime * 3f); } } }
NavMesh
に応じて最終目的地までの経路を計算し、順番に移動するようにした
これでお試し
とりあえず白ねこの方だけ箱をよけて動くようになった!