【Unity】Cubeをカメラから見て常に同じ向きに回転させる

投稿者: | 2020-05-05

カメラの前に置いたCubeなどのオブジェクトを、カメラの向きを基準にして回転させてみます。

マウスカーソルの移動を使って回転させるときに、Cubeの向きに沿って回転させると、Cubeの回転と一緒に軸も回転するので、カメラから見た回転方向が変わってしまって、直感的な操作ができません。

var x = CrossPlatformInputManager.GetAxis("Mouse X");
var y = CrossPlatformInputManager.GetAxis("Mouse Y");

turnAmount_x -= x;
turnAmount_y += y;

item.transform.localRotation = Quaternion.Euler(turnAmount_y * turnSpeed, turnAmount_x * turnSpeed, 0f);

Quaternion.Euler()は引数に回転させる軸のベクトルを入れますが、そこでCameraの向きをCubeのローカル座標に変換したものを使えば良いはずです。

空のゲームオブジェクトに前の記事のスクリプトを付けて、アイテムを回転させる部分を少し書き変えました

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;


public class ItemScript2 : MonoBehaviour
{
    [SerializeField] float turnSpeed = 3f;
    [SerializeField] GameObject item;
    [SerializeField] Material mat1;
    [SerializeField] Material mat2;
   
    [SerializeField] Transform cameraPivot;

    float turnAmount_x;
    float turnAmount_y;
    Transform cam;
    MeshRenderer itemMeshRenderer;
    bool frag = false;
    Material[] materials;



    // Start is called before the first frame update
    void Start()
    {
        cam = Camera.main.transform;
        itemMeshRenderer = item.GetComponent();
        materials = new Material[2];
        materials[0] = mat1;
        materials[1] = mat1;
    }

    // Update is called once per frame
    void Update()
    {
        if (CrossPlatformInputManager.GetButtonDown("Fire2"))
        {
            turnAmount_x = 0f;
            turnAmount_y = 0f;
        }

        if (CrossPlatformInputManager.GetButton("mouse 2"))
        {
            var x = CrossPlatformInputManager.GetAxis("Mouse X");
            var y = CrossPlatformInputManager.GetAxis("Mouse Y");

            //turnAmount_x -= x;
            //turnAmount_y += y;

            //item.transform.localRotation = Quaternion.Euler(turnAmount_y * turnSpeed, turnAmount_x * turnSpeed, 0f);
            
            item.transform.localRotation *= Quaternion.Euler(item.transform.InverseTransformDirection(cam.up) * x * -turnSpeed);
            item.transform.localRotation *= Quaternion.Euler(item.transform.InverseTransformDirection(cam.right) * y * turnSpeed);
        }


        // 面の色を変える
        float dot = Vector3.Dot(-item.transform.right, (cam.position - item.transform.position).normalized);

        if (dot > 0.85f)
        {
            materials[1] = mat2;

            itemMeshRenderer.materials = materials;
            frag = true;
        }
        else
        {
            if (frag)
            {
                materials[1] = mat1;
                itemMeshRenderer.materials = materials;
                frag = false;
            }
        }        
    }
}

アイテムのトランスフォームのInverseTransformDirection()にカメラの上と右方向を入れて、それらをCubeのローカル座標に変換しています。それに回転量をかけてからQuaternionに変換し、Cubeのローカル回転に掛け合わせれば、Cubeはその方向に沿って回転します。

カメラは枢軸となる空のゲームオブジェクトの子オブジェクトにしています。

ヒエラルキーウィンドウ

カメラの位置や向きを変えてもカメラの向きに沿って回転します。

コメントを残す

メールアドレスが公開されることはありません。