またーりUnity3D 入門 (少しでも参考文献日本語化計画)


unity3dのアニメーションについて


自身が勉強がてらに気まぐれにアップしていき、参考サイトも掲載していきます。

※注意書き
作成者は日曜なんちゃってプログラマーなので情報の真意は保障しません

●何ができるの?
視覚的に3Dゲームが作成できるようです。FLASHが3Dになった感じでしょうか

●何がすごいの?
MACでもWINDOWSでも製作でき、最終的なデータ書き出しの所にPSとかXBOXとかある(将来的に対応?なんでしょうか)
プラットフォームがマルチ。




オリジナル3Dモデルを読み込むには?

FBXという形式に変換する必要があります。変換ソフトに関しては以下にあります。

FBXコンバーター(無料 3ds.obj.dxfをfbxに)

LIGHTWAVE用FBXコンバーター (無料)

unity3dは3DSTUDIOMAXを標準にしているようです
キャラクターにモーションをつけた情報もそのFBXに含まれるようですので、キャラクターを動かすことを前提とすれば
モデリング&アニメーション作成ソフトは3dstudiomaxlightwave無料であればblenderあたりが選択肢になると思います・・・


■モーションについて
1キャラで複数のモーションを使う場合

Unity3d上で、1体のキャラで
複数のモーションを扱うには、
FBXファイルの命名規則を
「モデルネーム+@+アニメーションネーム」
に統一すれば良いらしい。

「player@wait.fbx」
「player@run.fbx」
「player@jump.fbx」

らしいです
モーションを作るごとにfbxで書き出すという作業が必要っぽいですね。

ということは3D作成ソフトで、
1.ボーンを入れて影響範囲の作成
2.歩くモーションを作る→「player@walk.fbx」で保存→攻撃モーションを作る→「player@attack.fbx」で保存のような作業が必要っぽいですね



■対応フォーマット一覧 詳しくは対応フォーマット一覧
3Dモデルとアニメーションとか

Maya .mb & .ma1
3D Studio Max .max1
Cheetah 3D .jas1
Cinema 4D .c4d1 2
Blender .blend1
Carrara1
Lightwave1
XSI 5.x1
SketchUp Pro1
Wings 3D1
3D Studio .3ds
Wavefront .obj
Drawing Interchange
Files .dxf
Autodesk FBX .fbx

2D画像
.psd,.tiff,JPEG, PNG, GIF, BMP, TGA, IFF, PICT

オブジェクトのインポートについて
オブジェクトの鏡面反射とかのパラメーターを0にしていると、インポートされたときに真っ黒の状態になっちゃうので注意が必要だ。
トゥーンアニメ的な効果を狙ってmetasequioaで無理やり自己発光を100%とかにしている場合は特に注意

赤丸のとこで明るさ変えられました

あとtoonっていう設定もあるのでそれにすればよさそうです


プログラミング

英語のスクリプトリファレンスはこちら
日本語訳のスクリプトリファレンス

■ 0章 オブジェクト(箱)の重力設定 youtube参考動画
Rigidbodyを使った簡単重力設定

■ 1章 オブジェクトの当たり判定(壁と地面) youtube参考動画

function OnCollisionEnter(){
Debug.Log("HIT!!");
}

■ 2章 キー入力の作成 youtube参考動画
スペースボタンを押したときにメッセージが出ます。

function Update(){

if(Input.GetButtonUp("Jump")){
Debug.Log("Hit The Space Bar!")
}

}

■ 3章 オブジェクトの複製(Prefab プレハブ は日本語で言う仮設住宅のようなものです) youtube参考動画

プレハブという空の枠を作り、その中にオブジェクトをドラッグすることで雛形ができます。
あとはその雛形を画面上にドラッグドロップするだけで複製が作れます。

■ 4章 オブジェクトの消滅 youtube参考動画

自オブジェクトの消滅(プログラム起動後すぐ) gameObjectは自分のことを指します
function Start () {
Destroy(gameObject);
}

対象オブジェクトCubeを3秒後に消滅
function Start () {
Destroy(gameObject.Find("Cube"),3);
}

■ 5章 
オブジェクトの複製

Instantiateはオブジェクトを複製します。Instantiateは非常に早く動作します。
全ての付与されたスクリプトや階層も含みます。
参照は次のように保持されます。複製された階層の外にあるオブジェクトへの参照は変更されません。複製された階層中のオブジェクトは複製され、参照が更新されます。


var thePrefab : GameObject;
function Start () {
var instance : GameObject = Instantiate(thePrefab,transform.position,transform.rotation);
}

■ 6章 タイマーの生成 (時間がたったらゲームオーバー)
var myTimer : float = 5.0;
function Update () {
myTimer -= Time.deltaTime;
if(myTimer <= 0){
Debug.Log("GAME OVER");
}
}

■ 7章 オブジェクトの座標移動
オブジェクトをプログラムで動かします

function Update () {
transform.Translate(Vector3(0,0,1));
}

■ 8章 重力設定(rigidbody)にプログラムで力を加える Force

var power : float = 500.0;
function Start () {
rigidbody.AddForce(Vector3(0,0,power));
}

■ 9章 テクスチャ設定の仕方

●4章のプログラミング部分



■イベントハンドラ 参考
イベントが起こったときに呼ばれる関数(マウスが動いたとか)



■コンポーネントと関数

クラスと関数と変数ページ

■transformとTransform

transformとTransformで頭文字の大小が異なることに注意してください。transformは変数で、Transformはクラスやスクリプトの名前です。大小文字の違いによって、変数とスクリプト/クラス名を区別できます。


・個人的解釈
tranceformというのは、雛形であるTransformクラスのコピーのtranceformクラスというものがデフォルトで作られていると想像する。

後にでてくる変数宣言、
var enemy : Transform;

は雛形のTransformクラスのコピーをenemyという名前のクラスで作っている作業

transform.positionで、現在のオブジェクト(ドラッグで追加したJavascript)
のpositionを知ることができる。

参考
ゲームオブジェクトの移動(Transform) または リジッドボディ(Rigidbody)によって行われます。これらはスクリプト内からアクセス可能なメンバ変数で transformとrigidbodyです。

属性には二つあります。
@値

A参照

■@値 (変数の数値をマウスで動的にいじくれる)メンバ変数
関数の外で変数を宣言すると、インスペクタウインドウに出てきて操作ができるようになります。
testという名前でjavascriptを作成し、以下のように記述。

var test = 0.0;

宣言した変数は必ず値を入れて初期化する

保存後、適当なオブジェクトにドラッグドロップ。


すると上記のように(右がインスペクタウインドウ)なります
マウスのドラッグで数値が増えたり減ったりします。

■A参照(マウスで対象を指定することができる)メンバ関数
まず、コンポーネント(Transform)雛形からコピーを作成する必要があるenemyという名前で作る。。
var enemy : Transform;

そしてjavascriptを記述し、設定したいオブジェクトにドラッグ。
すると、インスペクタウインドウにenemyが登場し、対象オブジェクトを選択することができる。

■当たり判定について。 こちらこちらこちらを参考
種類がいろいろあり、ちょっとややこしいですが

CollisionとColliderとTrigger。ここまでが一般の球とかボックスとか基本オブジェクト同士の衝突に使うあたり判定。


■キャラクターとオブジェクトの当たり判定 参考(キャラクターがオブジェクトを押し出すスクリプト有り)
外部から読み込んだキャラクターと一般オブジェクト(球とかボックスとか)などの当たり判定はCharacter Controller用
ControllerColliderHit
のってのがあります。

CollisionとColliderは一般のオブジェクト(箱とか球とか同士)の判定につかいます。
Triggerを使った判定は、対象物をすり抜けてしまう設定をしないと判定できません。
キャラクターと対象物の当たり判定にOnControllerHitを使います。
具体的には、例えばキャラクターとCube3という箱のあたり判定をとりたい場合

function OnControllerColliderHit (hit : ControllerColliderHit){
if(hit.collider.gameObject.name == "Cube3"){
Debug.Log("Hit!!");
}
}


このスクリプトを、自キャラに追加します。



■Collisionを使った特定の対象物との当たり判定
例えばFloorというオブジェクトとの判定なら

function OnCollisionEnter(theCollision : Collision){
if(theCollision.gameObject.name == "Floor"){
Debug.Log("Hit!!");
}

}


・Colliderを、Mesh Filter(=ポリゴンモデル)を持つGame Objectに追加すると、
 自動でモデルの形に合ったColliderを作成してくれる。

・OnColliderControllerHit(ControllerColliderHit hit)は、
 CharacterControllerがColliderと衝突したときに呼ばれる。

・OnTriggerEnter(Collider collisionInfo)は、
 ColliderがtriggerモードのColliderと衝突したときに呼ばれる。

・OnCollisionEnter(Collision collision)は、
 triggerモードでないCollider同士が衝突したときに呼ばれる。

■ThirdPersonControllerについて



■ダッシュについて
Trot After Secondsを0にするとダッシュしません
Trot Speedをあげるとダッシュ速度があがります

■ジャンプ中、空中制御について
ジャンプ中に方向キーで向きを変えたりできるかどうかのパラメーターは
In Air Control Accelerationです。
0ならば制御しないので、ジャンプ中はキャラクターを動かせません

・空中で戦うような場合
Gravityを0にして、In Air Control Accelerationを0より大きくすれば、無重力でキャラクターを動かすような感じになります(空中戦みたいな)

・地面で戦う場合
Gravityを0より大きくして、ジャンプ中にキャラを動かすのであれば In Air Control Acceleration は0より大きくします。

■読み込んだオリジナルのモデリングデータ(建物とか)に当たり判定をつける




今回は塔に当たり判定をつけます。

@塔を読み込みます。(読み込み方法については省略します。)

A読み込んだ塔を選択後、画面上部のコンポーネント(Component)→Physics→Mesh Colliderを選択

メッシュコライダーはおそらく形状に合わせて判定とってくれます。

想像ですが、きっと処理としてはポリゴン数が多いものは重くなりそう・・・


実際に動かすとこうなります。

http://mandokuse.info/unity3d/play/1/WebPlayer.html

塔を作るときに一緒に階段とかつけておくとちゃんと判定して登ってくれるかも


関数まとめ (function)

Update
Start
OnCollisionEnter
毎フレームごとに処理
プログラム開始直後に一回だけ処理
当たり判定。衝突が発生したときに呼ばれる

Destroy()
Debug.Log("")
Input.GetButtonUp("Jump")
Time.deltaTime
transform.Translate
対象オブジェクトを消す
デバッグウインドウに指定文字を表示
キー入力
時間関数
オブジェクトの移動

■整理されてない情報

RigidBodyのIsKinematicをONにすると、他のオブジェクトには物理的影響を与えるが、
 他のオブジェクトからは物理的影響をうけないオブジェクトになる。
RigidBodyのIntrpolateパラメータをONにすると、オブジェクトの動きを滑らかにする。

メンバ変数とかの参考

オブジェクトAとBの距離を取得する関数
Vector3.Distance

記述方法
Distance (a : Vector3, b : Vector3)

例1:
var other : Transform;
if (other) {
var dist = Vector3.Distance(other.position, transform.position);
print ("Distance to other: " + dist);
}

例2:
var enemy : Transform;

function Update() {
if ( Vector3.Distance( enemy.position, transform.position ) < 10 ) {
print("I sense the enemy is near!");
}
}

コンポーネント型を変数の型として指定すると(すなわち TransformRigidbodyCollider、その他のスクリプトなど)、ゲームオブジェクトをインスペクタの上にドラッグすることで設定できるようになります。

var enemy : Transform;

特定敵との距離を図りメッセージを出力するスクリプト
var enemy : Transform;
var kyori = 10;
function Update() {
if ( Vector3.Distance( enemy.position, transform.position ) < kyori ) { print("I sense the enemy is near!");
}
}

複数対応版

distance.js

キャラクターの移動にあわせてカメラを動かす。
chara_move_obj.js



Horizontal 水平、横方向という意味