More Related Content Similar to UnityとBlenderハンズオン第7章 (20) UnityとBlenderハンズオン第7章9. Unity:フォルダの基本ルール
フォルダ名 説明
Scenes ゲームのシーン(*.scn)を保存するフォルダ
Prefabs ゲーム内で繰り返し使用するObjectを保存するフォルダ
Scripts ゲーム内で使うスクリプト(.csや.js)を保存するフォルダ
Animations ゲーム内で使うアニメーションを保存するフォルダ
Materials ゲーム内のObjectに設定するマテリアルデータ(色とか光沢とか)を保存するフォルダ
Physics
Materials
ゲーム内の物理エンジンで使用するフィジカルマテリアルを保存するフォルダ
Fonts ゲーム内のフォントデータ(画像)を保存するフォル
Audio ゲーム内のBGMやSEなどのデータを保存するフォルダ
Resources ゲームプログラム内でなく、ゲームプログラムから別ファイルとしてデータをロードして扱うフォルダ
Editor Unityのエディタ機能を拡張するためのスクリプトを保存するフォルダ(ゲームを作成するだけなら不要)
Plugins
Unityで作成したゲームを、iPhoneやAndroidなどのプラットフォームで動作させるためのネイティブプラグインを
保存するフォルダ
12. Unity:Pixels Per Unitについて
Unityでは、1メートルを1Unitとしている。
Pixels Per Unitがデフォルトの100に設定されている場合、1メートルに100pxが入るように扱います。
例えば画像が48px × 48pxの場合、Pixels Per Unitが100なら、48cm × 48cmの大きさとなります。
Pixels Per Unitを48にすると画像は1m × 1mの大きさに変更されます。
※Pixels Per Unit を変更しても、画像の表示サイズが変わるだけで
transform.position.y = transform.position.y – 1 で下に1マス分移動するのは変わらない。
白い四角形が1マス分のスケール(1×1)のQuad Pixels Per Unit = 100→48に変更
14. Unity:CameraのSizeについて
要件定義 例
実際の解像度は 640×480 とします。
16×16 のスプライトを 320×240 の解像度に見立てたスクリーンに描画させます。
横 : 320px(画面サイズ) / 16px(スプライトサイズ) = 20個
縦 : 240px(画面サイズ) / 16px(スプライトサイズ) = 15個
16×16 のスプライトが横に 20 個、縦に 15 個描画できるようになる。
スプライトのPixels To Units は 「16」に設定しておく。
Size プロパティに縦にスプライトを敷き詰めたい個数を 2 で割った値 「7.5」を設定します。
すると、Unity では縦に 15 メートルの長さで描画してくれるようカメラを調整してくれます。
参考:Unity3D で画面の1ピクセルとテクスチャの1ピクセルを合わせる
15. Unity:GUI(テキスト)表示について
CanvasのRenderMode「Screen Space - Overlay」(デフォルト)
「Screen Space - Overlay」は、GUIが絶対に最前面にくる表示方法となります。
[GameObject]→[UI] →[Text]にてテキストを追加すると、右上に矩形の片鱗が見えるだけになります。
Sceneビュー上でマウスホイールにてかなり縮小すると、やっとテキスト文字が見える状態になります。
それでもGameビュー上では文字が一緒に表示されます。
この点が縮小
された表示内容
UI
Camera
UIとカメラを分けて
管理している。
24. Unity:プラットフォーム判別
Platform Dependent Compilation
コンパイル時にプラットフォームに応じてコードを分けることが出来ます。
ソースコード上に #If 等(ifディレクティブ)で分ける
#if UNITY_EDITOR
Debug.Log("Unity Editor");
#elif UNITY_IPHONE
Debug.Log("Unity iPhone");
#else
Debug.Log("Any other platform");
#endif
その他のプラットフォーム定義
プラットフォーム 条件文(一部)
Unityエディタ UNITY_EDITOR
Windows UNITY_STANDALONE_WIN
MacOS UNITY_STANDALONE_OSX
WebPlayer UNITY_WEBPLAYER
iPhone UNITY_IPHONE
Android UNITY_ANDROID
Unity 4.6 UNITY_4_6
25. Unity:プラットフォーム判別
Application.platform
実行時のプラットフォームを判別することが出来ます。
if (Application.platform == RuntimePlatform.IPhonePlayer) // iOS プレイヤー
その他のプレイヤー(RuntimePlatform)定義
プレイヤー プラットフォーム
iOS プレイヤー RuntimePlatform.IPhonePlayer
Android プレイヤー RuntimePlatform.Android
Windows プレイヤー RuntimePlatform.WindowsPlayer
Mac OS X プレイヤー RuntimePlatform.OSXPlayer
Windows 上の Web Player RuntimePlatform.WindowsWebPlayer
Mac OS X 上の Web Player RuntimePlatform.OSXWebPlayer
29. Unity:ゲームオブジェクトの取得
名前指定による取得(アクティブ時)
GameObject.Find()を使用する。
GameObject enemy = GameObject.Find("Enemy");
Debug.Log(enemy.name);
※複数ある場合、最初にヒットしたオブジェクトを取得
⼦要素を取得する。
GameObject tank = GameObject.Find("Tank");
Debug.Log(tank.name);
孫要素を取得する。※Tankを付けないと検索に時間がかかる
GameObject battery = GameObject.Find("Tank/Battery");
Debug.Log(battery.name);
※非アクティブ(非表示)の場合、GameObject.Findでは検索対象とならない。
チェックオン時は
表示かつ検索対象
30. Unity:ゲームオブジェクトの取得
名前指定による取得(非アクティブ時 or アクティブ時)
他GameObjectから下記のように取得しようとしてもnullになる。
GameObject enemy = transform.Find("Enemy").gameObject;
他GameObjectから取得するならスクリプトにpublic変数を用意し
Element[0] にEnemyのGameObjectをセットするなど予め取得しておく。
public GameObject[] element;
非アクティブ(非表示)の場合、 GameObject.Findでは検索対象とならない
その場合はTransform.Findとすることで取得できる。
・⼦要素の取得
GameObject tank = element[0].transform.Find("Tank").gameObject;
Debug.Log(tank.name);
・孫要素の取得
GameObject battery = element[0]. transform.Find("Tank/Battery").gameObject;
Debug.Log(battery.name);
チェックオフ時は
非表示かつ検索対象外
31. Unity:ゲームオブジェクトの取得
全ての⼦要素取得
GameObject enemy = GameObject.Find("Enemy");
SearchAll(enemy.transform); //再帰で全て取得する
private void SearchAll(Transform trans) {
foreach (Transform child in trans) {
Debug.Log(child.name);
SearchAll(child);
}
}
HelicopterとTankとBatteryが出力される。
32. Unity:ゲームオブジェクトの取得
⼦要素から親要素取得
GameObject battery = GameObject.Find("Battery");
GameObject parent = battery.transform.parent.gameObject;
Debug.Log(parent.name);
Tankが出力される。
孫要素(or ⼦要素)から最上位(Root)要素取得
GameObject battery = GameObject.Find("Battery");
GameObject root = battery.transform.root.gameObject;
Debug.Log(root.name);
Enemyが出力される。
37. Unity :ゲームオブジェクトの動的生成
特定のGameObjectの⼦要素にする
先に特定のGameObjectとして「Enemy」を作成しておく。
GameObject enemy = GameObject.Find("Enemy");
GameObject obj = (GameObject)Instantiate(element[0]);
obj.name = element[0].name;
obj.transform.SetParent(enemy.transform, false);
※親のGameObjectを取得して、親要素にセットする。
SetParent(parent: Transform, worldPositionStays: bool)の第二引数: worldPositionStays
親要素が X:-2、Y:1 で⼦要素が X:0、Y:0 の場合
true:ワールド座標系の位置情報を保持するため、⼦要素は親要素の位置を無視しX:0、Y:0に表示される。
false:親要素のローカル座標系に変換するため、⼦要素はX:(-2+0)、Y:(1+0)に表示される。
⼦要素に移動
38. Unity :ゲームオブジェクトの削除
オブジェクトの削除
Destroy(gameObject); //指定したGameObjectを削除することが出来ます。
自分自身を削除
Destroy(this); //コンポーネントが削除される(this=Destroyを呼び出したコンポーネント)
一定時間後に削除
Destroy(this, 5.0f); //第二引数にfloat型の秒数後にオブジェクトが削除されます。
全ての⼦オブジェクトを削除 (孫オブジェクトまで削除なら再帰させる)
foreach ( Transform child in gameobject.transform ) {
Destroy(child.gameObject);
}
39. Unity:コンポーネントの取得
GetComponent<コンポーネント名>()
GameObject heri = GameObject.Find("Helicopter");
Rigidbody2D rb = heri.GetComponent<Rigidbody2D>();
Debug.Log(rb.mass); //1が出力される。
コンポーネントが複数ある場合(例 Box Collider 2D)
BoxCollider2D[] colliders = heri.GetComponents<BoxCollider2D>();
foreach(BoxCollider2D bc in colliders) {
Debug.Log(string.Format("X:{0}, Y:{1}", bc.size.x , bc.size.y));
}
出力結果
X:1.12, Y:0.7637944
X:0.2860652, Y:0.3159404
40. Unity:コンポーネントの追加
先ほどのBoxCollider2Dを一旦削除して、動的に追加してみます。
gameObject.AddComponent<コンポーネント名>()
GameObject heri = GameObject.Find("Helicopter");
BoxCollider2D bc = heri.AddComponent<BoxCollider2D>();
Rect rt = new Rect(0f, -0.108f, 1.12f, 0.763f);
bc.center = new Vector2(rt.x, rt.y);
bc.size = new Vector2(rt.width, rt.height);
BoxCollider2D bc2 = heri.AddComponent<BoxCollider2D>();
Rect rt2 = new Rect(0f, 0.424f, 0.286f, 0.316f);
bc2.center = new Vector2(rt2.x, rt2.y);
bc2.size = new Vector2(rt2.width, rt2.height);
43. Unity:他スクリプトのアクセス(メソッド呼出)
SendMessage(“メソッド名”, 引数, SendMessageOptions)
※引数とSendMessageOptionsは省略可能
GameObjectに対して名前指定で処理を呼ぶ。引数を一つだけ持たせられる。
• 名前指定なので、ソースコードを変えずに呼び出し先を変えるのに使える。
但し、名前指定で渡すのでミスしててもコンパイルエラーにはならない。
• 返り値がもてない。
• SendMessageOptions.DontRequireReceiver を付けると、メソッド先が無くてもエラーにしない
• Privateなメソッドも実行出来る
【参照】
「宴」実装時に得られたUnityプログラムノウハウ
SendMessageに変わるExecuteEvents.Execute
44. Unity:他スクリプトのアクセス(メソッド呼出)
BroadcastMessage(“メソッド名”, 引数, SendMessageOptions)
GameObjectまたは全ての⼦GameObjectに対して名前指定で処理を呼ぶ。
引数を一つだけ持たせられる。
• オブジェクトのグループを作って、それらに対してまとめて実行させれる。
親要素のEnemyのBroadcastMessageでメソッドを呼ぶと
⼦要素のHelicopterやTankの同じメソッドが呼ばれる。
• 返り値がもてない。
• SendMessageOptions.DontRequireReceiver を付けると、メソッド先が無くてもエラーにしない
Invoke(“メソッド名”, 秒数)
GameObjectに対して指定した秒数後に名前指定で処理を呼ぶ。
• 引数を渡せない、返り値がもてない。
46. Unity:キー入力(複数の入力端末:方向)
入力と言ってもキーボード、ジョイスティック、ゲームパッドなど複数あるため、共通化されてます。
参照: 2.3 プレイヤーを動かす準備 Rigidbody2Dと組み合わせて操作する。
Input.GetAxisRaw (一定の間隔で移動する場合)
// 水平方向の入力量(-1、0、1) 、垂直方向の入力量(-1、0、1)
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Input.GetAxis (徐々に加速をしていく場合)
// 水平方向の入力量(-1~1)、垂直方向の入力量(-1~1)
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
対応するキーを押してもすぐには「-1」や「1」にはならず、徐々にその値に近づけるようになっている。
値 内容
0 左右どちらも入力されていない
-1 左が入力されている
1 右が入力されている
48. Unity:キー入力(複数の入力端末:ボタン)
ボタンが押されたかどうかを確認する(押している間は常に連射状態)
Input.GetButton( ボタン名の指定 );
例 Input.GetButton("Jump")
ボタンが押されたか瞬間を確認する
Input.GetButtonDown( ボタン名の指定 );
ボタンが離された瞬間を確認する
Input.GetButtonUp( ボタン名の指定 );
※ボタン名は大文字小文字を区別するので注意
不明な場合、[Edit]→ [ProjectSetting] →[Input]で内容を確認する。
ボタン名 内容
Jump スペースキー または
ジョイスティックのボタン3
Fire1 左Ctrl または 左クリック または
ジョイスティックのボタン0
Fire2 左Alt または 右クリック または
ジョイスティックのボタン1
Fire3 左Cmd または 中央クリック または
ジョイスティックのボタン2
51. Unity:タッチ入力とタッチ位置
タッチ数を検知
Input.touchCount
現在、同時にタッチされている数を返す。
タッチ情報の取得
Input.GetTouch(index) indexは、0~Input.touchCount-1
タッチした時の状態を扱う構造体を返す。(Touch構造体)
タッチ状態
Input.GetTouch(0).phase
タッチID(指:ポインター)
Input.GetTouch(0). fingerId
タッチ座標(スクリーン座標)
Input.GetTouch(0).position
タッチの状態 内容
TouchPhase.Began タッチした瞬間
TouchPhase.Moved タッチしたまま移動中
TouchPhase.Stationary タッチしているが移動していない
TouchPhase.Ended タッチから離れた
TouchPhase.Canceled タッチのトラッキングがキャンセル
1本指操作ならタッチ入力を使わなくても、
マウス入力(左ボタン)で対応可能
タッチパネルPCでも、Input.touchCountは
「0」を返す