【Unity】ユニティちゃんにマグロを持たせたよ【コンストレイントをラーニングした】
タイトルで伝わりにくかったので変更しました。
はじめに
最近コンストレイントを覚えたので忘れないようにメモしておこうと思います。
コンストレイントとは
自分は概念すら知らなかったのですが、MAYAなどではおなじみのようです。
オブジェクトのトランスフォームを参照のかたちで保持しておいて、自分はその参照を使って姿勢を決める。自分の親の姿勢は無関係。と理解しています。
従来の方法
└体
└腕
└手
└武器(これを制御したい)
体を Destroy した場合 武器まで 削除されます。一度デタッチしたり工夫が必要
コンストレイントを使用した場合
├体
│└腕
│ └手
│
└武器(手のTransformで更新)
たとえ 誰かが 体 を Destroy しても 武器は削除されません。参照先がなくなるだけです。
ほしかった機能に合致した
常々UnityのTransform の親子関係には不満を持っていました。親子関係と姿勢の関係が Transform にまとめられているので不満が出てきます。
- あるNodeにアタッチするには、その子供にしないと姿勢を継承できない。→親がDestroy されると 自分もDestroy される。
- 参照するようなスクリプトを自分で作る→ Updateのタイミングが微妙・無駄なUpdateが増える。
この辺りの問題が解消されます。
スクリプトで設定する場合
コンストレイントにも複数種類がありますが、詳細はマニュアルか他の解説ページを御覧ください。自分は ParentConstraint しかつかわないので。
GameObject m_Hand; // 手のオブジェクト
GameObject m_Weapon; // 武器のオブジェクト
// 武器にコンストレイント追加
var constraint = m_Weapon.AddComponent<UnityEngine.Animations.ParentConstraint>();
// コンストレイントのソースを追加
constraint.AddSource( new UnityEngine.Animations.ConstraintSource(){ sourceTransform = m_Hand.transform, weight = 1.0f }); // m_Handのtransform を参照
constraint.locked = true;
constraint.constraintActive = true;
m_Weapon に ParentConstraintコンポーネントを追加し、ソースに m_Hand.transform を設定しています。
これで m_Weapon と m_Hand の親子関係は無関係で Hand の Transform を継承してWeaponの姿勢が変化します。
m_Weapon を 90度回転させて 少し 移動した位置に アタッチしたい場合などは Set○○○○Offset() を使います。
// アタッチ具合を変更する
// X軸を90度回転
constraint.SetRotationOffset( 0, new Vector3( 90, 0, 0));
// X方向に1m移動
constraint.SetTranslationOffset( 0, new Vector3( 1, 0, 0));
エディッタで設定する場合
ParentConstraintコンポーネントをアタッチ
接続したいオブジェクト(今回はマグロ)を選択中に
Add Component > Miscellaneous を選択
Parent Constraint を選択
各種設定していきます。
① 接続先の Transform をドラッグします。今回はユニティちゃんの右手
② 姿勢のオフセットを設定します。今回は Zが逆だったので Z=-180 Y は微調整です。
③④設定が終わったら Lock と IsActive にチェックを入れ コンストレイントを有効にします。
親子関係は赤で囲んだ部分です。
Tunaf がマグロで
J_R_ForeArm_00_tw がユニティちゃんの手になります。
ご覧のように親子関係になくてもアタッチできています。
実際の映像
うまく接続されています。
仮に ユニティちゃんを Destroy して ミサキチちゃんに変更しても Tunaf の コンストレイントの参照先を変えるだけで持ち替えが可能になります。