親の回転角度を引いて相殺すればええやん?って思ったら、簡単にいかなかったのでメモ。
やりたいこと
親(3Dゲームオブジェクト)が回転しても、子(スプライト)が回転しないようにしたい。
NaviMeshを使ってAgentとなる親オブジェクトを移動させるんだけど、その時にYが回転するんですよね。
その親オブジェクトにキャラクター画像のスプライトをくっつけてるものだから、一緒に回っちゃう。
2Dだとそれじゃアカンやーん!
オブジェクトの相関図
この子にスクリプトをアタッチする。
ちなみに、親の親 Charactersはこんな感じ。
コード
このコードを子にアタッチする。
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); } }
実行結果
初期の親
初期の子
ログ
def=(90.0, 0.0, 0.0) _parent=(0.0, 0.0, 0.0) result=(90.0, 0.0, 0.0)
回転後の親
回転後の子
ログ
def=(90.0, 0.0, 0.0) _parent=(0.0, 86.1, 0.0) result=(90.0, 273.9, 0.0)
なんで、回転後の子の値が画像とresultで違うのかわからんけど、相殺はできているようでスプライトの向きが変わることはなかった。
考え方
考え方といってもまだ謎だらけで、いろいろ試した結果上手くいっただけだが・・・。
相殺の仕方
Quaternionのままだと難しかったので、オイラー角で考えることにした。
どうやら、単純に引き算して相殺する方法ではうまくいかないみたい。
親の変化量を逆方向に加算することで相殺させるといいらしい。
逆方向について
コードを見ると、_parentのXYZが"てれこ"になってる。
float _x = _parent.z + def.x; float _y = _parent.x + def.y; float _z = _parent.y + def.z;
それは、Quaternion.Eulerメソッドのリファレンスを見ると下のように書いてあったからそうしたんだけど、おそらくこれが逆方向なんだと思う。
Unity - スクリプトリファレンス: Quaternion.Euler
public static Quaternion Euler(float x, float y, float z);
Description
Z 座標を軸に z 度、X 座標を軸に x 度、Y 座標を軸に y 度 (順番はこのとおり) 回転する回転を返します。
以上。