すくまりのメモ帳すくまりのメモ帳
← 記事一覧に戻る

【Unity, Teddy, 3Dモデリング】カメラを回転したときのオブジェクト生成位置のずれを解消

2018-11-01
【Unity, Teddy, 3Dモデリング】カメラを回転したときのオブジェクト生成位置のずれを解消

はじめに

UnityのTeddyを使用する際、カメラを移動させたり向きを変えると、手書きのオブジェクトの生成位置がずれます。その問題に取り組みます。

前回の記事

【Teddy】ゲーム実行中に好きな色の3Dモデルを作製する方法

カメラの向きによるオブジェクト生成位置のずれ

Main Camera の位置をネズミを軸にして反転させてからオブジェクトを生成すると、y軸を対称にして反対側にオブジェクトが出現します。

手書きのオブジェクトはTeddy/TeddyRuntimeDemo/Prefabs内のPuppetという空オブジェクトにメッシュを取り付ける形で生成しております。

PuppetはPosition、Rotation共に(0,0,0)です。これをカメラの向きを180°反転させて生成すると、

Rotationが(x, y, z) = (0, -180, 0)となっていることが分かります。

ここでTeddyRuntimeDemoに入っているスクリプトのTeddyRuntimeDemo.csを見てみると、Create()メソッド内にgo.transform.rotation = camera.transform.rotation; という記述がありました。

        //-----------------------------------------
        //手書きのオブジェクトを生成する
        //------------------------------------------
        void Create (GameObject go, List<Vector2> screens)
        {
            //(Closureクラスが見つからない。たぶんTeddyRuntime.dllの中に入っていると思われます)
            var closure = Closure.GetClosure(screens);
            if (closure.Count > 2)
            {
                closure.RemoveAt(0);
                closure.RemoveAt(closure.Count - 1);
            }
            screens.AddRange(closure);
 
            //screenの座標を引数にして、camera.ScreenToWorldPointの座標を返す
            var world = screens.Select(screen => {
 
                //zOffsetが0だと生成したオブジェクトの中身が見えるので、camera.nearClipPlaneでz軸方向の撮影平面位置を少しずらす
                return camera.ScreenToWorldPoint(new Vector3(screen.x, screen.y, camera.nearClipPlane + zOffset)); 
 
            }).ToList();//ToList()で、screens全体にbody.isKinematic = true;を付与
 
            //go オブジェクトをカメラの向きに合わせる
            go.transform.rotation = camera.transform.rotation;
 
            var points = world.Select(p => new Vector2(p.x, p.y)).ToList();
 
            // create lowpoly mesh for MeshCollider vertex count limit.(APIの部分)
            var lowpoly = TeddyUtility.CreateMesh(points, 200, 0.85f);
            var collider = go.GetComponent<MeshCollider>();
            collider.sharedMesh = lowpoly;
 
            TeddyUtility.CreateTeddy(go, points, 600, 0.85f);
 
            //生成したオブジェクトの色を変更する
            go.GetComponent<Renderer>().material.color = Color.red;
        }

go は生成したオブジェクト(Puppet)を指しており、goのRotationをCameraのRotationと同じにする、といったものです。

これによりPuppetのRotateが変化しておりました。

一見問題なさそうですが、たぶんスクリーン座標とワールド座標の兼ね合いで不具合が起きているのでしょう。

これをダブルスラッシュで無視すると以下のようになります。

これでカメラの180°回転状態の問題については解消できました。しかしながら、あと二つ問題が残ってます。

カメラを90°回転させたとき

カメラを90°回転させると、円の中にオブジェクトが現れません。実際には、厚みの無いペラペラのオブジェクトが生成されております。なので、横からでも3Dオブジェクトを生成できるようにする必要があります。

カメラを移動してもPuppetの出現位置が変わらない

カメラを移動させてもPuppetの生成位置が変わらないので、右下のGame ビューのように、手書きの円と生成したPuppetの位置が大きくずれる結果となりました。

このあたりも、相対座標を組み込んで修正する必要があります。

まとめ

カメラを180°回転したときの3Dオブジェクト生成位置のずれを解消できた。

忙しい人のためのUnity入門講座へ