夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【Unity】ボウリングの投球をタッチ操作でコントロールする

前回まではキーボードのキーを押している間ボールに力を加え加速させるというシンプルな作りになっていました。
そのため、左右のコントロールはできず、また実際のボウリングではあり得ない、転がった玉を加速させるという動きも可能になっていました。
今回はリアリティを増すため投球をフリック操作で行い、投球後の加速は不可能にしました。また、フリックの角度により玉を投げる方向をコントロールできます。

もう一つ重要なのがオブジェクトの「突き抜け」や「刺さり」の対策です。
RigidbodyのCollision DetectionパラメータをContinuous Dynamicにしていますが、それでも玉が速すぎると突き抜けてしまします。
なので、ある程度以上の速度にならないようボールに加えられる力に制限を与えます。

それでは動画をご覧下さい。

マウスカーソルを動かす方向に応じて玉の射出方向がコントロールされているのがわかると思います。

今回のスクリプトはこうなりました

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
	
	public float powerPerPixel; //  force per one pixel flick 
	public float maxPower; // force limiter
	public float sensitivity; // the higher, the more control to the right and left
	
	private Vector3 touchPos;
	private bool isRolling; //  true after throwing the ball
	
	void Start () {
		isRolling = false;
	}
	
	void Update () {
		if (!isRolling) {
			if (Input.GetMouseButtonDown(0)) {
				touchPos = Input.mousePosition; // remember the initial touch position
					
			} else if (Input.GetMouseButtonUp(0)) {
				isRolling = true; //stop detecting touches
				Vector3 releasePos = Input.mousePosition;
				float swipeDistanceY = releasePos.y - touchPos.y; // flicking distance in Y-axis
				float power = swipeDistanceY * powerPerPixel;
				float swipeDistanceX = releasePos.x - touchPos.x; // flicking distance in X-axis
				float throwDirection = swipeDistanceX * sensitivity;
				
				if (power < 0) {
					power *= -1; // invert the sign if the value is negative
				}
				if (power > maxPower) {
					power = maxPower; // apply force limiter
				}
				rigidbody.AddForce(new Vector3(throwDirection, 0, power), ForceMode.Impulse); // apply force to the ball
			}
		}
	}
} 

今のところ一回投球する毎にプログラムの再起動が必要なので、次回は倒れたピンを並べ、ボールを手元に返せるように改良する予定です。