TGIF

Unityの覚え書き

Raycast

マウスクリックやタッチでオブジェクトを選択したい場合Raycastを使う。 ざっくりしたイメージだとある1点から線を伸ばし、当たったオブジェクトを取得する事が出来る。



void Update () { if (Input.GetMouseButtonDown(0)) { // カメラからタッチした場所まで光線を作成 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // RaycastHitに光線が当たったオブジェクトが格納させる。 RaycastHit hit; // 長さ15.0fの光線を作成しオブジェクトを取得 // 取得できたらtrueがかえる if (Physics.Raycast(ray, out hit, 15.0f)) { // ヒットしたオブジェクトのカラーを変更 hit.transform.gameObject.renderer.material.color = Color.red; } // デバッグ // Scene Viewに光線を可視化する。 // Game Viewには表示されない。 Debug.DrawRay(ray.origin, ray.direction*15.0f, Color.red); } }

Raycastはレイヤーを指定する事もできる。

void Update () {
    if (Input.GetMouseButtonDown(0)) {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        // レイヤーマスクはビットで指定する
        int layerMask = 1 << 8;
        // レイヤーマスクを指定
        if (Physics.Raycast(ray, out hit, 15.0f, layerMask)) {
            hit.transform.gameObject.renderer.material.color = Color.red;
        }
        Debug.DrawRay(ray.origin, ray.direction*15.0f, Color.red);
    }
}

Raycastは最も手前にあるオブジェクトを取得する事ができるが、 RaycastAllを使うと光線に当たったすべてのオブジェクトを取得する事ができる。

void Update () {
    if (Input.GetMouseButtonDown(0)) {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit[] hits = Physics.RaycastAll(ray, 15.0f);
        if (hits.Length > 0) {
             int num = hits.Length;
             for (int i=0; i<num; i++) {
                  hits[i].transform.gameObject.renderer.material.color = Color.red;
             }
        }
        Debug.DrawRay(ray.origin, ray.direction*15.0f, Color.red);
    }
}

また、別の使い方として、Raycastを使ってオブジェクトが他のオブジェクトに接地しているかなど 確認する事ができる。 以下の例は地面に接地しているかどうかをRaycastを使って確認し、 地面に接地している場合だけジャンプするようにしている。

float halfDist = 0;

void Start () {
    // Colliderの半分の長さを取得
    halfDist = collider.bounds.extents.y;
}
void Update () {
    if ( Input.GetKeyDown(KeyCode.Space) ) {
        // 下方向に光線を出し地面に接地しているか確認する。
        if (Physics.Raycast(transform.position, Vector3.down, halfDist) ) {
            rigidbody.AddForce(Vector3.up * 500.0f);
        }
    }
    Debug.DrawRay(transform.position, Vector3.down * halfDist, Color.red);
}

HTTP通信

HTTP通信を行うにはWWWクラスを使う。
HTTPコール後のレスポンスを待つ為にIEnumeratorを返すメソッドを作成し、
yield returnでレスポンスを待つようにする


IEnumerator GetData() {
     string url = "http://www.test123.com/GetData.php";
     WWW www = new WWW(url);
     yield return www;
     
     if (String.IsNullOrEmpty(www.error)) {
          // 成功処理
          Debug.Log(www.text);
     }
     else {
          // エラー処理
          Debug.Log(www.error);
     }
}

POSTで通信したい場合はWWWFormクラスを使う。


IEnumerator SetData() {
     WWWForm form = new WWWForm();
     form.AddField("data1", "foo");
     form.AddField("data2", "var");
     
     string url = "http://www.test123.com/GetData.php";
     WWW www = new WWW(url, form);
     yield return www;
     
     if (String.IsNullOrEmpty(www.error)) {
          // 成功処理
          Debug.Log(www.text);
     }
     else {
          // エラー処理
          Debug.Log(www.error);
     }
}

WWWFormにはAddField以外に、AddBinaryDataメソッドもあり、
画像などのバイナリデータを送る事もできる。

ヘッダー情報を付加したい場合はHashtableクラスを使用する。

IEnumerator GetData() {
     Hashtable hash = new Hashtable();
     hash.Add("Authorization", "something");
     hash.Add("Content-Type", "application/json");
     
     string url = "http://www.test123.com/GetData.php";
     WWW www = new WWW(url, new byte[]{(byte)0}, hash);
     yield return www;
     
     if (String.IsNullOrEmpty(www.error)) {
          // 成功処理
          Debug.Log(www.text);
     }
     else {
          // エラー処理
          Debug.Log(www.error);
     }
}

WWWクラスの第2引数にbyteの配列を渡しているのはiOS対応のため。
この値にNULLを指定した場合iOSではヘッダーが付加されない問題があるので、
適当にデータを入れてあげる必要がある。

ちなみに「yield return」で実行を停止させる場合「StartCoroutine」メソッドを使って呼び出す必要がある。


StartCoroutine("GetData");
StartCoroutine(GetData());

Color

Unityでマテリアルのカラーを変更するには以下のパラメーターを修正すればよい

renderer.material.color

colorにはRGBAの値が入っているがそれぞれ、0.0f ~ 1.0f の値の中で修正する(0~255ではない)

修正例
renderer.material.color = new Color(1.0f, 0.0f, 0.0f, 1.0f);

その他
Color.black
Color.white
Color.red
Color.green
Color.blue
などなどの静的変数で修正する事も可能

物理移動・回転

Rigidbodyを追加したオブジェクトを移動・回転させたい場合は以下のメソッドを使う
rigidbody.AddForce()・・・移動
rigidbody.AddTorque()・・・回転

引数は方向を示すVector3と力のかかり方を示すForceModeを任意で渡す。

ForceModeは以下4つのモードを持つ

Force・・・Massの情報を使い、連続的な力を加える
Acceleration・・・Massの情報を無視し、連続的な力を加える
Impulse・・・Massの情報を使い、瞬間的な力を加える。
VelocityChange・・・Massの情報を無視し、速度の変更をおこなう。

(デフォルトではForce)
また、AddForce / AddTorqueを行う場合UpdateメソッドではなくFixedUpdateメソッド内で行う。

 

rigidbody.AddForce(Vector3.forward * 10, ForceMode.Force);

(第2引数のForceModeは省略できる)

移動・回転・拡大縮小

Unityでの移動・回転・拡大縮小の仕方。

・移動
移動は以下のパラメーターを修正して行う
transform.position
transform.localPosition
親子関係があるさいに、子オブジェクトを移動させる場合は
localPositionで行う。
親のpositionを移動させた場合子オブジェクトもついてくる。

修正は下記の形で行う必要がある。
transform.position = new Vector3(90,0,0);
transform.position.xなどのパラメーターは取得は出来るが設定は出来ない。
すべての位置を0もしくは1などにしたい場合はVector3の以下のスタティック変数を使うのが便利
Vector3.zero;
Vector3.one;


・回転
回転は以下のメソッドもしくはパラメーターを修正する。
transform.Rotate()
transform.rotation
transform.localRotation

Rotateメソッドはオイラー角の指定以外にローカルもしくはワールド上の設定も可能。
rotationにQuaternion.Euler()メソッドを使って角度を入れてあげるとよい。
localRotationとrotationの関係は移動時と同じ

修正は下記のようにして行う。
transform.Rotate(Vector3.right, Space.World);
transform.rotation = Quaternion.Euler(90,0,0);


・拡大縮小
拡大縮小は以下のパラメーターを修正して行う
transform.localScale

修正方法は移動と同じ
transform.localScale = new Vector3(2,2,2);

また、オブジェクトにRigidbodyをつけ物理的な動きをさせたい場合は
positionやrotationなどの値を直接変更するよりAddForceやAddTorqueを使用する。
直接変更すると物理挙動がおかしくなる場合がある。