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を設定することはできる。







Unityのスクリプトの基本

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

Unityで何をするにしてもScriptが必要なわけだけれども、その基本形は以下の5つの関数から成り立っている。

初期化系
Awake()
Start()

アップデート系
Update()
FixedUpdate()
LateUpdate()

Awake()とStart()の違い
Awake()はゲーム開始前に呼ばれるので、ゲームの状態や値を初期化するために使った方がよい。どのオブジェクトのAwake()から順番に呼ばれるかはランダムだが、どのオブジェクトのStart()よりも前に呼び出される。従って、Awake()から他のオブジェクトの状態を参照するような処理はしない方がよい。そうした処理はStart()に任せるべき。

LateUpdate()の特徴
全てのオブジェクトのUpdate()が呼び出された後に呼び出される。LateUpdate()は例えば、追跡カメラの処理と相性が良い。Update()で全てのオブジェクトの移動処理が終わった後で、追跡カメラの座標を決められるから。

Update()とFixedUpdate()の違い
Update()は毎フレーム呼び出されるが、FixedUpdate()は指定されたフレーム毎に呼び出される。この特性から、FixedUpdate()は特にRigidbody(剛体)に対する処理、新しく力を加えるなど、に向いている。(毎フレーム処理をするのにはRigidbodyが向いていないから?)

スマートフォン(iPhone)向けUnityサンプルだけどAndroidでも可?

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

Unityの公式ページにはいくつもののサンプルプロジェクトがあって、その中にはiPhone向けのプロジェクトファイルがあるが、これはAndroid向けにもBuild可能だった。少なくとも、StarTrooperは。
http://unity3d.com/support/resources/example-projects/iphone-examples

StarTrooperは加速度センサーで飛行機を傾けることができて、画面をタッチするとミサイルを発射するようになっている。

Scriptを見てみると、Input.accelerationというVector3型のオブジェクトにアクセスすることで、傾きによる変更が必要なScriptでこの値を参照すれば、Androidでも傾きによるキャラクター操作が可能になる。
また、Input.GetMouseButtonDown(0)で画面がタッチされたかどうかを確かめることができた。

下の画像はサンプルの飛行機の小要素として自分で適当に作ったキャラクターの3Dオブジェクトを配置してみた図。理由はわからないけれども、今回は.blendファイルをAssetsファイル下に置くだけで、直接Unityが.blendファイルがプレハブ化してくれた。どうも、その辺は不安定らしい。




Blenderで作成したデータをUnityにインポートする

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

BlenderのモデルをUnityにインポートする ・・・

Unityは無料の3DCGソフトBlenderからも3Dデータをインポートすることができます。

最初の方法が、.blendファイルをUnityプロジェクト内部のAssetsフォルダに配置する方法。Assetsフォルダに配置した入るはプロジェクトビューに表示されるので、.blendファイルを選択すると、FBXインポーターがインスペクタビューに表示されるので、FBXに.blendファイルを変換することで、Unityで表示することが可能になる。
ただし、このインポートは制限が多いので、うまくインポートしにくい。

次の方法が、Blenderで先にFBXファイルをエクスポートしてから、FBXファイルをAssetsフォルダに配置する方法。こっちの方法の方がきちんとデータがインポートしやすいので、推奨らしい。










Unityのビルド方法 & Android向けビルドの方法

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

Unityでゲームをビルドする基本 ・・・
これもドラッグ&ドロップで行ける。「Scenes In Build」の中にビルドを行いたいシーンをドラッグ&ドロップして追加するだけ、後は生成したアプリケーションを動かしたいプラットフォームを選択して、Buildボタンを押すだけ。

Android向けにビルドする場合 ・・・
いくつかの設定が必要なので、Player Settingsボタンを押して、インスペクタビューでAndroid用の設定を編集します。まず必要なのが、アイコン画像の選択とパッケージ名の指定です。
他にもAPIレベルの指定や使用するOpenGLのバージョンの指定、キーストアファイルの作成なんかもできます。





Unityのプロジェクトの基本的な構造

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

ぱっと見だとちょっとわかりにくい気がするUnityのゲーム作りの流れ ・・・

最初にUnityのプロジェクトを作成しても、いまいちそこからどうゲーム作りにつながっていくのか、わかりにくかったのでUnityプロジェクトのごくごく基本的な構造はこんな感じ。(理解に誤謬があったとしても当方は一切関知いたしません悪しからず(^^;・・・)

1, Unityプロジェクトはシーンの集合 ・・・ ゲームにはメニュー画面、ゲーム画面と様々な画面があるけれども、Unityではそれらはシーンという1つの単位で扱われる。これまでに挙げたUnityの編集画面もすべてシーンの編集を行っている画面ということになる。

2, シーンの中身は階層構造 ・・・シーンの中は階層構造になっている。 構造は千差万別だけれども、基本的にはこんな感じ(?)で。なので、これまでに挙げた画像のヒエラルキビューは現在編集中のシーンの階層構造ということになる。

3, シーンとシーンをつなぐ ・・・ シーン(メニュー画面)とシーン(ゲーム画面)がそれぞれ独立していては、まったくゲームにならないので、スクリプトを使って、シーンとシーンをつなげます。基本的なパターンとしては、特定のボタンが押されたときに、Application.LoadLevel("シーン名");を呼んで、新しいシーンをロードします







プレハブの作り方

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

プレハブの作り方 ・・・
プロジェクトビューで右クリック、Prefabと選択すると、空のプレハブが作られる。
ヒエラルキビューで編集したオブジェクトを空のプレハブに向かって、ドラッグ&ドロップ。
プレハブの作り方はこれでOK





Unityのプレハブとは

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

プレハブ(Prefab)ってなんぞ? ・・・
Unityを触るとすぐさま出てくる単語の一つプレハブ。プレハブっていうと掘っ立て小屋のことしかイメージにないけど、それはだいたい正しい、、、かも。

3Dでキャラクターを動かすためには数多くのデータが必要になる。3Dの座標データ、3Dキャラクターを動かすための骨データ、3Dキャラクターの表面に張りつけるテクスチャ画像、3Dキャラクターを制御するスクリプトなどなど。プレハブはそれらを一まとめにしたもの。

例えば、3Dクリボーを作ろうと思ったら、3Dクリボーの座標データ、3Dクリボーの骨・アニメーションデータ、3Dクリボーのスクリプトなどが必要になるので、それらを1箇所にまとめて3Dクリボープレハブとして扱うことができる。

作ったプレハブはSceneビューやヒエラルキビューにドラッグ&ドロップして実際に配置することができる。プレハブ内部の属性をインスペクタビューで編集すると、編集した影響は配置したすべてのオブジェクトに及ぶので、ひとつひとつ編集する手間を省くことができる。

逆に、実際に配置したオブジェクト内部の属性を編集すると、プレハブとのリンクが外れて、今後プレハブの編集の影響が及ばなくなるので注意。(配置したオブジェクトを編集しようとすると、プレハブとのリンクが切れますよってダイアログが出てくる)




2011年8月16日火曜日

Unityの画面の基本的な見方

UnityのAndroidライセンスを購入したので、Unityの使い方をまとめておく意味もこめて、Unityの使い方を記録しておこうと思います。先にGoogle+に書き込んで、ある程度溜まったら、ブログに書き写しています。

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

1, Sceneビュー ・・・ 3Dオブジェクトを実際に配置する画面

2, ヒエラルキビュー ・・・ Sceneビューに配置されているものは目に見えるもの、見えないもの含めて階層構造になっているので、その階層構造を表示する画面(例えば、プレイヤーキャラクターオブジェクトがあったら、その下の階層にプレイヤーの手、足、胴体、頭がそれぞれ別に配置されてたりする感じ)

3, プロジェクトビュー ・・・ 3Dゲームには必要なデータが色々とある。例えば、カメラだったり、光源データだったり、3Dオブジェクトのデータだったり、画像データだったり、スクリプトだったりする。そういったたくさんの小道具を一箇所にまとめて表示するビュー。ここから必要な道具を選んで、ヒエラルキビューやSceneビューにドラッグ&ドロップするだけで、ゲームの中に配置することができる。このプロジェクトビューのフォルダ構成は実際のプロジェクトフォルダ内のAssetsフォルダの構成と同じ。

4, インスペクタビュー ・・・ それぞれの小道具は様々な属性を持っている。例えば、3Dオブジェクトが配置されている座標だったり、スクリプトのグローバル変数の値だったり、光の色だったりする。そうした属性の値はこのインスペクタビューで編集することができる。このビューの操作もドラッグ&ドロップでできる場合が多い。例えば、画像を登録したい場合にプロジェクトビューから画像をドラッグして、登録したいところでドロップするとそれだけで、画像を登録することができる。

5, Gameビュー ・・・ Sceneビューを似ているけれども、Sceneビューが編集用の3D画面なのに対して、こちらはヒエラルキビューに追加したカメラからの目線が表示される。画面上にあるプレイボタンを押すと実際にゲームがスタートして、このGameビューでゲームを試しプレイすることができる。