最適化についてまとめます。
特にiPhoneやAndroid向けに開発する場合は悩まされる部分ではあります。
Unityに限らず役に立つ部分もあるかもしれません。
まず最適化を行う上で意識すべきことはキャッシュすることです。
毎ループごとにGetComponent()しているような部分はStartであらかじめキャッシュすることで無駄な処理を省くことができます。
また、ComponentだけではなくFind()で探しているオブジェクトや、結果が変わらない計算等はキャッシュするのが基本です。
ほかにもRaycastのキャッシュも効果があります。Raycast自身を無意識で使用してしまうととんでもないネックになることがほとんどです。LayerMaskを指定して判定を行うオブジェクトを少なくすることは当然ですが、一度判定が取れたのならばその判定をキャッシュしておきRaycastHit.colliderからコライダのRaycastを使用するようにしましょう。
Physics.Raycastが全てのコライダと判定をとろうとするのに対してCollider.Raycastではコライダ自身との判定をとるだけなので圧倒的にコストが変わると考えられます。
キャッシュの他にはUpdateおよびFixedUpdateで処理する内容に注意する必要があります。特にFixedUpdateは単位時間あたりに呼び出される回数がUpdateよりも多いので、気をつけないと非常に危険です。とくに前述のRaycastと複合されてしまうと非常に大きなネックとなります。
最後にベクター系クラスのmagnitudeには気をつける必要があります。ベクトルの大きさを求める際には三平方の定理からもわかりますが、平方根の計算を行う必要があり、それには地味に負荷がかかります。単にベクトルの大小比較を行うだけであればsqrMagnitudeを使用しましょう。こちらの値は最後に平方根をとる部分が除かれているすなわち大きさの二乗の値が取れることになり、x < y ならば x^2 < y^2 となるので単純な大小比較だけであればこちらで問題ありません。
今回はプログラムを中心にまとめました。
バッチやDrawcallなどプログラム以外に深く関わっている部分に関しては後日まとめます。
2012年8月2日木曜日
2012年7月27日金曜日
しってると便利な小技系関数
知っとくと意外と得する関数について今日は紹介していきます。
GameObject.SetActiveRecursively(bool)
あるゲームオブジェクトおよびそのオブジェクトの全ての子オブジェクトをアクティブor非アクティブにすることができる。
➡複雑な階層構造のオブジェクトをまとめて非アクティブにする際に便利です。
GameObject.GetComponentInChildren(Type)
あるゲームオブジェクトの子オブジェクトから指定のコンポーネントを取り出す。
➡GetComponent"s"にすることで複数あった場合にまとめて取得することが出来る。こちらも階層構造になっているオブジェクトを扱うときに便利。
Mathf.Rad2Deg Mathf.Deg2Rad
値を度数法と弧度法でそれぞれ変換する
➡ angle = radian * Mathf.Rad2Deg のように使用する。この場合は弧度法から度数法へ変換したことになる。
Mathf.PingPong(float t , float length)
0〜lengthの値をピンポン球を床に反発させているかのように行き来させた値を取得することが出来る。
➡サンプルにもあるが hoge = Mathf.PingPong(time.deltaTime . 10.0); のように使用するこの場合 hoge には0~10.0までの値が入る。
Lerp(Hoge fuga1, Hoge fuga2 , float rate) Slerp(Hoge fuga1, Hoge fuga2 , float rate)
Lerpは線形補完、Slerpは球面線形を補完を行い、rateの比率分だけ進んだ値を返す。
➡Lerpでは二点を直線的に結び、Slerpは曲線でなめらかに結ぶ。Vector3やQuaternionなど様々な型で用意されている。例えばLerp(v1,v2,0.5)ではv1とv2の中点が取得できる。
ほかにもたくさん便利な関数が用意されています。
本日は眠いのでここまで。後日またまとめていきます。
2012年7月26日木曜日
続・Layerについて
Layerについて昨日書けなかった部分を書いていきます。
ここでPhysicsManagerからLayerごとの衝突判定を設定します。PhysicsManagerはEdit➡ProjectSettings➡Physicsを選択することでInspector上に現れます。
ここの下のマトリクスで衝突判定に関して設定できます。今回はSphereとPlaneの衝突判定をOffにしました。
そうするとこのようにSphereとPlaneの衝突判定がなくなります。
昨日はカメラのカリングマスクとして使用しましたが、Lightのカリングマスクとして使用することも可能です。
まずは設定なしの状態
カリングマスクを設定するにはLightのコンポーネントの下から二番目のタブで、カメラと同様に設定することが可能。
まずは青いライトのカリングマスクからPlaneをのぞいた場合。
Planeには青いライトの影響がなくなっています。
つづいて、青はSphereに、緑はCubeに、赤はPlaneにのみ影響するようにしました。
影響を明らかにするためにLightProbeをOffにしました。
カリングマスクを設定するにはLightのコンポーネントの下から二番目のタブで、カメラと同様に設定することが可能。
まずは青いライトのカリングマスクからPlaneをのぞいた場合。
Planeには青いライトの影響がなくなっています。
つづいて、青はSphereに、緑はCubeに、赤はPlaneにのみ影響するようにしました。
影響を明らかにするためにLightProbeをOffにしました。
このような機能を使用することでプレイヤーキャラクターのみにあたるライト等を作成することが可能になっています。
続いてLayerMaskと衝突判定について。
先ほどのシーンのCubeとSphereにRigidbodyを追加することで、剛体運動をさせるようにします。この場合通常であれば下にあるPlaneに衝突します。
ここでPhysicsManagerからLayerごとの衝突判定を設定します。PhysicsManagerはEdit➡ProjectSettings➡Physicsを選択することでInspector上に現れます。
ここの下のマトリクスで衝突判定に関して設定できます。今回はSphereとPlaneの衝突判定をOffにしました。
そうするとこのようにSphereとPlaneの衝突判定がなくなります。
これらのようにLayer設定を分けることで様々なことが出来るようになります。この他にもゲーム制作では書かせないRaycastなどもLayerMaskを指定することで処理を軽くすることが可能になったりします。
2012年7月25日水曜日
Layerについて
UnityのLayerの機能を上手に利用することで様々な処理が行えるようになる。
まず、Layerの設定方法について。
インスペクタの最上部
この右下のタブで選択する。
自分でレイヤーを追加するには、AddLayerを選択することでUserLayerに命名出来る。
第一の使い方としてカメラのCullingMaskとして使用することが出来る。
インスペクタから
チェックマークが入っているレイヤーに指定されたオブジェクトはレンダリングされます。
画像ではわかりにくいですが、このように設定次第で描画されたりされなくなったりします。
これを応用することでUIのみを別カメラで描画し、重ね合わせることが出来ます。
このとき注意しなくてはならないのがカメラのClearFlagsとDepthです。
この例では右上をベースに左上を重ねているのですが、左上のスフィアを描画しているカメラの設定を
このようにしています。
まず、Depthを-1から0にすることで-1となっているベースのカメラよりも後にこのカメラの描画結果を処理することになります。
次にClearFlagsをDepth onlyにすることで、すでにベースのカメラで描画したものの上にこのカメラで描画したものを書き込みます。ここをSkyboxもしくはSolid Colorにしてしまうと、既にベースのカメラで描画されている内容が塗りつぶされてしまい、現在のカメラでの描画しているものしか見ることが出来なくなってしまいます。
このようにLayerを分けることで描画関係で複雑なことが出来るようになります。
ほかにも衝突判定やライティング等においてもレイヤー分けすることで特殊な扱いができるので、それについては後日扱います。
まず、Layerの設定方法について。
インスペクタの最上部
この右下のタブで選択する。
自分でレイヤーを追加するには、AddLayerを選択することでUserLayerに命名出来る。
第一の使い方としてカメラのCullingMaskとして使用することが出来る。
インスペクタから
チェックマークが入っているレイヤーに指定されたオブジェクトはレンダリングされます。
画像ではわかりにくいですが、このように設定次第で描画されたりされなくなったりします。
これを応用することでUIのみを別カメラで描画し、重ね合わせることが出来ます。
このとき注意しなくてはならないのがカメラのClearFlagsとDepthです。
この例では右上をベースに左上を重ねているのですが、左上のスフィアを描画しているカメラの設定を
このようにしています。
まず、Depthを-1から0にすることで-1となっているベースのカメラよりも後にこのカメラの描画結果を処理することになります。
次にClearFlagsをDepth onlyにすることで、すでにベースのカメラで描画したものの上にこのカメラで描画したものを書き込みます。ここをSkyboxもしくはSolid Colorにしてしまうと、既にベースのカメラで描画されている内容が塗りつぶされてしまい、現在のカメラでの描画しているものしか見ることが出来なくなってしまいます。
このようにLayerを分けることで描画関係で複雑なことが出来るようになります。
ほかにも衝突判定やライティング等においてもレイヤー分けすることで特殊な扱いができるので、それについては後日扱います。
2012年7月23日月曜日
OnCollisionHogeHoge()とOnTriggerHogeHoge()
衝突検知の際に扱う関数といえばOnCollisionEnter()もしくはOnTriggerEnter()ですが、
もうちょっとこれらの関数を知っておくと、より自由に衝突関係を扱うことが出来ます。
まず、衝突関係の関数を列挙します。
Collision系列
OnCollisionEnter(Collision)
OnCollisionStay(Collision)
OnCollisionExit(Collision)
Trigger系列
OnTriggerEnter(Collider)
OnTriggerStay(Collider)
OnTriggerExit(Collider)
Collision系列とTrigger系列の大きな違いとして
Rigidbodyの必要性
があります。
Trigger系列はColliderのIsTriggerのチェックボックスをオンにするだけで良いですが、
Collider系列は衝突したオブジェクト”両方”がColliderとRigidbodyを持っている必要があります。
つまり動くもの同士の衝突検知はOnCollisionHogeHoge()で、
どちらかが動かない場合はOnTriggerHogeHoge()で検知する必要があります。
また、それぞれの引数はCollisionとColliderと若干異なっています。
OnCollisionHogeHoge()では衝突自身を検知できるため引数がCollisionとなり、
OnTriggerHogeHoge()では衝突しているオブジェクトしか検知できないため、Colliderなのではないかと考えられます。
CollisionとColliderの大きな違いとしてContactPoint、
すなわち接点が取得できる出来ないにあると考えられます。
加えて、それぞれのStayおよびExitを使いこなせると自由に衝突関係を扱うことが出来るでしょう。
注意すべきはFugaFugaStay()系列で、OnCollisionStay()でもOnTriggerStay()でも、
有効になっている間はFixedUpdateの度に呼び出されます。これらのなかに重い処理を入れてしまうと簡単に処理落ちしてしまうので注意しましょう。特にMobile向けに開発する際には注意が必要です。
もうちょっとこれらの関数を知っておくと、より自由に衝突関係を扱うことが出来ます。
まず、衝突関係の関数を列挙します。
Collision系列
OnCollisionEnter(Collision)
OnCollisionStay(Collision)
OnCollisionExit(Collision)
Trigger系列
OnTriggerEnter(Collider)
OnTriggerStay(Collider)
OnTriggerExit(Collider)
Collision系列とTrigger系列の大きな違いとして
Rigidbodyの必要性
があります。
Trigger系列はColliderのIsTriggerのチェックボックスをオンにするだけで良いですが、
Collider系列は衝突したオブジェクト”両方”がColliderとRigidbodyを持っている必要があります。
つまり動くもの同士の衝突検知はOnCollisionHogeHoge()で、
どちらかが動かない場合はOnTriggerHogeHoge()で検知する必要があります。
また、それぞれの引数はCollisionとColliderと若干異なっています。
OnCollisionHogeHoge()では衝突自身を検知できるため引数がCollisionとなり、
OnTriggerHogeHoge()では衝突しているオブジェクトしか検知できないため、Colliderなのではないかと考えられます。
CollisionとColliderの大きな違いとしてContactPoint、
すなわち接点が取得できる出来ないにあると考えられます。
加えて、それぞれのStayおよびExitを使いこなせると自由に衝突関係を扱うことが出来るでしょう。
注意すべきはFugaFugaStay()系列で、OnCollisionStay()でもOnTriggerStay()でも、
有効になっている間はFixedUpdateの度に呼び出されます。これらのなかに重い処理を入れてしまうと簡単に処理落ちしてしまうので注意しましょう。特にMobile向けに開発する際には注意が必要です。
キーボードショートカット(Mac)
Unityでもなんでもとにかくツールを自由自在に扱うには、
キーボードショートカットを覚えることが重要です。
なので、今回は自分がよく使うキーボードショートカットをまとめていきます。
自分の環境はMacなのでWindowsの方はごめんなさい。
CMD + N = 新しいシーンの作成
CMD + S = 現在のシーンの保存
CMD + Z = アンドゥ
CMD + Shift + Z = リドゥ
CMD + C = 現在選択しているオブジェクトをコピー
CMD + X = 現在選択しているオブジェクトをカット
CMD + V = コピーしたオブジェクトの複製
CMD + D = 現在選択しているオブジェクトの複製
CMD + Shift + N = 空のGameObjectの作成
CMD + Shift + N = 空のGameObjectの作成
CMD + B = ビルド
CMD + Shift + B = ビルドオプションを開く
シーンビューがアクティブな状態で F = 選択しているオブジェクトにフォーカス
他に思い出したら追記していきます。
登録:
投稿 (Atom)


















