はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】3Dモデルの関節のTransformをAnimatorコンポーネントから取得する(GetBoneTransform)

はじめに

UnityのHumanoidモデルには,モデルのImportSettingよりそのボーンマッピングをみることができます。
アバターの Mapping タブ - Unity マニュアル

f:id:hanaaaaaachiru:20200919192453p:plain
unityちゃんのボーンマッピング

今回はボーンに対応したゲームオブジェクトをスクリプトから取得する方法を紹介したいと思います。

ボーンの列挙型

取得する方法をみる前に,UnityEngine名前空間にはHumanoid型のモデルのボーンの一覧が記述されたHumanBodyBonesという列挙型が存在します。
Unity - Scripting API: HumanBodyBones

public enum HumanBodyBones
{
	Hips = 0,
	LeftUpperLeg = 1,
	RightUpperLeg = 2,
	LeftLowerLeg = 3,
	RightLowerLeg = 4,
	LeftFoot = 5,
	RightFoot = 6,
	Spine = 7,
	Chest = 8,
	UpperChest = 54,
	Neck = 9,
	Head = 10,
	LeftShoulder = 11,
	RightShoulder = 12,
	LeftUpperArm = 13,
	RightUpperArm = 14,
	LeftLowerArm = 0xF,
	RightLowerArm = 0x10,
	LeftHand = 17,
	RightHand = 18,
	LeftToes = 19,
	RightToes = 20,
	LeftEye = 21,
	RightEye = 22,
	Jaw = 23,
	LeftThumbProximal = 24,
	LeftThumbIntermediate = 25,
	LeftThumbDistal = 26,
	LeftIndexProximal = 27,
	LeftIndexIntermediate = 28,
	LeftIndexDistal = 29,
	LeftMiddleProximal = 30,
	LeftMiddleIntermediate = 0x1F,
	LeftMiddleDistal = 0x20,
	LeftRingProximal = 33,
	LeftRingIntermediate = 34,
	LeftRingDistal = 35,
	LeftLittleProximal = 36,
	LeftLittleIntermediate = 37,
	LeftLittleDistal = 38,
	RightThumbProximal = 39,
	RightThumbIntermediate = 40,
	RightThumbDistal = 41,
	RightIndexProximal = 42,
	RightIndexIntermediate = 43,
	RightIndexDistal = 44,
	RightMiddleProximal = 45,
	RightMiddleIntermediate = 46,
	RightMiddleDistal = 47,
	RightRingProximal = 48,
	RightRingIntermediate = 49,
	RightRingDistal = 50,
	RightLittleProximal = 51,
	RightLittleIntermediate = 52,
	RightLittleDistal = 53,
	LastBone = 55
}

最後にLastBoneという項目が存在するのですが、これがなかなかの曲者で実在するボーンではなく区切りになる最後のボーンというよく分からないものです。
HumanBodyBones - Unity スクリプトリファレンス

次に紹介する方法でLastBoneに対応したTransformを取得しようとすると、エラーが出てきてしまったので要注意してください。(特にforeachのとき)

取得方法

AnimatorにはGetBoneTransformというPublic Methodが存在し,これを用いるとボーンに対応したTransformを取得できます。

public Transform GetBoneTransform (HumanBodyBones humanBoneId);


実際に使ってみるとこんな感じ。

Animator animator = GetComponent<Animator>();
Transform head = animator.GetBoneTransform(HumanBodyBones.Head);
head.localRotation = new Quaternion(0, 0, 0, 0);

さいごに

最初は全部インスペクターで設定しようかなと思ったのですが、調べてみればこんな便利な機能があったみたいです。

良かったら活用してみてください。

ではまた。