動く障害物を作る

次は動く障害物を導入してステージに変化をつけられるようにしてみましょう。

スポンサーリンク

障害物の基底クラスの作成

まず、障害物のスクリプトに共通する部分をいちいち書かなくてもいいようにするために障害物の基底クラスを作っておきます。これを継承して個別の障害物のクラスを作ることで省力化しようというわけです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Trap : MonoBehaviour
{
	[SerializeField]
	protected float waitTime;

	protected bool stop = false;

	protected virtual void Start ()
	{
		
	}
	
	protected virtual void Update ()
	{
		
	}

	protected IEnumerator Wait()
	{
		stop = true;

		yield return new WaitForSeconds(waitTime);

		stop = false;
	}
}

ここでは一定時間の間だけ動きを止める機能を基本機能として追加しています。

スポンサーリンク

動く床

基底クラスができたので、まずアクションゲームでは定番の「動く床」を作ります。これはとても応用が利く障害物で、動かす軸によっては上下する床になったり、ユニティちゃんをコース外に押し出す壁になったりします(下図参照)。

動く床1動く床2

動く床のプログラム

適当なCubeに下記のプログラムをアタッチしてください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveCube : Trap
{

	[SerializeField]
	float moveX;
	[SerializeField]
	float moveY;
	[SerializeField]
	float moveZ;
	[SerializeField]
	float speed;

	float step;
	bool goBack = false;
	Vector3 origin;
	Vector3 destination;

	protected override void Start()
	{
		origin = transform.position;
		destination = new Vector3(origin.x - moveX, origin.y - moveY, origin.z - moveZ);
	}

	protected override void Update()
	{
		if (stop)
		{
			return;
		}

		step = speed * Time.deltaTime;

		if (!goBack)
		{
			transform.position = Vector3.MoveTowards(transform.position, destination, step);

			if(transform.position == destination)
			{
				goBack = true;

				StartCoroutine(Wait());
			}
		}
		else
		{
			transform.position = Vector3.MoveTowards(transform.position, origin, step);

			if(transform.position == origin)
			{
				goBack = false;

				StartCoroutine(Wait());
			}
		}
	}

}

プログラムの解説

元の座標と目的地の座標の間を往復運動するプログラムです。Updateの中ではMoveTowardsメソッドで目標の座標まで移動させる処理を行っています。

スポンサーリンク

回転する壁

次は回転する壁です。

回転する壁のプログラム

こちらも適当なCubeにアタッチしてください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateCube : Trap
{
	[SerializeField]
	float rotateX;
	[SerializeField]
	float rotateY;
	[SerializeField]
	float rotateZ;
	
	protected override void Update ()
	{
		transform.Rotate(new Vector3(rotateX, rotateY, rotateZ) * Time.deltaTime, Space.World);
	}
}

プログラムの解説

1秒間に指定した分だけ回転する処理を行っています。Unityでの回転というと難しいイメージがありますが、今回の場合はRotateメソッドを使ってシンプルに実現できるようにしました。

テストプレイして思った通りの動きをしていれば完成です。あとはステージに適当に配置してください。


次のページ→サウンドをつける