今回のゲームでは、敵はライン状を移動させます。ライン移動の処理は専用のスクリプトを用意します。
ここでやること
まずは敵キャラの作成を行いたいと思います。ライン上を移動し、到着時に把握できるようなものを作ります。
見た感じはこんなものを作る
ライン上を移動して、到着したことを確認(ログを出すことで確認)
トピック内容
- LineRendererの使い方
- LineRendererでいろんなラインを描けるようにする
- ついでにライン上を移動できるようなスクリプトを準備
- 敵キャラを作成
- スクリプト作成
- LineMoverを使ったデモ
- 到着時にログを出して、終点まで移動したことを知れるようにする
移動するラインを作成する
まずは経路に相当する移動ラインを作成します。ラインにはLineRendererを利用します。
LineRendererで線を表示する
まずはヒエラルキーのなにもないところを右クリックして、Effect>LineからLineRendererを作成します。特に基準点はないので、Transformの座標はリセット。
適当に経路を作ってみましょう。注意点としてはZ座標がおかしくなっているとGameビューで見えないことがありますので、Positionsがおかしくないか確認してください。
LineRendererの使い方がわからない場合はこちらのリンクからLineRendererの使い方を参考にしながら作って見ましょう。
ライン上を移動するためのサポートスクリプト
次に、LineRenderer上に沿ってオブジェクトを移動させるためのスクリプトを準備します。上記のLineRendererの使い方ページにあるのと同じですが、一応載せておきます。(メンテナンスの関係でズレている場合、リンク先のスクリプトを参考にしてください)
スクリプトファイルは、Assets直下にScriptsというフォルダを作成して、その中にLineMoverという名前のスクリプトを作成してください。スクリプト関連は、以降このフォルダに集約します。
using UnityEngine;
using System;
public class LineMover : MonoBehaviour
{
[SerializeField] private LineRenderer lineRenderer;
[SerializeField] private float speed = 1f;
private int currentIndex;
public EventHandler OnEndReached;
private void Start()
{
Initialize(0, speed, lineRenderer);
}
// このメソッドはテストで使います
public void SetSpeed(float speed)
{
this.speed = speed;
}
public void Initialize(int index, float speed, LineRenderer lineRenderer)
{
enabled = true;
currentIndex = index;
this.speed = speed;
this.lineRenderer = lineRenderer;
transform.position = this.lineRenderer.GetPosition(currentIndex);
}
public static (Vector3 targetPosition, bool isEnd) GetTargetPosition(ref int index, float moveSpeed, Vector3 currentPosition, LineRenderer lineRenderer)
{
int nextIndex = index + 1;
if (lineRenderer.positionCount <= nextIndex)
{
return (lineRenderer.GetPosition(index) + lineRenderer.transform.position, true);
}
var nextPosition = lineRenderer.GetPosition(nextIndex) + lineRenderer.transform.position;
float distance = Vector3.Distance(currentPosition, nextPosition);
if (distance < moveSpeed)
{
index += 1;
return GetTargetPosition(ref index, moveSpeed - distance, nextPosition, lineRenderer);
}
else
{
Vector3 direction = (nextPosition - currentPosition).normalized;
return (currentPosition + direction * moveSpeed, false);
}
}
private void Update()
{
var result = GetTargetPosition(
ref currentIndex,
speed * Time.deltaTime,
transform.position,
lineRenderer);
transform.position = result.targetPosition;
if (result.isEnd)
{
OnEndReached?.Invoke(this, EventArgs.Empty);
enabled = false;
}
}
}
敵キャラをラインに沿って移動させる
敵キャラは、このあとのメンテナンス性を考慮して、LineRenderer上を移動させます。経路を変更したりするのにとても便利です。
敵キャラのオブジェクトを作成
まずは敵キャラの基本になるものを作成します。
- Images/takotako01という画像をシーンビューにドラッグアンドドロップします。
- 座標は画面中央(0,0,0)にセット
- 敵キャラ制御用のスクリプトを作成し、アタッチします
- EnemyControllerというスクリプトを作成
- 作成できたら敵キャラのインスペクターにアタッチします。
- スクリプトは後で編集しますので、いったんそのままでOK
- LineMoverスクリプトを同じ位置にアタッチ
ライン上の移動と終点チェック
ここまで準備が出来たら一度動かしてみて、終点まで到達したのをログで確認してみましょう。まずEnemyControllerのスクリプトを次のように変更します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
private void Start()
{
var lineMover = GetComponent<LineMover>();
lineMover.OnEndReached += (sender, e) =>
{
Debug.Log("お城に到着したよ!");
};
}
}
スクリプトが変更できたら、インスペクター上での設定を行います。LineMoverはインスペクターでセットされたライン状を勝手に移動します。これは後に外部から設定したいので変更しますが、まずはその設定を利用して、勝手に移動してもらいましょう。設置済みのLineRendererをインスペクターにセットし、Speedを5にします。(Speedに関しては任意ですが、遅いと感じたら変更してください)
動かして確認
経路場を動くのはもちろん、終点に到達したときにログが表示されることを確認してください。これでぐるぐる回るような道でもジグザグでも、好きな経路を作ることができるようになりましたね。
ゲームでは終点に到達するとお城にダメージを与えて消えます。
コメント