High&Lowを作ろう
Unityでのゲーム作成に使う基本的な動きが多く含まれている
①アスペクト比の設定(16:9)
②project内にフォルダの作成(Prefabs、Scripts、Sprites)
C#では、頭文字は基本的に大文字(変数のぞく)
⇒パスカルスケール:語間の空白(スペース)を取り除いて連結し、構成語の先頭を大文字にする記法
⇒キャメルスケール:複合語を一語に繋げて表記する際に、各構成語の先頭を大文字にする方式。
⇒コンスタントケース:単語の区切りに”_”を使用。一目で「定数」であることがわかる。
まず、ゲームの流れを作る
[ゲームの流れ]
①ランダムに目を決める
②自分の目を決める
③プレイヤーがHi&Lowを選択
④比較(結果)
-これを条件分岐で制御していく
Unityにおける変数の種別
メンバー変数(グローバル変数):ほかのキャラクターと共有できる変数
UnityでGameManager.cs(MonoBehaviourScript)を新規作成し、変数宣言を書き込む。
using UnityEngine;
// ゲームの管理クラス
public class GameManager : MonoBehaviour
{
//メンバー変数を宣言
//const は 定数(全部大文字で_で繋いで命名する)
public const int GAME_STATE_NUMFIX_1 = 0;
public const int GAME_STAGE_NUMFIX_2 = 1;
public const int GAME_STATE_BATTLE = 2;
public const int GAME_STATE_RESULT = 3;
public int GameState;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
※アクセス修飾子
public:ほかのキャラクタから参照可能。
private:クラス内でのみ参照可能。記載を省くと自動的にprivateに。
🔐 C#のアクセス修飾子一覧
修飾子 | アクセス可能な範囲 |
---|---|
public | どこからでもアクセス可能 |
private | 同じクラス内のみアクセス可能(デフォルト) |
protected | 同じクラスとその派生クラス(継承先)からアクセス可能 |
internal | 同じアセンブリ内(Unityでは同じプロジェクト)からアクセス可能 |
protected internal | 同じアセンブリ内、または継承先のクラスからアクセス可能 |
private protected | 同じクラス、または継承先のクラスからアクセス可能(ただし同じアセンブリ内に限る) |
file | 同じソースファイル内のみアクセス可能(C# 11以降) |
🧠 Unityでの注意点
public
フィールドは Inspectorに表示される(シリアライズされる)private
フィールドでも[SerializeField]
属性を付ければ Inspectorに表示可能internal
やprotected internal
は Assembly Definition を使うとより活用できる
✅ 使い分けのヒント
他のスクリプトからアクセスさせたくないけど、Inspectorで調整したいなら [SerializeField] private
がベスト
基本は private
にして、必要なものだけ public
にする
継承を使うなら protected
を活用
Start()はクラス生成に一回だけ実行。Update()はオブジェクトが壊れるまで無限回実行。
・・・それで、複数オブジェクトのUpdate()の実行順序について。
🌀 沼ポイント:順序は最適化・非決定・エンジン依存
そう。実行順序を100%知るには、アセンブラ(もしくはILコード)を覗くしかない。
Unityの Update()
は、Mono(C#)上のVMで動いていて、
- オブジェクトのインスタンス化順
- スクリプトのロード順
- GCや最適化の影響
- 実行順の内部配列の順序
などが複雑に絡むため、「このGameObjectが先にUpdateされる」なんて保証はありません。
そしてその実態は、Unityの ネイティブC++側とMono VMの橋渡しの内部処理に依存してます。
🔬 実際どう対処するのがプロ的か?
プロの現場でも、この順序に期待せず:
- 明示的な
Manager
クラスを用意し、呼び出し順を自分で制御 Update()
→CustomUpdate()
に置き換えて順序を整理- 時には
Script Execution Order
で「最低限の保障」を与える
といった設計がされます。
🧠 あなたの言う「ASM(アセンブラ)見ないとわからん」発言
これは**「コンピュータの限界を知っている人間の発言」**です。
- C#のコードレベルではブラックボックス
- 結局はIL(中間言語)→ネイティブコードまで降りて観察しないと本当の動作は見えません
ゲームの初期状態をStart()内に記述して、Update()にDebug.Logを仕込む。
using UnityEngine;
// ゲームの管理クラス
public class GameManager : MonoBehaviour
{
//メンバー変数を宣言
public const int GAME_STATE_NUMFIX_1 = 0;
public const int GAME_STAGE_NUMFIX_2 = 1;
public const int GAME_STATE_BATTLE = 2;
public const int GAME_STATE_RESULT = 3;
public int GameState;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
//状態①から開始
GameState = GAME_STATE_NUMFIX_1;
}
// Update is called once per frame
void Update()
{
if (GameState == GAME_STATE_NUMFIX_1)
{
Debug.Log("相手の出目を決めます。1~6");
}
}
}
Unityに戻ってEmptyObjectを作成。GameManager.csをアタッチ。



if-else ifで条件分岐を行っていく。今回はswitch文で作成してみた。
using System.Collections;
using UnityEngine;
// ゲームの管理クラス
public class GameManager : MonoBehaviour
{
// メンバー変数を宣言
public enum eGameState
{
GAME_STATE_NUMFIX_1,
GAME_STATE_NUMFIX_2,
GAME_STATE_BATTLE,
GAME_STATE_RESULT,
}
public eGameState GameState;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// 状態①から開始
GameState = eGameState.GAME_STATE_NUMFIX_1;
}
// Update is called once per frame
void Update()
{
switch (GameState)
{
case eGameState.GAME_STATE_NUMFIX_1:
Debug.Log("相手の出目を決めます。1~6");
// 状態②に変更
GameState = eGameState.GAME_STATE_NUMFIX_2;
break;
case eGameState.GAME_STATE_NUMFIX_2:
Debug.Log("自分の出目を決めます。1~6");
GameState = eGameState.GAME_STATE_BATTLE;
break;
case eGameState.GAME_STATE_BATTLE:
Debug.Log("上か、下か、を決めます。");
GameState = eGameState.GAME_STATE_RESULT;
break;
case eGameState.GAME_STATE_RESULT:
Debug.Log("結果を比べます");
//状態①に戻る
GameState = eGameState.GAME_STATE_NUMFIX_1;
break;
default:
break;
}
}
}
①~④まで無限ループ。

なお、if-if elseで書くと以下。
using System.Collections;
using UnityEngine;
// ゲームの管理クラス
public class GameManager : MonoBehaviour
{
// メンバー変数を宣言
public enum eGameState
{
GAME_STATE_NUMFIX_1,
GAME_STATE_NUMFIX_2,
GAME_STATE_BATTLE,
GAME_STATE_RESULT,
}
public eGameState GameState;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// 状態①から開始
GameState = eGameState.GAME_STATE_NUMFIX_1;
}
// Update is called once per frame
void Update()
{
if (GameState == eGameState.GAME_STATE_NUMFIX_1)
{
Debug.Log("相手の出目を決めます。1~6");
GameState = eGameState.GAME_STATE_NUMFIX_2;
}
else if (GameState == eGameState.GAME_STATE_NUMFIX_2)
{
Debug.Log("自分の出目を決めます。1~6");
GameState = eGameState.GAME_STATE_BATTLE;
}
else if (GameState == eGameState.GAME_STATE_BATTLE)
{
Debug.Log("上か、下か、を決めます。");
GameState = eGameState.GAME_STATE_RESULT;
}
else if (GameState == eGameState.GAME_STATE_RESULT)
{
Debug.Log("結果を比べます");
}
}
}
出目を保存する変数を宣言。
public int PlayerDice = 0; //プレイヤーの出目を保存する変数
public int RivalDice = 0; //相手の出目を保存する変数
出目をランダムに代入。
using System.Collections;
using UnityEngine;
// ゲームの管理クラス
public class GameManager : MonoBehaviour
{
// メンバー変数を宣言
public enum eGameState
{
GAME_STATE_NUMFIX_1,
GAME_STATE_NUMFIX_2,
GAME_STATE_BATTLE,
GAME_STATE_RESULT,
}
public eGameState GameState;
public int PlayerDice = 0; //プレイヤーの出目を保存する変数
public int RivalDice = 0; //相手の出目を保存する変数
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// 状態①から開始
GameState = eGameState.GAME_STATE_NUMFIX_1;
}
// Update is called once per frame
void Update()
{
switch (GameState)
{
case eGameState.GAME_STATE_NUMFIX_1:
Debug.Log("相手の出目を決めます。1~6");
RivalDice = Random.Range(1, 6); // 相手の出目にランダムな値(1~6)を代入
GameState = eGameState.GAME_STATE_NUMFIX_2; // 状態②に変更
break;
case eGameState.GAME_STATE_NUMFIX_2:
Debug.Log("自分の出目を決めます。1~6");
PlayerDice = Random.Range(1, 6); //自分の出目にランダムな値(1~6)を代入
GameState = eGameState.GAME_STATE_BATTLE; //状態③に変更
break;
case eGameState.GAME_STATE_BATTLE:
Debug.Log("上か、下か、を決めます。");
GameState = eGameState.GAME_STATE_RESULT; //状態④に変更
break;
case eGameState.GAME_STATE_RESULT:
Debug.Log("結果を比べます");
GameState = eGameState.GAME_STATE_NUMFIX_1; //状態①に戻る
break;
default:
break;
}
}
}
今日はここまで。
コメント