第2回Unity講座 コンパイラ班 3年 山崎 弘靖 1 今日やること 3D関連&その他諸々 1. 座標について 2. RigidBodyとColliderについて 3. スクリプトで物体を操る 4. Prefabの使用 2 1. 座標について Unityにかかわらず、CGの分野では直交座標系を用いることが多いです。 Unityでは左手座標系で表されています。 DirectXも左手座標系を用いています。 OpenGLは右手座標系を用いています。 開発環境によって異なるので注意してください。 3 CGの世界では、位置関係を表すためにワールド座標系(グローバル座標系、 絶対座標系)とローカル座標系(相対座標系)がよく用いられています。 ワールド座標:3次元空間そのものを表す座標 →決して変わることのない座標 ローカル座標:3D空間に配置されている、あるオブジェクトを基準とした座標 →基準にするオブジェクトにより座標が変わる 4 例 (2次元) 点Aのワールド座標 : (1,1) 点Bのワールド座標 : (2,3) 点Bを基準とした点Aのローカル座標 : (-1,-2) 点Oを基準とした点Aのローカル座標 : (1,1) 点Aを基準とした点Bのローカル座標 : (1, 2) 点Oを基準とした点Bのローカル座標 : (2,3) 5 Unityで確認 図のようなCubeを2つ配置します。 この時、Cubeの座標は全てワールド座標系 で表されています。 Transformコンポーネントに表示されている値は ワールド座標系の値となります。 6 UnityではGameObjectを階層関係(親子関係)にすることができます。 Cube2をCube1の子にします。 HierarchyビューのCube2をCube1へドラッグ&ドロップしてください。 図のようになればCube2はCube1の子となります。 → 7 ここでCube 2の座標を確認してください。 先ほどの座標の値と変わっています。 この値はCube1を基準としたCube2の座標の値(ローカル座標系)になっています。 Unityでは、GameObjectを親子関係にした時、親はワールド座標系、 子は親を基準としたローカル座標となります。 8 2. RigidBodyとColliderについて UnityにはRigidBodyというコンポーネントが用意されています。 GameObjectにRigidBodyコンポーネントを付けることで重力や加速度を使った 処理をできるようになります。 またGameObject同士の衝突判定を用いる時に必要です。 RigidBodyコンポーネントの付け方は、付けたいGameObjectを 選択し、AddComponent→Physics→RigidBodyと選びます。 まずCube1にRigidBodyコンポーネントを付けてみましょう。 9 Mass:オブジェクトの質量 Drag:力により動く際のオブジェクトに影響する 空気抵抗の量 Angular Drag:回転する際のオブジェクトに 影響する空気抵抗の量 Use Gravity:重力による影響を受けるかどうか Is Kinematic:物理エンジンによる影響をなくす。 Interpolate:RigidBodyの動きがおかしい時に使うオプション Collision Detection:高速で動くオブジェクトのすり抜け防止のオプション Constraints:RigidBodyの動きに制限をかける 10 Cube1はRigidBodyコンポーネントをつけたことにより重力の影響をうけます。 プレイボタンを押してどのような効果が得られるのか確かめてみましょう。 Cube1が下に落ちると思います。 このようにRigidBodyを付けることで重力による影響を受けることができます。 11 Cube1はRigidBodyコンポーネントによって重力による影響を受けます。 しかし、床との衝突判定をとっているのは別のコンポーネントが処理をしています。 Cube1のInspectorを見るとBox Colliderというものがあると思います。 Unityで衝突判定を処理させたい場合はColliderというコンポーネントが必要に なります。緑色の線がColliderの大きさです。 12 衝突判定をとる場合、衝突する互いのオブジェクトにColliderがついていなければ なりません。 ※Planeにも「Mesh Collider」というコンポーネントがついています。 Edit Colliderでエディタ上で直接Colliderを編集 することができます。 Is Triggerは衝突判定は取りたいけど、 物理エンジンの影響を受けさせたくない場合に チェックを入れます。 CenterはColliderの中心座標(ローカル座標) SizeはColliderのサイズ 13 Colliderにはいくつか種類があり、名前が異なるCollider同士でも互いに衝突判定 をとります。 ただ、Mesh ColliderのConvexにチェックを入れた場合は少し処理が異なります。 Mesh ColliderのConvexにチェックを入れた場合、そのMesh Colliderは 他のMesh Colliderとしか衝突判定をとらなくなります。 Mesh ColliderはポリゴンによってColliderを自動生成するため、複雑な形の オブジェクトによく使われます。 14 3. スクリプトで物体を操る UnityエディタでC#スクリプトを作成した場合、全てのクラスはMonoBehaviorクラスを継承して 作られています。 処理は基本的にはStartメソッドから開始します。StartメソッドはUpdateメソッドが呼ばれる 直前の1回しか呼ばれません。基本的には各パラメータの初期化を行います。 void Start ( ) { 各パラメータの初期化などを行う。 } 15 Startメソッドの処理が終わったらUpdateメソッドの処理を行います。 Updateメソッド内には1フレーム毎の処理を記述します。 例えば60FPSで固定した場合、1秒間に60回Update関数は呼ばれます。 void Update ( ) { ここに1フレーム分の処理を書く } ※他にもAwake()やOnGUI()などがあります。 16 MonoBehaviourクラスのメンバ変数 transform :Transformコンポーネントにアクセス gameObject:スクリプトが追加されているゲームオブジェクトそのものにアクセス collider:Colliderコンポーネントにアクセス rigidbody:RigidBodyコンポーネントにアクセス ※transformとgameObjectはよく使うので覚えといてください。 17 実際に書いてみましょう! クラス名「Object_Controller」で以下のスクリプトを書いてください。 using UnityEngine; using System.Collections; public class Object_Controller : MonoBehaviour { public Vector3 angle; void Update () { transform.Rotate(angle * Time.deltaTime); } } 18 書けたら、前につくったCubeに貼り付けてみましょう。 Object_Controllerコンポーネントが追加されていれば大丈夫です。 「Object_Controller」では、Vector3 angleの頭にpublicを付けています。 publicはどこからでもアクセス可能な変数にするためのものだと考えてください。 Unityでは、public を頭に付けたメンバ変数は、図のようにエディタ上で編集する ことができます。 19 ※ベクトルを表す時は、Vector型を使用します。 Vector型には、2次元のベクトルを表すVector2 , 3次元のベクトルを表す Vector3という型が存在します。 Vectorは型なのでインスタンスを生成する時は以下のようにします。 例 Vector3 vect = new Vector3 ( ) ; vect.x = 1; 20 試しに x = 30としてみます。 この状態で実行すると、x軸を中心に回転し始めます。 ※RigidbodyコンポーネントのUse Gravityのチェックは外しといてください transform.Rotateでゲームオブジェクトを相対的に回転させることができます。 同様に移動も簡単に実装できます。transform.Rotate~の1文を消して、次の文を Updateメソッド内に記述してください transform.Translate(new Vector3(0, 1, 0) * Time.deltaTime); 21 実行すると、Cubeが正のY軸方向にどんどん移動していきます。 移動はtransform.Translate(ベクトル)で移動させることができます。 transform.Rotateとtransform.Translateは オブジェクトを簡単に回転、移動させる 関数なので、覚えておくと便利です。 (他にもたくさんやり方があります) 22 次は入力した方向にGameObjectを移動させてみましょう。 キーボードの入力に対して、float型の値を返すメソッドを紹介します。 Input.GetAxis (“Horizontal”) :左右キーを押した場合、-1.0f~1.0fの値を返す Input.GetAxis(“Vertical”) : 上下キーを押した場合、-1.0f~1.0fの値を返す また、特定のキーを押したときにbool型の値を返すメソッドもあります Input.GetKey(“a”) : aを押し続けているときtrueを返し、それ以外はfalseを返す 23 クラス名「Object_Move」で以下のスクリプトを書いてください。 using UnityEngine; using System.Collections; public class Object_Move : MonoBehaviour { public float speed = 5.0f; public float rotate_speed = 100.0f; void Update () { float ud = Input.GetAxis ("Vertical") * speed; float lr = Input.GetAxis ("Horizontal") * rotate_speed; transform.Translate (0, 0, ud * Time.deltaTime); transform.Rotate (0, lr * Time.deltaTime, 0); } } 24 「Object_Move」クラスをさっきと同じCubeに貼り付けてください。 (Object_Controllerコンポーネントは外しておいてください 右クリック→Remove Componentで外せます) speedは移動の速度、Rotate_speedは回転の速度を表しています。 25 実行すると、Cubeが動くようになります。上下キーで前や後ろに進み、左右キーで 回転します。 26 せっかく動くようになったので、もう少しゲームっぽくします。 Main CameraをCubeに追従するようにしたいと思います。 まず、CubeのTransformコンポーネントを図のようにしてください。 次にPlaneのTransformコンポーネントを図のようにしてください。 27 次にカメラのTransformコンポーネントを次のようにしてください。 Transformコンポーネントを調整したら、Main CameraをCubeの子にします。 28 この状態で実行してみてください。 カメラがCubeの後を追いかけて移動していると思います。 子のオブジェクトの座標は、親オブジェクトの座標を基準としたローカル座標と なっているので、親オブジェクトが移動しても、ローカル座標は変わらないので 親オブジェクトに追従するようになります。 29 GameObjectの親子関係を用いることで様々な応用ができるので いろいろ調べて試してみてください! 例: カメラの座標を変えてFPS視点にする 移動+眺め回すようにする ネットに様々なやり方が載っているので暇な時にでも試してみてください。 30 4. Prefabについて Prefabは再利用可能なGame Objectのことです。 このPrefabをScene上に追加すると、そのPrefabのインスタンスが生成されます。 Prefabを変更するとそのインスタンスも全て変更されます。 このプレファブをスクリプトからScene上にCubeを生成したいと思います。 31 まずPrefabを作成します。 ProjectsビューのAssets上で右クリック→「Create」→「Prefab」を選択してください。 名前は「Cube_Prefab」としておいてください。 32 このPrefabはまだ空であるので、Game Objectを格納します。 今回はCubeを複製するので、PrefabにCubeを格納します。 新しくCubeを作成し、そのCubeを「Cube_Prefab」にドラッグ&ドロップします。 ドラッグ&ドロップしたら、新しく作成したCubeは 削除してください。 (オブジェクトを選択してDELキー) 33 これでCubeのPrefabができました。 Prefabを作る時は、一度SceneにGame Objectを置いてから、Prefabにすると 良いです。 34 次にScene上のCubeを、削除します。 Main CameraがCubeの子になっている場合は、Main CameraをCubeの子から 外してください。 図のようにドラッグ&ドロップすると、階層関係から外すことが出来ます。 その後、Cubeを削除し、Main CameraのTransformコンポーネントを変更します。 35 次に新しくスクリプトを作成します。 クラス名「Random_Create」で以下のスクリプトを書いてください。 using UnityEngine; using System.Collections; public class Random_Create : MonoBehaviour { public GameObject cube; void Update () { if (Input.GetKeyDown ("z")) { int x = Random.Range(-25, 25); int z = Random.Range(-25, 25); Instantiate(cube, new Vector3(x, 1, z), Quaternion.identity); } } } 36 空のGame Objectを1つ配置して、さっきつくった「Random_Create」を空の Game Objectに追加してください。 その後、「Random_Create」コンポーネントのCubeに、「Cube_Prefab」をドラッグ& ドロップします。 37 それでは再生してみましょう。 Zキーを押すと、ランダムにCubeが生成されます。 PrefabやGame Objectを生成する時は、 Instantiate(オブジェクト、位置、角度) で生成することができます。 38 今日は一通り、3D関連向けのことをやりましたが、パラメータを1つ減らすことで、 2Dに全て対応しています。 今日は特に覚えてほしいことは、 ・Game Objectは階層関係(親子関係)にすることができ、座標系も変わる ・StartメソッドとUpdateメソッドの処理の仕方 ・Instantiateでオブジェクトを生成できる の3つは覚えといてください。 39 お疲れ様でした! 40 41
© Copyright 2024 ExpyDoc