【Unity2D】順番に踏むと扉が開く床スイッチの作り方
だいぶ仕掛けの根本ができてきましたね。
あと1週間もないのでこれはかなり厳しいです……
もう2つほど仕掛けを作ったらあとは組み合わせで一気に仕上げましょう。
床スイッチを配置
ドット絵は各自よろしくお願いします。
オブジェクトのサイズは16x16のままですが、判定のサイズは8x8ぐらいにしておけば
スイッチを踏んだ感じが演出できるのではないでしょうか。
通常サイズだと端っこに触れただけで踏んだことになりますので、
少しユーザビリティが低下してしまう気がします。
こういう細かいところをしっかりしていないと見た目との乖離が生じてクソゲーになってしまいます。
まずは1個踏んだら開く扉を作ります。
プレハブ化しないと面倒なので仕組み作りをしてからスイッチ数を増やしましょう。
本来はステージごとに管理したいのですが、一旦スイッチ専用のスクリプトを組みます。
モンスターせん滅の応用で親スクリプトでスイッチ全体を管理しましょう。
State_SwitchFloorManageというファイルを作ってください。
using System.Collections;
using UnityEngine;
public class State_SwitchFloorManage : MonoBehaviour
{
// フロア内スイッチ数カウント保持
protected uint _switchCount = 0;
public uint SwitchCount
{
get { return _switchCount; }
protected set { _switchCount = value; }
}
// プレイヤーステータス確保用変数
protected State_Player _State;
// 踏む順番の番号照らし合わせ用変数
protected int _flowSwitchNo = 0;
public int FlowSwitchNo
{
get { return _flowSwitchNo; }
}
// Start is called before the first frame update
protected virtual void Start()
{
// 初回時にカウントしておく
checkAreaSwitches();
// プレイヤーステータスを取得
_State = GameObject.FindGameObjectsWithTag("State_Manager")[0].GetComponent<State_Player>();
}
// Update is called once per frame
protected virtual void Update()
{
}
// フロア内スイッチをカウント
private uint _checkAreaSwitches()
{
foreach (Transform child in transform)
{
SwitchCount += 1;
}
return SwitchCount;
}
}
ほとんどモンスター管理のスクリプトと同じですね。
こういったステート管理スクリプトは親を作って継承させたほうがよさそうです。
同じ処理を書いてしまうのはよろしくないですからね。
ちょっと使ってみたかったのでint型じゃなくてマイナスがないuint型を使ってみました。
マイナスがあり得ない変数の場合はuintのほうが適切です。
とりあえず時間がないので一旦これでいきます。
重要なのが「踏む順番の番号照らし合わせ用変数」ですね。
子スイッチを踏んだ時に親にスイッチが自分自身の番号を親に伝え、
次踏む番号と合致するかどうかを調べて正解であれば次の番号に進むといった感じにします。
間違っていたら押す順番のリセットをかけます。
これで順番に踏むスイッチは作れそうです。
子スイッチは判定と通知のみ
子は親とだけ繋がればいいですね。
子にプレイヤーが乗ったら親に自身の保持番号を通知するだけです。
あとは親側で処理すればいいのでかなりシンプルな作りになります。
なので親を引き継がずにコリジョンスクリプトとして独立させます。
using System.Collections;
using UnityEngine;
public class _SwitchFloor_Collision : MonoBehaviour
{
// 自身の保持ナンバー
[SerializeField]
private uint myNumber = 0;
// 親に通知のため
private State_SwitchFloorManage _SwitchManager;
// Start is called before the first frame update
private void Start()
{
// 親オブジェクトのスクリプトを取得
_SwitchManager = transform.parent.gameObject.GetComponent<State_SwitchFloorManage>();
}
// 衝突判定
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
// 接触してきたのがプレイヤーだった場合、親に自分自身のマイナンバーを通知する
_SwitchManager.sendMyNumber(myNumber);
}
}
}
とてもシンプルですね。
SwitchManagerでsendMyNumber関数を作りましょう。
// 子からマイナンバーを送ってもらうための関数
public void sendMyNumber(uint myNumber)
{
// 次に踏むナンバーとマイナンバーが同じであれば
if (myNumber == _flowSwitchNo)
{
// 次に踏むナンバーをインクリメントする
_flowSwitchNo++;
}
else
{
// 間違っていた場合はリセットする
_flowSwitchNo = 0;
}
}
次に踏む数値と同じであれば次の数値にインクリメント。
そうでなければ踏む順番のリセットですね。
現時点ではSEが無いのですごくわかりづらいですが、
体験版までには正解と間違いのSEは必ずつけないとヒントなしの謎解きになるので注意です。
正解の順番で踏んだら扉を開く
次に_flowSwitchNoと_switchCountが同じ数になったら正解の順番で踏まれたことになるので、
仕掛けを作動して扉を開くようにします。
とりあえず1個踏んだら開くようにしてそこからプレハブ化して数を増やしてみましょう。
空オブジェクトをSwitchManagerにしてその中にSwitchFloorオブジェクトを配置します。
SwitchManagerに「State_SwitchFloorManage」をアタッチ。
SwitchFloorに「_SwitchFloor_Collision」をアタッチしてください。
次に正解の数値になったら、設定している扉を開くようにしてみます。
条件を満たしたら一旦座標を変更するだけでOKです。
// 子からマイナンバーを送ってもらうための関数
public void sendMyNumber(uint myNumber)
{
// 次に踏むナンバーとマイナンバーが同じであれば
if (myNumber == _flowSwitchNo)
{
// 次に踏むナンバーをインクリメントする
_flowSwitchNo++;
}
else
{
// 間違っていた場合はリセットする
_flowSwitchNo = 0;
}
// 正解チェック
_checkSuccess();
}
// 正解チェック
private void _checkSuccess()
{
if (_flowSwitchNo == SwitchCount)
{
_SwitchDoor.transform.localPosition = Vector3.zero;
}
}
正解チェックの関数を作ってボタンを踏まれたときの最後にチェックをしましょう。
正解だったら保持している扉オブジェクトの位置を変更します。
これでボタンを踏んだら扉が開くようになりました。
あとは数を増やして踏む順番を決めてやりましょう。
本来であれば重複したボタンが無いかを調べる仕組みも作ったほうが
制作者のミスもなくなりますが、今はまぁいいでしょう。
ヨシッ!👈🐱 pic.twitter.com/XkwBmucQkH
— なおキーヌ@ゲームクリエイターLv5 (@naokeyzmt) January 13, 2020
次回は1つ前の部屋に戻ってモンスターのせん滅後に宝箱が出現するようにして、
南の扉を開くようにしてみます。
前回これやるの忘れてましたね。
それでは!