簡単なパズル風ゲーム作成の第3回目です。「ゴール」と「ゴール出現ギミック」を設定していきます。
はじめに
前回の続きの第3回目です。第1回目は下記から。
ゲーム作成開始
1回目、2回目で「地面」、「壁」、「プレイヤー」、「ブロック」、「スイッチ」を一通り作成しました。今回は「ゴール」と「ゴールが出現するギミック」の作成をしていきます。
ゴールの作成
まずはゴールを作成。
ヒエラルキーメニューから「3Dオブジェクト」→「平面」を追加。名前をGoalにしておきます。

「位置」と「スケール」を変更し、色も分かりやすいように変えておきます。

とりあえず端の方に配置。

起動ギミック
次に、「ゴールを起動する部分」を作成します。
「スイッチを踏んだからゴールが起動」ですが、スイッチは一つとは限らないため、複数スイッチに対応したのを作成していきます。
まずはヒエラルキーメニューから「空のオブジェクトを作成」。名前はGameManagerに。

スイッチONのオブジェクトに新しいタグを割り当てます。とりあえず、SwitchONとしています。

新しいスクリプトを作成し、名前をGameManagerに。
スクリプトの中身を下記に変更します。Awakeは立ち上がりに起動するので、Startよりも早く呼び出されます。SwitchONのオブジェクトと数を保管して、ONを無効にしています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject GoalObject;
private GameObject[] _switchObjects;
private int _switchNum;
private int _SwitchOnCount;
void Awake()
{
_switchObjects = GameObject.FindGameObjectsWithTag("SwitchON");
_switchNum = _switchObjects.Length;
for (int i = 0; i < _switchNum; i++)
{
_switchObjects[i].SetActive(false);
}
}
}
タグでオブジェクトを探す場合、オブジェクトが有効になっていないとカウントされないのでデフォルトは有効にしておき、スクリプト内で無効にします。
ゴールも一緒にスクリプト内で無効にしても良いですね。

ついでにGameManagerスクリプトに下記の関数も追加。
全部のスイッチ数とONのスイッチ数を比較して「ゴールを有効/無効」にしています。
public void SwitchCount()
{
_SwitchOnCount = 0;
for (int i = 0; i < _switchNum; i++)
{
if (_switchObjects[i].activeSelf) _SwitchOnCount++;
}
if(_switchNum == _SwitchOnCount)
{
GoalObject.SetActive(true);
}
else
{
GoalObject.SetActive(false);
}
}
スイッチスクリプトを下記に変更して、スイッチON,OFFのタイミングでスイッチONの数をカウント。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Switch : MonoBehaviour
{
public GameObject onSwitch;
public GameObject offSwitch;
public GameObject GameManagerObj;
private void OnTriggerEnter(Collider other)
{
onSwitch.SetActive(true);
offSwitch.SetActive(false);
GameManagerObj.GetComponent<GameManager>().SwitchCount();
}
private void OnTriggerExit(Collider other)
{
onSwitch.SetActive(false);
offSwitch.SetActive(true);
GameManagerObj.GetComponent<GameManager>().SwitchCount();
}
}
スイッチオブジェクトとゲームマネージャーオブジェクトに変数をセット。

一度動かしてみて、スイッチにブロックを乗せた時にゴールが出てこればOK
複数のスイッチで実験
次に複数のブロックで試してみます。まずは適当に内壁を設置。

ブロックとスイッチをコピーして、親オブジェクトとして「Stage1」として下のような感じに構造的にまとめておきます。

スイッチとブロックを下記の様に適当な位置に変更。

スイッチが2つでも問題なく動作するのを確認。
現状だとプレイヤーがスイッチに乗っても反応するのでブロックだけにする場合は、ブロックにタグを追加。

スイッチのスクリプトを下記に変更
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Switch : MonoBehaviour
{
public GameObject onSwitch;
public GameObject offSwitch;
public GameObject GameManagerObj;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Block"))
{
onSwitch.SetActive(true);
offSwitch.SetActive(false);
GameManagerObj.GetComponent<GameManager>().SwitchCount();
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Block"))
{
onSwitch.SetActive(false);
offSwitch.SetActive(true);
GameManagerObj.GetComponent<GameManager>().SwitchCount();
}
}
}
これで一通りの仕組みはOK。
この後は、例えばStage2では別のスイッチを導入してブロックを乗せることでスイッチを押せるようにするみたいな感じで、ステージが先に進むほど少しづつ内容を変えていくという感じですね。

