質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

4327閲覧

UnityのAnimationをスクリプトから上書きしたい(例:腰をひねる)

moyashi1

総合スコア6

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/10/31 13:22

編集2021/11/01 01:43

前提・実現したいこと

アセットストアにてアニメーションを購入しました。
銃を構えているアニメーションです。

腰を左右に捻ることで、銃口の向きを制御したいと考えています。
IK等いろいろな方法を検討しましたが、Animationウィンドウの「Animator.Chest Twist Left-Right」の値を変更するのが、最も綺麗に実現できそうだと考えました。

しかし、Animatorのパラメーターにアクセスする方法がわかりません。
変更したいパラメーター

どのようなスクリプトを書けば、ここを上書きできますか?
ご存じの方ご教示ください。

該当のソースコード

C#

1// ※実際には動かなかったのですが、下記のように指定できる関数があればなぁと思ってます 2 3// 左を向く 4animator.SetFloat("Animator.Chest Twist Left-Right", -1f); 5 6// 右を向く 7animator.SetFloat("Animator.Chest Twist Left-Right", 1f);

試したこと

  • 該当のソースコードは実行してみました。
  • ちょっと書き換えたバージョンもいくつか試しました。

C#

1// Animator.を消してみる 2animator.SetFloat("Chest Twist Left-Right", -1f); 3// スペースを消してみる 4animator.SetFloat("Animator.ChestTwistLeft-Right", 1f); 5// Animator.とスペースを消してみる 6animator.SetFloat("ChestTwistLeft-Right", 1f);

補足情報(FW/ツールのバージョンなど)

Unity 2020.3.20f1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

AnimatorのSet系メソッドはAnimator Controller上で定義したパラメーターを設定するためのものでしょうから、さらにその中で再生されているAnimationClipのプロパティにまでアクセスすることはできないんじゃないでしょうかね...

私がそのような銃口のコントロールをやるとしたら、おそらくbboydaisukeさんがおっしゃるようにIK機能を利用するように思います。ですがキャラクターのマッスルを直接操作した方が好都合な場合があるかもしれません。
代替案として、HumanPoseHandlerで姿勢を修正するのはどうでしょうか?
試しに下記スクリプトをキャラクターにアタッチしたところ...

lang

1using UnityEngine; 2 3[RequireComponent(typeof(Animator))] 4public class PoseModifier : MonoBehaviour 5{ 6 [SerializeField][Range(-1.0f, 1.0f)] private float spineFrontBack; 7 [SerializeField][Range(-1.0f, 1.0f)] private float chestTwistLeftRight; 8 [SerializeField][Range(-1.0f, 1.0f)] private float headNodDownUp; 9 private HumanPoseHandler poseHandler; 10 11 // あらかじめHumanPoseHandlerを取得しておく 12 private void OnEnable() 13 { 14 this.poseHandler = new HumanPoseHandler(this.GetComponent<Animator>().avatar, this.transform); 15 } 16 17 // HumanPoseHandlerが不要になったら破棄する 18 private void OnDisable() 19 { 20 this.poseHandler.Dispose(); 21 } 22 23 private void LateUpdate() 24 { 25 // ポーズを取得して... 26 var t = this.transform; 27 var rootPosition = t.position; 28 var rootRotation = t.rotation; 29 t.SetPositionAndRotation(Vector3.zero, Quaternion.identity); 30 var pose = new HumanPose(); 31 this.poseHandler.GetHumanPose(ref pose); 32 t.SetPositionAndRotation(rootPosition, rootRotation); 33 34 // マッスル値を修正する 35 pose.muscles[0] += this.spineFrontBack; 36 pose.muscles[5] += this.chestTwistLeftRight; 37 pose.muscles[12] += this.headNodDownUp; 38 39 // 修正したポーズを設定する 40 this.poseHandler.SetHumanPose(ref pose); 41 } 42 43 // 各マッスルが何番なのかは、HumanTraitを見てみるのがいいかと思います 44 private void Start() 45 { 46 var muscleNames = HumanTrait.MuscleName; 47 for (var i = 0; i < HumanTrait.MuscleCount; i++) 48 { 49 Debug.Log($"Muscle {i}:[{muscleNames[i]}]"); 50 } 51 } 52}

下図のような結果になりました。

図

##上半身・下半身同時ひねり問題への対策

lang

1using UnityEngine; 2 3[RequireComponent(typeof(Animator))] 4public class PoseModifier : MonoBehaviour 5{ 6 [SerializeField][Range(-1.0f, 1.0f)] private float spineFrontBack; 7 [SerializeField][Range(-1.0f, 1.0f)] private float chestTwistLeftRight; 8 [SerializeField][Range(-1.0f, 1.0f)] private float headNodDownUp; 9 private HumanPoseHandler poseHandler; 10 private Transform hips; 11 12 private void OnEnable() 13 { 14 var animator = this.GetComponent<Animator>(); 15 this.poseHandler = new HumanPoseHandler(animator.avatar, this.transform); 16 17 // Hipsに相当するボーンを取得しておく 18 this.hips = animator.GetBoneTransform(HumanBodyBones.Hips); 19 } 20 21 private void OnDisable() 22 { 23 this.poseHandler.Dispose(); 24 } 25 26 private void LateUpdate() 27 { 28 // ポーズ修正を加える前に、あらかじめHipsの回転を覚えておく 29 var hipsRotation = this.hips.rotation; 30 31 // ポーズ修正部分は変更なし 32 var t = this.transform; 33 var rootPosition = t.position; 34 var rootRotation = t.rotation; 35 t.SetPositionAndRotation(Vector3.zero, Quaternion.identity); 36 var pose = new HumanPose(); 37 this.poseHandler.GetHumanPose(ref pose); 38 t.SetPositionAndRotation(rootPosition, rootRotation); 39 pose.muscles[0] += this.spineFrontBack; 40 pose.muscles[5] += this.chestTwistLeftRight; 41 pose.muscles[12] += this.headNodDownUp; 42 this.poseHandler.SetHumanPose(ref pose); 43 44 // マッスル値設定によるポーズ修正を加えた後、 45 // Hipsの回転を元に戻す 46 this.hips.rotation = hipsRotation; 47 } 48 49 private void Start() 50 { 51 var muscleNames = HumanTrait.MuscleName; 52 for (var i = 0; i < HumanTrait.MuscleCount; i++) 53 { 54 Debug.Log($"Muscle {i}:[{muscleNames[i]}]"); 55 } 56 } 57}

投稿2021/11/01 12:02

編集2021/11/01 22:04
Bongo

総合スコア10811

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moyashi1

2021/11/01 14:18 編集

まさしく探していた情報です、ありがとうございます! 添付いただいたgifでもそうですが、上半身をひねると下半身も同じだけ逆方向に捻られてしまうようです。 これを上半身だけに適用する方法はありますか? 今から今回教えていただいたマッスル制御を勉強してみるので自己解決目指しますが もしご存知でしたらご教示いただけますと幸いですm(__)m ※上半身だけ捻って狙いをつけるイメージだったので、足から下は動かしたくない
Bongo

2021/11/01 22:05

Hipsの姿勢を元のまま維持させる...というのはどうでしょうかね?回答欄に追記しました。 すみませんが即興の思いつきですので、不具合を見落としているかもしれません。変な挙動を見つけましたらコメントいただければ、可能であれば直してみようと思います。
moyashi1

2021/11/02 12:57

たったいま帰宅して動かしてみました。 めちゃいい感じです!! おかげさまでイメージ通りの処理を実装できました。 また質問させていただいた際は是非回答お願いします。 ※ 腰をひねると、ごくわずかに位置がずれる問題が発生していたのですが、 HipsのRotation同様Positionも維持するように修正したところ解消しました。
guest

0

アニメーション クリップ(.anim ファイル)はアセットなので実行中に上書きはできません。IK を使いましょう。

投稿2021/11/01 01:28

bboydaisuke

総合スコア5308

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moyashi1

2021/11/01 01:29

ご回答ありがとうございます! animファイル自体は編集しないにしても、 Animator側の、実行時の値だけ変更することはできませんか?
bboydaisuke

2021/11/01 01:30

もしくはアバターマスク+レイヤーでもいいでしょう。アバターマスク レイヤー とか、 Unity 上半身だけ動かす とかでググればいろいろ出てきます。
bboydaisuke

2021/11/01 01:31

> Animator側の、実行時の値だけ変更することはできませんか? 何を表現しているかよくわかりませんが、そういうことはしません。
moyashi1

2021/11/01 01:34

ありがとうございます。 IKやアバターマスクの方法は認識しています。 >> Animator側の、実行時の値だけ変更することはできませんか? >何を表現しているかよくわかりませんが、そういうことはしません。 パラメータであれば animator.SetFloat("パラメータ名", 0.5f); といった形で設定できますよね。 同じように animator.関数("Chest Twistt Left-Right", -1f); とすると、左を向いてくれると嬉しいのですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問