実現したいこと
RotationConstraintが使いづらかったので自作している中です。
やりたいこととしては、ソースのQuaternionの要素1つに対してウェイトをかけ、補正先に代入したいです。
また、いずれはすべての要素に別々の倍率をかけて値を代入したいです。
本来はRotationConstraintの動きを元に各軸事に倍率をかけられたらいいな~というところから来ています。
(1/6追記)
当初ジンバルロックの記事やUnityドキュメントを見ましてQuaternionは直接いじらないほうがよい、と書いてあったためオイラー角を使用しプログラムを組んでいました。
しかし、オブジェクトAが左回りで動くとき(インスペクター上ではマイナスの値になるとき)、-10度は350度として計算されてしまい、オブジェクトBが右回りで350度回ったことになってしまい、思った動きになりませんでした。(0~180度で計算されるので仕方のないことではありますが・・・)
SerializeObject化させオブジェクトAのインスペクター上の値をそのままオブジェクトBに使用する方法を取りましたが、再生時値が動かず思った動きになりませんでした。
「オブジェクトAの角度Xにウェイトをかけて、オブジェクトBに反映させる」をどの回転方向でも対応できるにはどのようにしたらよいでしょうか?
発生している問題・分からないこと
単純にウェイトをかけてそのままの値を入れてしまうと、ソースとなる角度が大きくなると段々誤差が大きくなり、正しい値を取ることができません。
例)オブジェクトAのXが90度のとき、Quaternionは(0.70711, 0, 0, 0.70711)。
オブジェクトAのXを0.5倍してオブジェクトBのXを45度にしたいので、0.70711 * 0.5 をする。
結果補正先オブジェクトBのQuaternionは(0.35355, 0, 0, 0.93541)になるが、インスペクター上で見ると41.41度となっている。
Quaternionの知識が浅いため単純に掛け算してしまっているので、知識として足りない部分があるかと思いますが、方法がございましたらご教授いただけますと幸いです。
該当のソースコード
C#
1 public class Param 2{ 3 public enum eAxis 4 { 5 X = 0, 6 Y = 1, 7 Z = 2 8 } 9 10 // 参照元 11 [SerializeField] private Transform m_Source; 12 public Transform Source { get { return m_Source; } } 13 [SerializeField] private eAxis m_SourceAxis; 14 public eAxis SourceAxis { get { return m_SourceAxis; } } 15 16 // 補正先の軸 17 [SerializeField] private eAxis m_TargetAxis; 18 public eAxis TargetAxis { get {return m_TargetAxis; } } 19 20 // ウェイト 21 [SerializeField, Range(0, 1.0f)] private float m_Weight; 22 public float Weight { get { return m_Weight; } } 23}
C#
1 // 参照元のQuaternionを取得 2 Quaternion sourceQuat = m_Param.Source.localRotation; 3 4 // 補正先のQuaternionを取得 5 Quaternion targetQuat = this.transform.localRotation; 6 7 8 // 参照する軸を判定 9 float sourceElement = 0.0f; 10 switch (m_Param.SourceAxis) 11 { 12 case Param.eAxis.X: 13 sourceElement = sourceQuat.x; 14 break; 15 16 case Param.eAxis.Y: 17 sourceElement = sourceQuat.y; 18 break; 19 20 case Param.eAxis.Z: 21 sourceElement = sourceQuat.z; 22 break; 23 } 24 25 // 指定した軸に対してWeightをかける 26 sourceElement *= m_Param.Weight; 27 28 // 補正先にいれる 29 switch (m_Param.TargetAxis) 30 { 31 case Param.eAxis.X: 32 targetQuat.x = sourceElement; 33 break; 34 35 case Param.eAxis.Y: 36 targetQuat.y = sourceElement; 37 break; 38 39 case Param.eAxis.Z: 40 targetQuat.z = sourceElement; 41 break; 42 } 43 this.transform.localRotation = targetQuat;
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
Rotationの値をSerializeObject化させインスペクター上の値をそのまま取ってくる方法を取りましたが、再生時値が動かず補正できませんでした。(アニメーションなどつけていたので他に原因はあるかもしれません)
補足
環境
Unity 6000.0.23f1