2011年8月21日日曜日

Android でここまで3Dが作れる

Unityの公式アプリでAngry BotsっていうのがAndroid Marketで無料でアップされてますね。
床の微妙な光源の反射っぽい演出とかとても綺麗。
Androidスマートフォンでもここまで演出できるんだっていう良い見本ですね。

Android Market : Angry Bots Demo






2011年8月17日水曜日

UnityでAndroidアプリをビルドしてみた

UnityのiPhone向けサンプルのStarTrooperを少しだけいじって、Android向けにビルドしてみたもの。
OPyTestShooter.apk

いじったといっても、プレイヤーを飛行機から自作のドラゴンに変えてみただけです。

Unityでオブジェクトを破棄する方法

Unityを触ってちょっとずつ理解したこと11

ゲーム中に動的にオブジェクトを増減する方法(例:キャラクターがミサイルを発射するとミサイルが表示されて何かに当たると消える)

function OnCollisionEnter(collision : Collision) {

var contact : ContactPoint = collision.contacts[0];

var thisExplosion : GameObject = Instantiate (explosion, contact.point + (contact.normal * 5.0) , Quaternion.identity);

if (collision.gameObject.tag == "enemy")
{
Destroy (collision.gameObject);
}

Destroy (thisExplosion, 2.0);
Destroy (gameObject); }
function OnCollisionEnter(collision : Collision)はオブジェクトが何かと接触したと判定されたと気に呼び出されるメソッド。

var contact : ContactPoint = collision.contacts[0];は衝突した座標。

var thisExplosion : GameObject = Instantiate (explosion, contact.point + (contact.normal * 5.0) , Quaternion.identity);で衝突地点に爆発オブジェクトのクローンを生成。

Destroy (collision.gameObject);で衝突相手のオブジェクトを破棄。
Destroy (gameObject);でこのスクリプト呼び出しているミサイルオブジェクトを破棄。
Destroy (thisExplosion, 2.0);で爆発オブジェクトも2秒後に破棄。



Unityでオブジェクトを動的に生成する方法

Unityを触ってちょっとずつ理解したこと11

ゲーム中に動的にオブジェクトを増減する方法
(例:キャラクターがミサイルを発射するとミサイルが表示されて何かに当たると消える)

var missile : GameObject;
function Update () {
if (Input.GetMouseButtonDown (0))
{
var position : Vector3 = new Vector3(0, -0.2, 1) * 10.0;
position = transform.TransformPoint (position);
var thisMissile : GameObject = Instantiate (missile, position, transform.rotation) as GameObject;
Physics.IgnoreCollision(thisMissile.collider, collider);
}
}

var missile : GameObject;にクローンを生成したいミサイルを登録する登録方法は下図のようにミサイルプレハブをスクリプトの上にドラッグ&ドロップするだけ。

var position : Vector3 = new Vector3(0, -0.2, 1) * 10.0;
position = transform.TransformPoint (position);
はミサイルが発生する地点を設定している。TransformPointメソッドは引数で渡された座標をローカル座標からワールド座標に変換する。この例の場合では、ミサイルの発射元であるキャラクターを原点とした座標からO(0,0,0)を原点とした絶対座標に変換した座標の値を取得する。これは、これから生成されるミサイルオブジェクトはキャラクターの子オブジェクトではなく、ヒエラルキーのルート直下に置かれるため。

var thisMissile : GameObject = Instantiate (missile, position, transform.rotation) as GameObject;
Instantiateメソッドでミサイルオブジェクトのクローンを生成する。Instantiateメソッドの第一引数がクローンの元になるオブジェクト、第二引数が生成されたクローンが配置される座標、第三引数がクローンが生成された時に向いている向き。as GameObjectは不明。このキャストっぽい構文がJavaScriptのキャストの仕方?

Physics.IgnoreCollision(thisMissile.collider, collider);
Physics.IgnoreCollisionメソッドでミサイルとキャラクターが接触しても、ぶつかったと判定されないようにする。




Unityで入力を受け付ける処理の種類いくつか

Unityを触ってちょっとずつ理解したこと10

・Unityの入力処理の基本的な部分のまとめ(仮)

2,Unityの入力の種類いくつか
UnityのClassReference(http://unity3d.com/support/documentation/ScriptReference/20_class_hierarchy.html)みればわかることだけど、いくつかまとめておく。

// ジョイスティックの入力を受け取る場合
Input.GetAxis("Horizontal") : float
Input.GetAxis("Vertical") : float

// キーボード入力を受け取る場合(例 : スペースキー)
Input.GetKeyDown("space") : boolean
Input.GetKeyDown(KeyCode.Space) : boolean

// ボタン入力(押した時 & 離した時)
Input.GetButtonDown("Fire1") : boolean
Input.GetButtonUp("Fire1") : boolean代表的なものとして"Fire1", "Fire2", "Fire3", "Jump"があるが、キーボードの場合には左Ctrl、左Alt、左Cmd、スペースが対応しているとのこと。

// マウス入力
Input.GetMouseButtonDown (0)
0は左クリック、1は右クリック、2は中クリックになる。
また、Androidでスクリプトを実行したところ、任意の画面タッチでもInput.GetMouseButtonDown(0)は有効だった。

// スマートフォンのようなマルチタッチ入力
for (var event : Touch in Input.touches)
{
if (event.phase == TouchPhase.Moved)
{
// Do something
}
}

// 加速度センサー
var accelerator : Vector3 = Input.acceleration;
var x : float = accelerator.x;
var y : float = accelerator.y;
var z : float = accelerator.z;

Unityで入力を受け付ける基本的な処理方法(Androidと簡易比較)

Unityを触ってちょっとずつ理解したこと10

・Unityの入力処理の基本的な部分のまとめ

1,Unityの入力の受け取り方
普通のGUIプログラミングだと入力処理は単一のメソッド・関数から行う。例えば、Androidだとこんな感じ。
public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// do something for Player
// do something for NPC
break;
case MotionEvent.ACTION_UP:
// do something for Player
// do something for NPC
break;
case MotionEvent.ACTION_MOVE:
// do something for Player
// do something for NPC
break;
}

return true;}
Unityスクリプトの場合はスクリプトごとに入力処理を行う。例えばこんな感じ。
------------------ PlayerGunController.js ------------------

var bulletPrefab : GameObject;
function Update () {
// Playerが弾を発射する
if (Input.GetButtonDown("Fire1")) {
var bullet : GameObject =
Instantiate(bulletPrefab, transform.position, transform.rotation);
}

}
------------------ PlayerJumpController.js ------------------
function Update () {
// PlayerがJumpする
if (Input.GetButtonDown("Jump")) {
animation.Play("jump");
}

}

衝突判定処理(Collider)の種類

Unityを触ってちょっとずつ理解したこと9

大抵のゲームはオブジェクト同士がめり込み合わないように当たり判定の処理を行っている。 Unityでは、Colliderという仕組みを使って、オブジェクト同士の当たり判定処理を選択することができる。

Colliderの設定は簡単。プロジェクトビューかヒエラルキビューの当たり判定を行いたいオブジェクトを選択して、メニューのComponentからColliderを選択する。

Colliderの種類は以下の通り。
Box Collider ・・・ 箱状のCollider。処理が軽い。複数個組み合わせることで様々な形状のオブジェクトの当たり判定を行える。
Sphere Collider ・・・ 球体状のCollider。処理が軽い。しかし、様々な形状の対応させることは難しい。
Capsule Collider ・・・ カプセル状のCollider。
Mesh Collider ・・・ 設定対象になる3Dオブジェクトのポリゴンの形状に沿ったCollider。処理が非常に重くなりやすいので、できるだけ使用しないほうがいい。
Wheel Collider ・・・ ホイール状のCollider。複数のBox Colliderで代用できる気がする。

Mesh Colliderの処理は非常に重たくなりやすいので、可能な限り使用しないことが望ましい。ただし、下図のようにMesh Colliderの設定にあるConvexをチェックすると、3Dオブジェクトの凸部分だけをつなげるようにColliderの形状が設定されるので、比較的処理が軽めのMesh Colliderを設定することはできる。