【Unity】Anima2DのTrex調査してみた①【Anima2D】【編集中】
Anima2Dで今回調査する対象は以下になります(きっしーのUnityエディタの動画です)
このSceneがどのような構成で成り立っているか調べていきます。
Anima2Dを利用してスケルタルアニメーションを作成するまでの解説は別で行う予定です。
Hierarchyの構成
このSceneはざっくり以下で構成されています
①Main Camera(今回はTrexを追従するためのスクリプトをアタッチしています)
②Trex(今回のメインGameObjectであるTrex。スケルタルアニメーションの設定がされており、とKey入力を受け付けるコントローラーをアタッチしています)
③Jungle(背景の遠近感を出すためにSpriteをTrexより前のレイヤーに1、後ろのレイヤーに3設定してそれぞれ独立して移動しています)
Game画面のみの動画を作成しました。レイヤーの動きに注目してください。すごく感動しました。
Main Camera
今回のMainCameraはFollowスクリプトをアタッチしています。
ざっくり説明すると、メインカメラをTrexに追従するようにしています。
以下、Followスクリプトになります。その後もう少し解説します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using UnityEngine; using System.Collections; [ExecuteInEditMode] public class Follow : MonoBehaviour { public Transform target; public Vector3 offset; void LateUpdate() { if (target) { transform.position = target.position + offset; } } } |
ソースを説明すると、targetにTrexのTransformコンポーネントをアタッチしており、offsetにはInspectorで設定した値が格納されており、MainCameraのポジションをTrex基準で調整できるようになっています。
Followスクリプトの説明は以上になります。
簡単なスクリプトなので説明することはほどんどありません。
Trex
以下、Trex配下のGameObject一覧です
①SpriteMeshes
⒈t_rex_leg_l
⒉t_body
⒊t_rex_jaw_open_back
⒋t_rex_jaw_open
⒌t_rex_leg_r
②Controls
⒈Control Hips
⒉Control Jaw
③IKs
⒈Head Ik CCD
⒉Tail Ik CCD
⒊R Foot Ik Limb
・R Toes Ik Limb
⒋L Foot Ik Limb
・L Toes Ik Limb
④Hips
⒈Tail 1
・Tail 2
・Tail 3
・Tail 4
⒉Upper Leg R
・Leg R
・Foot R
・Fingers R
⒊Upper Leg L
・Leg L
・Foot L
・Fingers L
⒋Spine 1
・Neck
・Head
・Jaw
・Jaw 2
見てわかる通り数が多すぎるので親要素であるTrexと、①〜④の親要素のみ今回は解説します。
Trex
Trex本体のObjectは以下で構成されています。
- Animator
- CharacterMotionスクリプト
- PoseManagerスクリプト
- IkGroupスクリプト
がアタッチされています。
Trex-Animator
TrexのAnimatorは今回TrexのIdleアニメーションとWalkアニメーションが設定されておりAnimationコントローラーで制御されています。
設定詳細は以下になります。(待機状態のアニメーションとアニメコントローラーです。)

思っていたよりもポイントは少なめでした。

Trex-CharacterMotionスクリプト
こちらのスクリプトはキー入力された時にIdleアニメーションとWalkアニメーションを切り替えるために利用しています。
以下、CharacterMotionスクリプトになります。その後もう少し解説します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using UnityEngine; using System.Collections; public class CharacterMotion : MonoBehaviour { Animator animator; void Start() { animator = GetComponent<Animator>(); } void Update () { float xAxis = Input.GetAxis("Horizontal"); Vector3 eulerAngles = transform.localEulerAngles; if(xAxis < 0f) { eulerAngles.y = 180f; }else if(xAxis > 0f) { eulerAngles.y = 0f; } transform.localRotation = Quaternion.Euler(eulerAngles); animator.SetFloat("Forward", Mathf.Abs(xAxis)); } } |
ソースを説明すると、Updateで水平方向のキー入力を検知して、animatorのForwardに値をセットしてIdleアニメーションとWalkアニメーションを切り替えています。
また、検知した値が0<x,0>xを判断してTrexを左右どちらに向けるか制御しています。
Trex-PoseManagerスクリプト
PoseManagerは以下のプログラムが記述されており、Pose型のスクリプタブルオブジェクトを保持しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Anima2D { public class PoseManager : MonoBehaviour { [SerializeField][HideInInspector] List<Pose> m_Poses; } } |
Poseクラスの定義は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; namespace Anima2D { public class Pose : ScriptableObject { [Serializable] public class PoseEntry { public string path; public Vector3 localPosition; public Quaternion localRotation; public Vector3 localScale; } [SerializeField] List<PoseEntry> m_PoseEntries; } } |
対応するパスと各パラメーターが定義されています。
この定義でbone位置を記録しています。
※Posesスクリプトの利用方法は別の記事で解説する予定です。
Trex-IkGroup
IKコンポーネントが設定されているGameObjectをまとめて管理しており、
毎フレーム最新の位置情報に更新しています。
以下、プログラムになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Anima2D { public class IkGroup : MonoBehaviour { [SerializeField] [HideInInspector] List<Ik2D> m_IkComponents = new List<Ik2D>(); public void UpdateGroup() { for (int i = 0; i < m_IkComponents.Count; i++) { Ik2D ik = m_IkComponents[i]; if (ik) { ik.enabled = false; ik.UpdateIK(); } } } void LateUpdate() { UpdateGroup(); } } } |
①SpriteMeshes
SpriteMeshesにはTrexを構成するためのSpriteが設定されています。
正確には、各部位毎のGameObjectにSpriteMeshInstanceコンポーネントがアタッチされており
そのコンポーネントにTrexを構成するためのSpriteの設定と対応するBoneのbind設定がされています。
※Anima2Dで必要なSpriteMeshのbind等は別記事で説明します。
②Controls
Controlsは空のGameObjectになっており、子であるControl HipsとControl JawともにControlスクリプトがアタッチされています。
処理は、毎フレームboneの位置を最新の位置に更新しているだけです。
以下、プログラム記載。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using UnityEngine; using System.Collections; namespace Anima2D { public class Control : MonoBehaviour { [SerializeField] Transform m_BoneTransform; public Color color { get { if(m_CachedBone) { Color color = m_CachedBone.color; color.a = 1f; return color; } return Color.white; } } Bone2D m_CachedBone; public Bone2D bone { get { if(m_CachedBone && m_BoneTransform != m_CachedBone.transform) { m_CachedBone = null; } if(!m_CachedBone && m_BoneTransform) { m_CachedBone = m_BoneTransform.GetComponent<Bone2D>(); } return m_CachedBone; } set { m_BoneTransform = value.transform; } } void Start() { } void LateUpdate() { if(bone) { transform.position = bone.transform.position; transform.rotation = bone.transform.rotation; } } } } |
③IKs
IKsは空のGameObjectになっており、子階層にIKコンポーネントがアタッチされてあるObjectを配置しているだけです。
④Hips
Trexの全boneを親子階層で配置しています。
※親子階層にboneを組み立てbindする方法は別に記事を作成する予定です。
Jungle
【編集中】
※編集中の記事はお問い合わせ件数により更新順を優先させていただくことがあります。
この記事、早く!って場合は、以下からお問い合わせください。
今回はざっくり説明しましたので、詳しく知りたい部分がありましたら
お問い合わせから連絡いただけると助かります。
以下、問い合わせ例一覧
- 足一本が動かせるところまでを説明してほしい
- 歩けるようになるまでを説明してほしい
- 背景がループで移動するロジックを説明してほしい
- アニメーションの切り替え方法を詳しく説明してほしい
- Posesスクリプト(スクリプタブルオブジェクト)の説明をしてほしい