Unityメモ

Unity修行中の覚え書きです。書かれている事が正しいとは限りません。

2015年05月

UnityのPhysicsについて - プログラムの素
とても参考になったので。
Collider + Rigidbody の組み合わせで
・Static Collider
・Rigidbody Collider
・Kinematic Rigidbody Collider
を分類してある所とか判りやすかったです。

あとは Character Controller 絡みもあるといいんだけどなぁ。

Unity4.6で開発中のプロジェクトをUnity5にコンバートした後、Web Playerで影が出なくなったので、Quality設定を確認。(辿りつくまで数時間悩んだ)
quality
※[Edit]=>[Project Settings]=>[Quality]

各プラットフォームのデフォルト値が全部Fastestになってました。Web Player(一番左)は確か以前はSimpleだったよな、と思い出してデフォルト値をSimpleに再設定。
結果、影が出るようになりました。

4.6から5へ移行しました。気づいた点を列挙していきます。
■Screen.lockCursor非推奨。今後はCursor.lockStateを使用すべし。
Cursor.lockState = CursorLockMode.None; // カーソルを解放する
Cursor.lockState = CursorLockMode.Locked; // カーソルを中央にロックする
Cursor.lockState = CursorLockMode.Confined; // カーソルをウィンドウ内に留める
http://docs.unity3d.com/500/Documentation/ScriptReference/CursorLockMode.html

■GameObjectのvaliablesから以下の項目が削除されている。今後はGetComponentで。
animation, audio, camera, collider, collider2D, constantForce, guiText, guiTexture, hingeJoint, light, networkView, particleEmitter, particleSystem, renderer, rigidbody, rigidbody2D

■データコンバートしたゲームが固まる
ゲームを起動すると、1分くらい固まってから動き出します。調べた所、ゲーム冒頭でInstantiateしている箇所で固まっていました。
具体的には、色を変えただけの同じモデルで作ったプレハブ二つ(prefab1及びprefab1a)を用い、続けてInstantiateしている箇所です。
どちらかをコメントアウトすると問題なく動作します。
NG(固まる)
    Instantiate(prefab1);
    Instantiate(prefab1a);

OK(固まらない)
    Instantiate(prefab1);
//  Instantiate(prefab1a);

OK(固まらない)
//  Instantiate(prefab1);
    Instantiate(prefab1a);

データコンバートした結果、資源の競合でも起きてるんだろうとアタリを付けて、二つのプレハブを再定義(作り直し)してみたら問題解消しました。結局根本原因は判らずじまい。

SliderをGetComponentしてvalueを参照することでスライド値を参照できます。
多分こんな感じで。
    Slider sld = gameObject.GetComponent<Slider>();
    Debug.Log("スライダー値="+sld.value.ToString());

これとは別にOnValueChangedに定義したメソッドでスライド値を受け取る方法です。
slider
画像の例ではManagerクラスのredSliderメソッドにスライド値を渡して何らかの処理を行う想定です。OnValueChangedなのでスライダーを動かす度に当該メソッドを実行します。
注意点ですが、画像のようにメソッドを選択する際、一番上のほうの「redSlider」を選択する事です。下のほうにも「redSlider(float)」がありますが、こちらを選んでも正しく値を渡すことは出来ません。

そして受け取る側のスクリプトは以下のようになります。
    public void redSlider(float val){

    }

この例ではvalにスライド値が入ります。ちなみに、SliderのインスペクタでWhole Numbersにチェックが入っているとスライド値が整数になるのですが、この場合もfloat型で受け取ります。

MobのAIなどで、複数の目的地を格納した配列を元に次の行動を決めたい場合。
一番簡単な方法は、一番近い場所を次の目的地とする、みたいな判断ですが、これでは全てのMobが同じ行動を取ってしまいます。
そこでランダム要素を取り入れるわけですが、そこに距離による重みづけを加味します。つまり近ければ高確率、遠いほど低確率に選択されるようにしたいわけです。

    private int SelectRandom(float[] weight, bool reciprocal){
        float total = 0f;
        float[] eval = new float[weight.Length];
        for (int i = 0; i < weight.Length; i++) {
            if (reciprocal){
                eval[i] = (1f / Mathf.Abs(weight[i]));
            } else {
                eval[i] = Mathf.Abs(weight[i]);
            }
            total += eval[i];
        }
        if (total == 0f) {
            return -1;
        }
        float rand = Random.value * total;
        for (int i = 0; i < eval.Length; i++) {
            if (rand < eval[i]) {
                return i;
            }
            rand -= eval[i];
        }
        return -1;
    }

重みづけ配列 weight を引数として受け取り、乱数 rand の値がどの要素を指すかを調べて配列インデックスを返します。
このような処理は、円グラフにダーツを投げてどの要素に当たるか、などと例えられますが、それは数値が大きいほど高確率の場合です。
今回は数値が小さい(=距離が近い)ほど高確率にしたいので、引数に reciprocal を設けました。 reciprocal がtrueの場合は重みを逆数で評価します。

↑このページのトップヘ