Quaternion.RotateTowardsを使ってみるのはどうでしょう。
このメソッドは回転アニメーションの製作例で見かけることが多いかと思いますが、回転量を制限する機能に注目して、こんな使い方をしてもいいんじゃないかと思います。
C#
1using System.Collections;
2using System.Collections.Generic;
3using UnityEngine;
4
5public class LookAtMe : MonoBehaviour
6{
7 public Transform neckBone;
8 public GameObject watchTarget;
9 public float _plusRotationY;//Inspector上で-90
10 public float _plusRotationZ;//Inspector上で-90
11 public float _maxAngle = 60;
12
13 protected virtual void LateUpdate()
14 {
15 if (neckBone != null)
16 {
17 if (watchTarget != null)
18 {
19 // 制限なしの回転を求め...
20 var rotation = Quaternion.LookRotation(watchTarget.transform.position - neckBone.position);
21
22 // その回転角を_maxAngleまでに制限した回転を作り、それをrotationにセットする
23 neckBone.transform.rotation = Quaternion.RotateTowards(Quaternion.identity, rotation, _maxAngle);
24
25 neckBone.Rotate(0, _plusRotationY, _plusRotationZ);//回転値をプラスして補間
26 }
27 }
28 }
29}
※おまけ
ターゲットがキャラクターの背後を横切るときなどには、首が一瞬で逆向きに回るのが気に入らないかもしれません。
一案としては、Quaternion.Slerpで回転を混ぜ合わせて動きを緩和する手があるかと思います。
C#
1using System.Collections;
2using System.Collections.Generic;
3using UnityEngine;
4
5public class LookAtMe : MonoBehaviour
6{
7 public Transform neckBone;
8 public GameObject watchTarget;
9 public float _plusRotationY;//Inspector上で-90
10 public float _plusRotationZ;//Inspector上で-90
11 public float _maxAngle = 60;
12 public float _smoothingFactor = 6;
13
14 private Quaternion previousRotation;
15
16 protected virtual void LateUpdate()
17 {
18 if (neckBone != null)
19 {
20 if (watchTarget != null)
21 {
22 // 制限なしの回転を求め...
23 var rotation = Quaternion.LookRotation(watchTarget.transform.position - neckBone.position);
24
25 // その回転角を_maxAngleまでに制限し...
26 rotation = Quaternion.RotateTowards(Quaternion.identity, rotation, _maxAngle);
27
28 // 軸合わせを行い...
29 rotation *= Quaternion.Euler(0, _plusRotationY, _plusRotationZ);
30
31 // Slerpで前回の回転とブレンドし、previousRotationにセットし...
32 previousRotation = Quaternion.Slerp(previousRotation, rotation, Time.deltaTime * _smoothingFactor);
33
34 // その回転を首のrotationとする
35 neckBone.transform.rotation = previousRotation;
36
37 // 首の回転がアニメーションにより制御されている場合、それによって回転が毎回更新されてしまうはずなので
38 // 下記のようにやったのでは、なめらかに回ってくれないかもしれません
39 // neckBone.transform.rotation = Quaternion.Lerp(neckBone.transform.rotation, rotation, Time.deltaTime);
40 }
41 }
42 }
43}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/20 12:29