実現したいこと
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
補足
足りない情報があったら教えてください
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/01/07 04:36
2025/01/07 23:32