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 14:18 編集
2021/11/01 22:05
2021/11/02 12:57