nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

Unity 自分用まとめ

はじめに

  • 書籍「ゲームの作り方 Unityで覚える遊びのアルゴリズム」と、それについてくるコードを読みながら Unity の使い方やスクリプトの記法などを自分用にまとめ中。

ゲームの作り方  Unityで覚える遊びのアルゴリズム

ゲームの作り方 Unityで覚える遊びのアルゴリズム

オブジェクトをシーンビューの中央に表示する

  • シーンビューでオブジェクトを選択して F キー

Assets から割り当てられた GameObject を検索する

  • Assets にある Script Component などが、どの GameObject に割り当てて使われているかを参照する方法
  • Assets の Component などを右クリック > [Find References In Scene] で、Hierarkey に割り当てられた GameObject の一覧が表示される

MonoDevelopのショートカット

  • コードリーディングに便利なショートカット via http://yasuiyasuo.blogspot.jp/2012/12/monodevelop.html
  • cmd + y : 定義へジャンプ
  • cmd + shift + y : 参照先のリスト
  • cmd + f : 現在のファイル内検索
  • cmd + shift + f : 複数ファイル検索

列挙型の宣言と使用

// 列挙型の宣言
public enum STEP {
	NONE = -1,
	START,
	GOAL,
	GAME_OVER,
};
// 列挙型変数の初期化
public STEP	step = STEP.NONE;
// 列挙型をswitchで使う
switch(this.step) {
	case STEP.START:
	{
		/* some op */
	}
	break;
}

文字列型配列の初期化

public static string[] evaluation_str = {
	"okay",
	"good",
	"great",
	"miss",
};

構造体の

// 構造体宣言
public struct Result {

	public int		oni_defeat_num;			// 倒したオニの数(トータル).
	public int[]	eval_count;				// 各評価の回数.

	public int		rank;					// ゲーム全体を通しの、結果.
	
	public float	score;					// 現在のスコア
	public float	score_max;				// ゲーム内で取れる得点の最大
};
// 構造体用のプロパティ宣言
public Result result;
// プロパティの初期化
this.result.oni_defeat_num = 0;
this.result.eval_count = new int[(int)EVALUATION.NUM];
this.result.rank = 0;
this.result.score = 0;
this.result.score_max = 0;
for(int i = 0;i < this.result.eval_count.Length;i++) {
	this.result.eval_count[i] = 0;
}

GameObject を参照する

// GameObject 用のプロパティの宣言
public GameObject main_camera = null;
// GameObject をプロパティに代入
// "MainCamera" という Tag のついた GameObject を参照する場合
this.main_camera = GameObject.FindGameObjectWithTag("MainCamera");

同じ GameObject の Component を参照する

// Script Component 用のプロパティ
// "ScoreControl" は Script Component の名前
public ScoreControl score_control = null;
// Script Component をプロパティに代入
this.score_control = GetComponent<ScoreControl>();

他の GameObject の Component を参照する

// Script Component 用のプロパティを宣言
// "PlayerControl" は Script Component の名前
public PlayerControl player = null;
// Script Component をプロパティに代入
// "Player" という Tag のついた GameObject に、目的の Script Component が割り当てられている場合
this.player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerControl>();

Script Component を GameObject に割り当てずに使う

  • MonoBehaviour を継承したクラスでは使用できない
// Script Component 用のプロパティの宣言
public ResultControl result_control = null;
// Script Component の初期化と代入
this.result_control = new ResultControl();

配列の順次処理

public OniControl[]	onis;
foreach(OniControl oni in this.onis) {
	/* do something */
}

Prefab から GameObject の作成

GameObject go = Instantiate(this.OniEmitterPrefab) as GameObject;

GameObject の削除

Destroy(this.gameObject);

アニメーションの再生

// アニメーションコンポーネントの取得? / 子要素に Animation Component があるが、transform から取得するのがよくわからない
Animation animation = this.transform.GetComponentInChildren<Animation>();
// アニメーションの再生? / TODO: "P_attack_R" は Assets に入っていれば指定できる?
animation.CrossFade("P_attack_R", 0.2f);
// 前のアニメーション終わりで再生するものをキューに入れる?
animation.CrossFadeQueued("P_run");

Chapter1で左クリックから攻撃して敵を倒すまでの処理の流れ

  • PlayerControl(Script Component)のUpdateで左クリックを拾う
  • AttackColliderControl の衝突判定が有効になる
  • 攻撃用オブジェクトが敵と衝突していた場合、攻撃効果の再生や効果音の再生
  • OniGroupControl から SceneControl に倒した敵の数を引き渡す
  • GUIControl で SceneControl を参照して倒した敵の数を画面に表示

Chapter2のシーン中での処理ステップの制御

	// 処理ステップを列挙型で定義
	enum STEP {

		NONE = -1,

		WAIT = 0,		// クリックまち中.
		PLAY_JINGLE,	// スタート音再生中.

		NUM,
	};

	// 初期状態の定義
	// step が現在のステップ、next_step が次のステップ
	private STEP step      = STEP.WAIT;
	private STEP next_step = STEP.NONE;

	// 現在のステップの再生時間を定義
	private float step_timer = 0.0f;

	// Update でステップの進行判定と進行
	void Update () {
	
		// ---------------------------------------------------------------- //
		// 現在のステップでの経過時間を更新
		this.step_timer += Time.deltaTime;

		// ---------------------------------------------------------------- //
		// 状態遷移チェック.

		switch(this.step) {

			// 初期ステップ
			case STEP.WAIT:
			{
				// ボタン押下で次のステップへ
				if(Input.GetMouseButtonDown(0)) {

					// 次のステップの定義
					this.next_step = STEP.PLAY_JINGLE;
				}
			}
			break;

			// 開始時の効果音再生ステップ
			case STEP.PLAY_JINGLE:
			{

				// 現在のステップの経過時間を利用し、SE の再生が終わったら、ゲームシーンをロードして終了.
				if(this.step_timer > this.audio.clip.length + 0.5f) {

					Application.LoadLevel("GameScene0");
				}
			}
			break;
		}

		// ---------------------------------------------------------------- //
		// ステップの遷移時の初期化

		// 初期値が STEP.NONE なので、何らかの遷移が発生した場合
		if(this.next_step != STEP.NONE) {

			// 次のステップによって初期化処理を分岐
			switch(this.next_step) {

				// 効果音再生開始
				case STEP.PLAY_JINGLE:
				{
					this.audio.Play();
				}
				break;
			}

			// 次のステップを、現在のステップに
			this.step      = this.next_step;
			// 遷移が発生しない場合は NONE
			this.next_step = STEP.NONE;

			// 現在のステップの再生時間をリセット
			this.step_timer = 0.0f;
		}

		// ---------------------------------------------------------------- //
		// 実行処理.

		// ステップ毎の処理を記述
		switch(this.step) {

			// ボタン押下待ちをするだけなので何もしない
			case STEP.WAIT:
			{
			}
			break;
		}

	}