タグ別アーカイブ: C-sharp

[Unity3D]UPDATE()は遅いらしいし

  • UPDATE()を10000回呼ぶ
    Unityのオフィシャルブログの記事を見ていくつか気づいたこと、今後すべきことをメモしておく。

気づいたこと

  • Script Call Optimization を Fast but no Exceptions に変更 という作業で高速化できる
  • Updateは遅い

Script Call Optimization を Fast but no Exceptions に変更

Updateをまま使う場合、 Script call optimazation の項目を設定してあげる必要がある。

メニュー: Edit->Project Settings->Player

ここから設定が可能。

Updateは遅い

Updateやその他のマジックメソッドは、まずUnity側に登録されてその後GameObjectの存在チェックやNullチェック等を経て初めて呼び出される。
そのため、たとえ中身がカラだとしても void Update(){} と記述するだけで呼び出し対象にはなるし、上記のチェック等を経ているために処理の対象になり、少ないとはいえレイテンシーが発生する。

記事中では、この辺が必要無い場合、自前でManagerを作ってManagerのUpdate時に子に対して自前のUpdateを流す仕組みの方が高速であるとしている。
さらにListではなくArrayを使用したほうが効率的だとも述べられている。

自律制御のテストをしやすく子として呼ばれた時もよ動作させやすいやりかた

Manager側は一方的に呼び出すで良いとして、子側はMonobehaviour継承クラスだとしても void Update() 等を記述しない
自律テストをする場合は ChildDriver としてUpdate内で自身に着いた子用コンポーネントを自動取得して自前Updateを呼び出す仕組みにしてテストしたら良いと思われる。

具体的には

マネージャとして以下の様なコンポーネントでUpdate呼び出し。ブログまま。

    public abstract class Manager<ChildType> : MonoBehaviour
        where ChildType : IManagedMember
    {
        protected ChildType[] members;
        protected void Update(){
            int count = members.Length;
            for (var i = 0; i < count; i++) members[i].UnmmanagedUpdate();
        }
    }

呼び出される側はこんな感じでインターフェースを用意。

    public interface IManagedMember{
        void UnmmanagedUpdate();
    }
    public abstract class ManagedMember : MonoBehaviour,IManagedMember {
        public abstract void UnmmanagedUpdate();
    }

独立して子の挙動をテストしたいこ時は子にこれを追加してあげる。

    public class ManagedMemberDriver : MonoBehaviour {
        IManagedMember[] components;
        void Start () {
           this.components = GetComponents<IManagedMember>();
        }
        void Update () {
            int count = components.Length;
            for (var i = 0; i < count; i++) components[i].UnmmanagedUpdate();
        }
    }

あとは必要に応じてManager側には子作りメソッドを用意したりで色々できる。

C#のコードからメッシュを生成するチュートリアル

Polygon from s2kw on Vimeo.

  • コードからポリゴンを生成するチュートリアル。
  • 大まかな流れは以下のとおり
    • Mesh オブジェクトの生成
    • Mesh オブジェクトに頂点情報を渡す
    • Mesh オブジェクトの頂点情報に合わせた三角ポリゴン情報を渡す (この時点で画面には描画される)
    • Mesh オブジェクトにUV情報を渡す
    • Mesh オブジェクトにtangent情報を渡す
  • 書いたコード
  • チュートリアル
  • Unity::Reference::Mesh

続きを読む

CharacterControllerのMoveの1とSimpleMoveの1

nityでのオブジェクトの 移動 方法は三種類あって、必要なコンポーネントも予め用意されている。

  • CharacterController の SimpleMove() を叩く
  • CharacterController の Move() を叩く
  • Rigidbody の velocity の値を変更する

SimpleMoveとMove、velocityもVector3型のパラメータを必要とする。

なので controller.Move( this.transform.forward * this.speed )のように記述することがある。この時の引数として渡す値の Vector3 の magnitude の値の単位は何なのか、ということが気になって夜も眠れないので確認してみた。

確認するために適用した各GameObjectの構成は以下の通り。

続きを読む

SerializeFieldのデフォルトはnullであってnullでない

Unityのエディタ上でAssetを選択するとInspector上にD&Dで設定できるObjectFieldがある。
publicに指定したり、SerializeFieldなどのAttributeを記述するとInspector上に出現し、指定の型に合ったAssetの参照を関連付けすることができるおなじみの仕組み。

ここに何も指定していなかった場合の対応策として null合体演算子 という条件演算子がある。
これで判定して対応しようとすると上手く動かない。

続きを読む

[Unity3D][Unity:Editor]Editor拡張会のまとめの続き

Editor拡張会のまとめの続き

エラい時間が空いたどころか、年が明けてしまいました。今年も宜しくお願いします。
それとは別で講習中にとっていたメモが消失してしまって問題内容とか解答とかが分からなくなってしまったのでこのシリーズいったんやめようと思いますです。
テーマやコードはupされているのでそれにリンクを張る形をとった上で今回でいちど閉じたいと思います。

[wp_ad_camp_1]

Q 3

  • お題:GenericMenu
    • EditorWindowにコンテキストメニューを表示し「CreateCube」を選択してCubeを生成しなさい

やること

  • 右クリックのイベントを取得しなければならい。
  • イベントはOnGUI内で確認できる。
  • メニューはGenericMenuオブジェクトをnewする。
  • アイテムを追加する。
  • ShowAsContext()を忘れずに。

createCubeはprimitiveを使う。

GameObject.CreatePrimitive(PrimitiveType.Cube);

GenericMenuとは何か

  • GenericMenu
    GenericMenuとはコンテキストメニューとかドロップダウンメニューとかを提供するクラス。

  • AddItemでアイテムを追加して項目を増やす。

  • AddDisableItemはグレーアウト。
  • AddSeparator
  • DropDown
  • GetItemCountでアイテム数を確認。
  • ShowAsContextで実際に表示を行う。

GUIContentとは何か

以降のお題と回答例

Q 3 Pratical

解答例

Q 4

  • お題:CustomEditor

Q 4 Pratical

Q 5

  • お題:Gizmo

Q 5 Pratical

Q 6

  • お題:Handles

Q 6 Pratical

Q 7

  • お題:ScriptableObject & AssetDatabase

Q 7 Pratical

Q 8

  • お題:PostProcessor

Q 8 Pratical

Q 9

  • お題:EditorApplication & EditorUtility

Q 9 Pratical

Q 10

  • お題:Undo & Redo

Q 10 Pratical

ありません。

C#ショートコードプログラミング 第2版 (MSDNプログラミング)

[Unity3D][C#][Unity:Editor]GUILayout/EditorGUILayout/ObjectFieldまとめ

UnityEditorの出題2とGUILayoutやらEditorGUILayoutやら

引き続き、Editor拡張の会の出題と解答を参考に作成してます。

CodeIQにも出題されているのでやってみると面白いと思います。
日本Androidの会 秋葉原支部 Unity部 安藤 圭吾さんの問題に挑戦中!

[wp_ad_camp_1]

Q 2

  • お題:EditorWindow
    • ウィンドウを出現させて各パラメータの調整項目を出現させてね!
  1. EditorWindow継承クラスをGetWindow、またはCreateWindowで出現させる。
  2. OnGUIイベント内でEditorGUILayoutを使ってパラメータの反映をさせるためのUIを作成する記述をする。

GUILayoutはUnityの用意したゲーム画面用のGUIでやたらと重いクラス。
とはいえ3Dをバリバリ使う事が無ければそれほど気にならない。
GUILayoutにEditro部分のように描画させようとしても記述が増えてしまう。

EditorGUILayoutに名前部分の記述をさせるとこうなる

this.name = EditorGUILayout.TextField("名前",this.name);
EditorGUILayoutだとこんなにシンプル。
実際に表示される内容は、項目名と入力ボックス。入力をすると自動的に参照先に上書きされる。

GUILayoutに同じ事やらせるとこうなる

GUILayout.BeginHorizontal();<br />
GUILayout.Label("名前");<br />
this.str = GUILayout.TextField("Default Name");<br />
GUILayout.EndHorizontal();

お分かりいただけただろうか…。長い。

ただ、UnityEngine内にあるし、ゲーム画面側にも描画できるので覚えて居た方が良い。
実機デバッグでむちゃくちゃ重宝する。

そしてwindow.Show();は忘れずに。

Q 2 Pratical

  • 追加:基礎編に追加でテクスチャをD&Dする矩形を設けてくださいな。
    解答例

できませんでした。

回答例から何をすべきだったかを導きだす。
– テクスチャ格納メンバの追加
– テクスチャ格納領域の表示

テクスチャはUnityEngine.Texture2Dを使用することで解決できるが、問題はDrag&Dropする領域。
EditorGUILayoutを見てみるとオブジェクトを格納できるのは1つだけ。
EditorGUILayout.ObjectFieldを参照してみる。

実際、出題中もここは確認したのだけれど、そもそも格納メンバがTexture2Dというところまで到達できていなかったので、この項目を使うべきだとは思わなかった。これはUnityが用意しているObject型に対する造詣がまだまだ甘かったということの証左。精進します。

“`
Texture2D texture;

texture = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), false, GUILayout.Width(64), GUILayout.Height(64));

“`

回答例をみてみると、EditorGUILayout.ObjectFieldの表示サイズを変更している。
第四引数、第五引数だ。これについては後述する。

ObjectFieldの引数について

ドキュメントの丸写しだけれども。
– label
– フィールドの戦闘にだすためのラベル
– obj
– 実際にターゲットになるオブジェクト
– objType
– オブジェクトのタイプ
– allowSceneObjects
– シーン内のオブジェクトを受け入れるか否か。後述。
– options
– 次の項目で解説。

allowSceneObjectsについて

これをfalseにすると、assetの一部のオブジェクトを参照していた場合、assetはシーン内の参照を保持する事は出来ない。
– ※訳あってんのか…?

試しにGameObjectを格納することができるフィールドを用意して試してみたところ、Trueにするとシーン内(Hierarchy)内からD&Dすることができ、selectボタンをクリックした際もAssetsとSceneが選択できる。
逆にfalseにするとDrag&Dropをしようにも矩形は反応してくれないし、selectボタンをクリックしてもAssetsのみしかタブが表示されない。

つまり、そういうこと。

Gitポケットリファレンス

[C#]enumをint/stringにしたりint/stringからenumにしたり

[wp_ad_camp_1]

できました。

audio-technica ダイナミックヘッドホン ATH-W1000X

参考

Unity+NGUIで3Dオブジェクトに2D表示を行う

下準備・用意するもの

  • UISpriteオブジェクトを用意
  • 2Dカメラ(NGUIから Create New UI で作ったやつ)
  • 3D空間のカメラ(mainカメラ)
  • 3D空間のブジェクト

サンプル

gist

やってること

  1. 3Dカメラでワールド座標からスクリーン上の座標に変換
  2. 1の値を別のカメラのスクリーン座標上に変換
  3. 2D上に表示させたいアイテムのx,y座標だけ2で得た座標を上書き

※zは描画順やカメラの有効射程から外れるので無視。

ポイント

UISpriteは bottom に原点がくるように指定する。

bottomにすると原点が中央下部になるので、3Dオブジェクトのちょい上にあらかじめ表示が可能になる。

Spriteオブジェクトが乗ったパネルオブジェクトをPoint2DのplaneObjectに参照させる

そうするとパネル内で表示物を切り替えたりするときに便利だから。

ゲームメカニクス  おもしろくするためのゲームデザイン (ゲームデベロッパー)

のめりこませる技術 ─誰が物語を操るのか