Unityで使用するロボットのモデルを製作しています。
ゲームのイベント(腕を飛ばすなど)に応じてロボットをパーツごとに分離できるようにするため、各パーツを別のオブジェクト(メッシュ)扱いにした上で一つのアーマチュアで操作したいです。
そのためにはどういった機能を使用すればいいですか?
あるいはこの方法以外で上記のゲームシステムを実装する手段はありますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答1件
0
ベストアンサー
「腕を飛ばす」という言葉に興味が湧き、ちょっと調べてみました。
もし主にBlender側の操作方法を知りたいのでしたら、申し訳ないですがBlenderの使用経験がなく不確かなのですが、こちらの解説ムービー(TIP: one armature ruling multiple meshes in Blender)を見た感じですと、一つのアーマチュアに複数のメッシュを関連付けることは可能なように思います。
私の場合は別のソフトで複数のメッシュからなるFBXを作成して(Space Robot Kyleの前腕部と残りの部分を分断して書き出したもの)Unityに持って行きましたが、各メッシュが個別のゲームオブジェクトとして配置され、ボーンの変形に合わせてそれぞれのメッシュがちゃんと変形されていました。
以下はUnity側で動かす際の話で、ちょっと蛇足かもしれません。
腕を飛ばすなど体の一部に独立した動きをさせたい場合、SkinnedMeshRendererでボーンとメッシュが繋がったままだとどうも扱いづらいように感じたので、次のようなアプローチを試してみました。
- 前腕ボーンの階層に、腕の形に合わせたコライダーを持たせた空のゲームオブジェクトを配置する
- 腕を発射するタイミングで、腕メッシュの形状を新規メッシュにベイクし形状を固定
- SkinnedMeshRendererに代わってMeshRendererをアタッチして、これで腕メッシュを描画
- 腕コライダーをボーン階層外に出してモーションに追従させなくする
- 腕メッシュを腕コライダーの階層下に入れて腕コライダーに追従させる
Kyleにアタッチしたスクリプト
C#
1using UnityEngine; 2 3[RequireComponent(typeof(Animator))] 4public class KyleController : MonoBehaviour { 5 public float RocketPunchSpeed; 6 public GameObject ArmObject; // 腕メッシュのオブジェクト(階層上の位置はインポート時のまま) 7 public Rigidbody ArmRigidbody; // 腕のリジッドボディ(ボーン階層の中の前腕部の子として空のゲームオブジェクトを作り、腕の形に合うようにしたコライダーとリジッドボディをアタッチしておく) 8 private SkinnedMeshRenderer armRenderer; 9 private Animator animator; 10 11 private void Start() { 12 this.ArmRigidbody.isKinematic = true; // 初期状態ではArmRigidbodyのisKinematicをオンにしておき、キャラクターのモーションに追従できるようにしておく 13 this.armRenderer = this.ArmObject.GetComponent<SkinnedMeshRenderer>(); 14 this.animator = this.GetComponent<Animator>(); 15 } 16 17 private void Update() { 18 if (Input.GetKeyDown(KeyCode.Space)) 19 { 20 // スペースキー押下でパンチモーションへ遷移 21 this.animator.SetTrigger("PunchTrigger"); 22 } 23 } 24 25 // 腕を伸ばしたタイミングにアニメーションイベントを仕込んでおき、このメソッドを呼ばせる 26 private void RocketPunch() 27 { 28 Debug.Log("Rocket punch!!"); 29 30 // ArmObjectの現在のメッシュの形をベイクし、MeshFilterとMeshRendererをアタッチして描画させる 31 var bakedMesh = new Mesh(); 32 this.armRenderer.BakeMesh(bakedMesh); 33 var bakedMeshFilter = this.ArmObject.AddComponent<MeshFilter>(); 34 bakedMeshFilter.mesh = bakedMesh; 35 var bakedMeshRenderer = this.ArmObject.AddComponent<MeshRenderer>(); 36 bakedMeshRenderer.sharedMaterial = this.armRenderer.sharedMaterial; 37 38 // SkinnedMeshRendererは削除して、本来の腕の位置には描画させないようにする(enabledをオフにするだけでもいいかと思います) 39 Destroy(this.armRenderer); 40 41 // ArmRigidbodyをボーンの階層外(とりあえずルート直下)に移動し、Animatorの制御が及ばないようにする 42 this.ArmRigidbody.gameObject.transform.parent = null; 43 44 // ArmObjectはArmRigidbodyの子に移動させ、ArmRigidbodyの動きに追従するようにする 45 this.ArmObject.transform.parent = this.ArmRigidbody.gameObject.transform; 46 47 // ArmRigidbodyに適当な速度を与える 48 this.ArmRigidbody.velocity = this.transform.forward * RocketPunchSpeed; 49 50 // ArmRigidbodyのisKinematicをオフにし、以降は物理シミュレーションに従って動かす 51 this.ArmRigidbody.isKinematic = false; 52 } 53} 54
投稿2017/09/06 19:30
総合スコア10816
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/09/08 07:12