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

回答編集履歴

2

コード中のコメントを追加

2018/01/11 01:37

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -73,7 +73,7 @@
73
73
  var speed = motion.magnitude;
74
74
  if (speed > 0.25f)
75
75
  {
76
- this.transform.rotation = Quaternion.LookRotation(motion);
76
+ this.transform.rotation = Quaternion.LookRotation(motion); // 入力に対する向き合わせのための回転はプレイヤー操作用原点のTransformを操作する
77
77
  }
78
78
  this.characterController.SimpleMove(motion); // 移動はプレイヤー操作用原点のCharacterControllerを操作する
79
79
  this.PlayerAnimator.SetFloat("Speed", inputMagnitude); // アニメーションはユニティちゃんのAnimatorを操作する

1

修正案を追記

2018/01/11 01:37

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -1,3 +1,88 @@
1
1
  よくあるやり方としては、新しく「GameObject」→「Create Empty」で空のオブジェクトを作り、ユニティちゃんをそのオブジェクトの中に入れ(ヒエラルキー上でユニティちゃんを新しいオブジェクトの子にする)、移動・回転させるときはその新しいオブジェクトの方を操作するという手があるかと思います。
2
2
 
3
- 参考: [UnityでObjectのPivotを変更する - 脳汁portal](http://portaltan.hatenablog.com/entry/2016/04/15/134129)
3
+ 参考: [UnityでObjectのPivotを変更する - 脳汁portal](http://portaltan.hatenablog.com/entry/2016/04/15/134129)
4
+
5
+ ###[追記]
6
+ 下図のような、「プレイヤー操作用原点」→「Z軸周り回転用原点」→「ユニティちゃん」の三重構造にするのはどうでしょう。プレイヤー操作用原点は本来のユニティちゃんと同じく足下に位置するようにして、Z軸周り回転用原点をおヘソの位置に配置する感じです。
7
+
8
+ ![ヒエラルキー](52e3518084589d6ea03cd7c58d241822.gif)
9
+
10
+ 本来のユニティちゃんの原点とプレイヤー操作用原点が一致するようにしておいて、CaracterControllerやプレイヤー制御用スクリプトはプレイヤー操作用原点にアタッチし、Z軸周り回転アクションだけはZ軸周り回転用原点を操作、それ以外はプレイヤー操作用原点を操作するようにすれば、今までの足下原点前提のコードを残したまま回転アクションを加えられるかと思います。
11
+
12
+ 実行時の様子
13
+ ![アクション](5412e245592c07a5e75563dc15ac01ac.gif)
14
+
15
+ ちなみにご参考までに、上図のプレイヤー操作用原点のスクリプトは下記のようになっています。ご質問者さんの設計とは異なる部分が多々あるかと思いますので、あまりお役に立てないかもしれませんが...
16
+
17
+ ```C#
18
+ using System.Collections;
19
+ using System.Linq;
20
+ using UnityEngine;
21
+
22
+ [RequireComponent(typeof(CharacterController))]
23
+ public class PlayerController : MonoBehaviour
24
+ {
25
+ public float MaxSpeed = 5.0f;
26
+ public Animator PlayerAnimator; // ユニティちゃんのAnimator
27
+ public Transform RotationPivot; // Z軸周り回転用原点
28
+ private Transform cameraTransform; // 移動制御のためのカメラのTransform(今回の話題とは直接関係ありません)
29
+ private CharacterController characterController; // プレイヤー操作用原点にアタッチされているCharacterController
30
+ private Coroutine rollingCoroutine;
31
+
32
+ // Z軸周り回転アクション
33
+ private IEnumerator Roll()
34
+ {
35
+ var angle = 0.0f;
36
+ while (angle < 360.0f)
37
+ {
38
+ this.RotationPivot.localEulerAngles = new Vector3(0.0f, 0.0f, angle); // Z軸周り回転はRotationPivotに関して行う
39
+ angle += 30.0f;
40
+ yield return null;
41
+ }
42
+
43
+ this.RotationPivot.localEulerAngles = Vector3.zero;
44
+ this.rollingCoroutine = null;
45
+ }
46
+
47
+ private void Start()
48
+ {
49
+ this.characterController = this.GetComponent<CharacterController>();
50
+ this.cameraTransform = Camera.main.transform;
51
+ if (this.PlayerAnimator == null)
52
+ {
53
+ this.PlayerAnimator = this.GetComponentInChildren<Animator>();
54
+ }
55
+ if (this.RotationPivot == null)
56
+ {
57
+ this.RotationPivot = this.GetComponentsInChildren<Transform>()
58
+ .Where(t => t.name == "RotationPivot")
59
+ .First();
60
+ }
61
+ }
62
+
63
+ private void Update()
64
+ {
65
+ // プレイヤーの移動
66
+ var input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
67
+ var inputMagnitude = Mathf.Clamp01(input.magnitude);
68
+ var right = this.cameraTransform.right;
69
+ var forward = this.cameraTransform.forward;
70
+ forward.y = 0.0f;
71
+ forward.Normalize();
72
+ var motion = ((input.x * right) + (input.y * forward)) * this.MaxSpeed;
73
+ var speed = motion.magnitude;
74
+ if (speed > 0.25f)
75
+ {
76
+ this.transform.rotation = Quaternion.LookRotation(motion);
77
+ }
78
+ this.characterController.SimpleMove(motion); // 移動はプレイヤー操作用原点のCharacterControllerを操作する
79
+ this.PlayerAnimator.SetFloat("Speed", inputMagnitude); // アニメーションはユニティちゃんのAnimatorを操作する
80
+
81
+ // スペースキー押下でZ軸周り回転アクション
82
+ if ((this.rollingCoroutine == null) && Input.GetKeyDown(KeyCode.Space))
83
+ {
84
+ this.rollingCoroutine = this.StartCoroutine(this.Roll());
85
+ }
86
+ }
87
+ }
88
+ ```