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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

156閲覧

【Unity3d】ジャンプ中に視点を変えるとプレイヤーの向きも変わってしまう。

masaobloom

総合スコア1

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2025/01/04 13:30

実現したいこと

Unityで3dのアクションゲームを作っていてその中のジャンプを作っているときに起きた問題なのですが
ジャンプ中に視点を変えてしまうと動かしているキャラクターも視点の方向へ進んでしまい、ジャンプの挙動がリアルじゃなくなってしまいました。

試したこと

そこでジャンプ中にrigidbodyのpositionを変えるのではなくジャンプキーを押したときに向いている方向へaddforceさせ、空中ではpositionは変えずキー入力とプレイヤーの向きに応じてAddforceするようにしたところ、視点を変えてもキャラクターの向きは変わらなくなったのですが、思わぬ方向へジャンプしたり空中での移動速度がすごい遅かったりキーが効かなかったり?不具合が起きてしまいました。

該当のソースコード

これがプレイヤーを操作するスクリプトです。

c#

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using Cinemachine; 5using Unity.VisualScripting; 6using UnityEditor; 7using UnityEngine; 8 9public class playerController : MonoBehaviour 10{ 11 public GameObject SavePoint; 12 public float JumpSpeed = 300; 13 public float maxVelocity = 3; 14 Rigidbody rb; 15 16 [Header("Aim")] 17 [SerializeField] AxisState Horizontal; 18 [SerializeField] AxisState Vertical; 19 20 bool jumpKey = false; 21 22 enum PLAYER_STATE{ 23 GROUND = 0, 24 JUMP = 1 25 }; 26 PLAYER_STATE playerState = PLAYER_STATE.GROUND; 27 float timer = 0f; 28 float gravity = 0.5f; 29 float lowerJumpLimit = 0.03f; 30 float receptionTime = 0.1f; 31 float keyreleaseTime = 0f; 32 33 float horizontal, speed, vertical; 34 Vector3 right, forward; 35 36 // Start is called before the first frame update 37 void Awake() 38 { 39 //コンポーネントの取得 40 TryGetComponent(out rb); 41 } 42 43 void Start() { 44 //カーソルを真ん中にロック 45 Cursor.lockState = CursorLockMode.Locked; 46 } 47 48 // Update is called once per frame 49 void Update() 50 { 51 //AxisStateのアップデート 52 Horizontal.Update(Time.deltaTime); 53 Vertical.Update(Time.deltaTime); 54 55 //向きを更新 56 var horizontalAngles = Quaternion.AngleAxis(Horizontal.Value, Vector3.right); 57 var verticalAngles = Quaternion.AngleAxis(Vertical.Value, Vector3.up); 58 transform.rotation = verticalAngles; 59 eye.localRotation = horizontalAngles; 60 61 //Debug.Log(isJump + "spacekey:" + Input.GetKey(KeyCode.Space)); 62 63 if(Input.GetKey(KeyCode.Space)) { 64 jumpKey = true; 65 66 if(playerState == PLAYER_STATE.GROUND) { 67 playerState = PLAYER_STATE.JUMP; 68 69 //ここでスペースキーを押した時のベクトルを加える 70 Vector3 vec = horizontal*speed*right + vertical*speed*forward; 71 vec.y = JumpSpeed; 72 73 rb.AddForce(vec); 74 } 75 } 76 else { 77 if(jumpKey) keyreleaseTime = timer; 78 jumpKey = false; 79 } 80 81 //ゲームオーバー処理 82 if(transform.position.y < SavePoint.transform.position.y - 3) { 83 transform.position = SavePoint.transform.position; 84 } 85 } 86 87 void FixedUpdate() { 88 horizontal = Input.GetAxis("Horizontal"); //A、Dキー 89 vertical = Input.GetAxis("Vertical"); //W、Sキー 90 speed = Input.GetKey(KeyCode.Space) ? 0.2f : 0.1f; 91 92 right = rb.rotation * Vector3.right; 93 forward = rb.rotation * Vector3.forward; 94 95 if(playerState == PLAYER_STATE.GROUND) { 96 rb.position += horizontal * speed * right; 97 rb.position += vertical * speed * forward; 98 } 99 else { 100 //ジャンプ中なら 101 if(Math.Abs(rb.velocity.x) < maxVelocity) { //移動速度が大きすぎないか 102 rb.AddForce(speed*right*horizontal); 103 } 104 if(Math.Abs(rb.velocity.z) < maxVelocity) { //移動速度が大きすぎないか 105 rb.AddForce(speed*forward*vertical); 106 } 107 } 108 109 /* 110 transform.forwardってのは前向きだから transform.rotation*new Vector3(0, 0, 1)で求められる 111 transform.rightも同じようにtransform.rotation*new Vector3(1, 0, 0)でOK 112 */ 113 114 var vec = rb.velocity; 115 if(playerState == PLAYER_STATE.JUMP) { 116 timer += Time.deltaTime; 117 118 if(!jumpKey && timer > lowerJumpLimit && keyreleaseTime < receptionTime) { //小ジャンプの処理 119 timer += Time.deltaTime; 120 if(vec.y > -4) vec.y -= timer*gravity; 121 } 122 } 123 124 rb.velocity = vec; 125 } 126 127 void OnCollisionEnter(Collision col) { 128 rb.velocity = Vector3.zero; 129 playerState = PLAYER_STATE.GROUND; 130 keyreleaseTime = 0f; 131 timer = 0f; 132 } 133} 134

補足

足りない情報があったら教えてください
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

csharp

1 //ジャンプ中なら 2 3 if(Math.Abs(rb.velocity.x) < maxVelocity) { //移動速度が大きすぎないか 4 5 rb.AddForce(speed*right*horizontal); 6 7 } 8 9 if(Math.Abs(rb.velocity.z) < maxVelocity) { //移動速度が大きすぎないか 10 11 rb.AddForce(speed*forward*vertical); 12 13 }

Rigidbody.velocity.z が進行方向を向いている前提で処理していますが、 velocity はワールド座標なので、回転すればその前提が崩れます。
例えば90度回転すれば、 z は0になりますので、どんなに移動速度が上がっても制限がかかりませんね。
相対的な向きに変換する必要があると思います。

csharp

1 Vector3 v = Quaternion.Inverse(rb.rotation) * rb.velocity; 2 if(Math.Abs(v.x) < maxVelocity) { //移動速度が大きすぎないか 3 } 4 if(Math.Abs(v.z) < maxVelocity) { //移動速度が大きすぎないか 5 }

こんな感じかな?と思うけど、自信がないので、あとはご自身で検討してみてください。

投稿2025/01/07 00:02

katsuko

総合スコア3554

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

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

masaobloom

2025/01/07 04:36

ありがとうございます!試してみてまたなにかあったらご相談させていただいてもよろしいでしょうか?
katsuko

2025/01/07 23:32

別に構いませんが、自分は気まぐれで投稿しているので、あまり期待はしないでください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問