teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

急激な振り向きを避けるための改善案を追記

2019/03/19 21:20

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -31,4 +31,53 @@
31
31
  }
32
32
  }
33
33
  }
34
+ ```
35
+
36
+ ※おまけ
37
+ ターゲットがキャラクターの背後を横切るときなどには、首が一瞬で逆向きに回るのが気に入らないかもしれません。
38
+ 一案としては、[Quaternion.Slerp](https://docs.unity3d.com/ja/current/ScriptReference/Quaternion.Slerp.html)で回転を混ぜ合わせて動きを緩和する手があるかと思います。
39
+ ```C#
40
+ using System.Collections;
41
+ using System.Collections.Generic;
42
+ using UnityEngine;
43
+
44
+ public class LookAtMe : MonoBehaviour
45
+ {
46
+ public Transform neckBone;
47
+ public GameObject watchTarget;
48
+ public float _plusRotationY;//Inspector上で-90
49
+ public float _plusRotationZ;//Inspector上で-90
50
+ public float _maxAngle = 60;
51
+ public float _smoothingFactor = 6;
52
+
53
+ private Quaternion previousRotation;
54
+
55
+ protected virtual void LateUpdate()
56
+ {
57
+ if (neckBone != null)
58
+ {
59
+ if (watchTarget != null)
60
+ {
61
+ // 制限なしの回転を求め...
62
+ var rotation = Quaternion.LookRotation(watchTarget.transform.position - neckBone.position);
63
+
64
+ // その回転角を_maxAngleまでに制限し...
65
+ rotation = Quaternion.RotateTowards(Quaternion.identity, rotation, _maxAngle);
66
+
67
+ // 軸合わせを行い...
68
+ rotation *= Quaternion.Euler(0, _plusRotationY, _plusRotationZ);
69
+
70
+ // Slerpで前回の回転とブレンドし、previousRotationにセットし...
71
+ previousRotation = Quaternion.Slerp(previousRotation, rotation, Time.deltaTime * _smoothingFactor);
72
+
73
+ // その回転を首のrotationとする
74
+ neckBone.transform.rotation = previousRotation;
75
+
76
+ // 首の回転がアニメーションにより制御されている場合、それによって回転が毎回更新されてしまうはずなので
77
+ // 下記のようにやったのでは、なめらかに回ってくれないかもしれません
78
+ // neckBone.transform.rotation = Quaternion.Lerp(neckBone.transform.rotation, rotation, Time.deltaTime);
79
+ }
80
+ }
81
+ }
82
+ }
34
83
  ```