こんにちは。システム部の長野です。
今回も前回に引き続きUnityネタで行きます。
今流行の鳥を飛ばして障害物を避けていく某人気ゲームのようなものを作ってみました。
(既に出尽くした感満載ですが、、)
※閲覧するにはUnity Web Playerのインストールが必要です。
ゲーム説明
・スタートを押すとボールが落下します。
・画面をクリックするとボールが少し浮きます。
・障害物にあたるか地面に落ちるとゲームオーバーです。
・障害物を避けると1点です。
スクリプト解説
今回書いたスクリプトは二つです。
progress.js・・・ゲームの進行等、あたり判定以外のすべての処理。progressオブジェクトに割当てています。
tama.js・・・・・あたり判定処理。playerオブジェクトに割当てています。
progress.js
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54  | 
						#pragma strict var player:GameObject; var barrierX:float; var barrier:GameObject; var score:GameObject; var scoreValue:int; static var playing:boolean = false; function Start() {   Application.targetFrameRate = 60; } function OnGUI(){    if(playing == false){       if(GUI.Button(Rect(140,240,50,20),"start")){          playing = true;          initGame();       }    } } function initGame() {   player.transform.position.y = 0.0;   player.transform.position.x = 0.0;   player.transform.rotation.z = 0.0;   player.rigidbody2D.WakeUp();   scoreValue = 0;   setDefaultBarrier(); } function Update() {   if(playing){     if(Input.GetMouseButtonDown(0)) {       player.rigidbody2D.AddForce(Vector2(0, 200));     }     barrierX -= 0.02;     if(barrierX < -3.0) {       scoreValue ++;       setDefaultBarrier();     }     barrier.transform.position.x = barrierX;   }else{     player.rigidbody2D.Sleep();     player.rigidbody2D.velocity = Vector2.zero;       player.rigidbody2D.angularVelocity = 0.0;      } } function setDefaultBarrier(){   barrierX = 1.3;   barrier.transform.position.y = Random.Range(-1.2, 2.0);   score.GetComponent('GUIText').guiText.text = "" + scoreValue; }  | 
					
tama.js
| 
					 1 2 3 4  | 
						#pragma strict function OnCollisionEnter2D(col : Collision2D){    progress.playing = false; }  | 
					
スタートボタン
| 
					 1 2 3 4 5 6 7 8  | 
						function OnGUI(){    if(playing == false){       if(GUI.Button(Rect(140,240,50,20),"start")){          playing = true;          initGame();       }    } }  | 
					
OnGUI()内でGUI.Button()を呼ぶとボタンが表示されます。
playingでプレイ中かを判断し、プレイ中は表示しないようにしています。
スタートボタンをクリックしたらゲーム初期化用のinitGame()を呼んでいます。
ゲーム初期処理
| 
					 1 2 3 4 5 6 7 8  | 
						function initGame() {   player.transform.position.y = 0.0;   player.transform.position.x = 0.0;   player.transform.rotation.z = 0.0;   player.rigidbody2D.WakeUp();   scoreValue = 0;   setDefaultBarrier(); }  | 
					
playerはインスペクタ側であらかじめ玉のオブジェクトに割り当てられています。
この玉のX、Y位置とz回転を0で初期化し、玉を初期位置に配置させています。
| 
					 1  | 
						  player.rigidbody2D.WakeUp();  | 
					
このrigidbody2D.WakeUp()で重力等の物理モードをオンにしています。
フレーム処理
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  | 
						function Update() {   if(playing){     if(Input.GetMouseButtonDown(0)) {       player.rigidbody2D.AddForce(Vector2(0, 200));     }     barrierX -= 0.02;     if(barrierX < -3.0) {       scoreValue ++;       setDefaultBarrier();     }     barrier.transform.position.x = barrierX;   }else{     player.rigidbody2D.Sleep();     player.rigidbody2D.velocity = Vector2.zero;       player.rigidbody2D.angularVelocity = 0.0;      } }  | 
					
ここではマウスクリック処理、フレーム毎の処理、ゲーム停止中の処理を書いています。
| 
					 1 2 3  | 
						    if(Input.GetMouseButtonDown(0)) {       player.rigidbody2D.AddForce(Vector2(0, 200));     }  | 
					
マウスをクリックしたとき、玉に対して上方向に200の力を加えています。
| 
					 1 2 3 4 5 6  | 
						    barrierX -= 0.02;     if(barrierX < -3.0) {       scoreValue ++;       setDefaultBarrier();     }     barrier.transform.position.x = barrierX;  | 
					
フレーム毎に障害物(barrier)を左に動かしています。
画面の左端まで行ったらスコアを加算させて、
| 
					 1 2 3 4 5  | 
						function setDefaultBarrier(){   barrierX = 1.3;   barrier.transform.position.y = Random.Range(-1.2, 2.0);   score.GetComponent('GUIText').guiText.text = "" + scoreValue; }  | 
					
で右端に戻しています。
そのときにY軸をランダムにすることで障害物の穴の位置を微妙に変化させています。
| 
					 1 2 3  | 
						    player.rigidbody2D.Sleep();     player.rigidbody2D.velocity = Vector2.zero;     player.rigidbody2D.angularVelocity = 0.0;     | 
					
障害物に当たったときにplayingがfalseになり、
その場合はスタートボタンの入力待ちになるため物理モードをオフにします。
あたり判定処理(tama.js)
| 
					 1 2 3 4  | 
						#pragma strict function OnCollisionEnter2D(col : Collision2D){    progress.playing = false; }  | 
					
OnCollisionEnter2D()で自身に別のオブジェクトが衝突したときを判定しています。
この関数を呼ぶだけで、障害物や地面に当たったときの判定が取れます。
この中ではprogress.jsのplayingをfalseにしています。
最後に
解説は以上になります。
重力周りや当たり判定が簡単に実装できるので
少ないスクリプトで面白いゲームが色々作れそうですね!
このブログを書いている時点でUnity5の予約も始まっており、
Unity5はWebGLに対応しているということなのでいつかこのブログで書きたいです。
サービス開発や社内インフラ等を担当しています。 このブログではJavaScript周りのネタを中心に書いていきたいです。
                
            


        
