Roba Memo - 素人のUnity覚書と奮闘記

素人のUnity覚書と奮闘記

親の回転を無視したい

親の回転角度を引いて相殺すればええやん?って思ったら、簡単にいかなかったのでメモ。

やりたいこと

親(3Dゲームオブジェクト)が回転しても、子(スプライト)が回転しないようにしたい。

NaviMeshを使ってAgentとなる親オブジェクトを移動させるんだけど、その時にYが回転するんですよね。
その親オブジェクトにキャラクター画像のスプライトをくっつけてるものだから、一緒に回っちゃう。
2Dだとそれじゃアカンやーん!

オブジェクトの相関図

f:id:nico-taniku:20170906104009p:plain
この子にスクリプトをアタッチする。
ちなみに、親の親 Charactersはこんな感じ。
f:id:nico-taniku:20170906104322p:plain:w300

コード

このコードを子にアタッチする。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FixChildRotation : MonoBehaviour
{

    Vector3 def;

    void Awake ()
    {
        def = transform.localRotation.eulerAngles;
    }
    
    void Update ()
    {
        Vector3 _parent = transform.parent.transform.localRotation.eulerAngles;

        float _x = _parent.z + def.x;
        float _y = _parent.x + def.y;
        float _z = _parent.y + def.z;

        transform.localRotation = Quaternion.Euler (new Vector3 (_x, _y, _z));

        //ログ用
        Vector3 result = transform.localRotation.eulerAngles;
        Debug.Log ("def=" + def + "     _parent=" + _parent + "     result=" + result);
    }


}

実行結果

初期の親
f:id:nico-taniku:20170906102627p:plain:w300
初期の子
f:id:nico-taniku:20170906102643p:plain:w300
ログ

def=(90.0, 0.0, 0.0)     _parent=(0.0, 0.0, 0.0)     result=(90.0, 0.0, 0.0)

回転後の親
f:id:nico-taniku:20170906102701p:plain:w300
回転後の子
f:id:nico-taniku:20170906102716p:plain:w300
ログ

def=(90.0, 0.0, 0.0)     _parent=(0.0, 86.1, 0.0)     result=(90.0, 273.9, 0.0)

なんで、回転後の子の値が画像とresultで違うのかわからんけど、相殺はできているようでスプライトの向きが変わることはなかった。
360度 - 273.9度 = 86.1度
だから、逆方向に回転しているのがわかる。

考え方

考え方といってもまだ謎だらけで、いろいろ試した結果上手くいっただけだが・・・。

相殺の仕方

Quaternionのままだと難しかったので、オイラー角で考えることにした。
どうやら、単純に引き算して相殺する方法ではうまくいかないみたい。
親の変化量を逆方向に加算することで相殺させるといいらしい。

逆方向について

コードを見ると、_parentのXYZが"てれこ"になってる。

float _x = _parent.z + def.x;
float _y = _parent.x + def.y;
float _z = _parent.y + def.z;

それは、Quaternion.Eulerメソッドのリファレンスを見ると下のように書いてあったからそうしたんだけど、おそらくこれが逆方向なんだと思う。

Quaternion.Euler - Unity スクリプトリファレンス

public static Quaternion Euler(float x, float y, float z);
 
Description
Z 座標を軸に z 度、X 座標を軸に x 度、Y 座標を軸に y 度 (順番はこのとおり) 回転する回転を返します。

以上。