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

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

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

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

Unity

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

Q&A

解決済

1回答

1554閲覧

Unityのキャラクターコントローラーを使ってウォールジャンプを作ろうとしましたがうまく動きません。

Mr-WoodMan

総合スコア2

C#

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

Unity

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

0グッド

1クリップ

投稿2021/07/15 14:57

編集2021/07/18 13:51

#概要
UnityでcharacterControllerを使ってFPSのコントローラーを今作っているのですが、ウォールラン中に壁がない方向に飛ぶウォールジャンプの機能がうまくできません。
#コードの説明
Raycastで左か右かにウォールランできる壁があるかどうかを検知、壁が右にある状態でDキー(右移動キー)を押すまたは、壁が左にある状態でAキー(左移動キー)を押すウォールラン開始でウォールラン中は重力を与えないようにしておきます。
その状態でスペースキーを押すと加速度用のvector3のvelocityに値を壁のない方のX方向上のY方向に入れそしてvelocityはMove関数(コードの真ん中らへん)でTime.deltatimeをかけてCharacterControlle.Moveで動かすのですが実際ジャンプしてもX方向にしか動きません。

#検証してことについて
別のスクリプトでDキーを押したら横にCharacterControllerで動く、スペースキーをおしたら上に同じような方法でジャンプする、同じ方法で重力も与えるこの機能のスクリプトをゲームオブジェクトのカプセルにつけてキャラクターコントローラーもつけるこの状態でDを押して移動先にキューブを置いてぶつけるキューブにぶつけてDを押し続けてジャンプすると全く動きません壁キックできないのはこれと一緒の原因何のかなと思いますどう解決したらいいでしょうか?

今のコード

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerAll : MonoBehaviour 6{ 7 float rotaX,rotaZ; 8 float inputCamX, inputCamY; 9 public float sense = 400; 10 public Transform player; // 空のオブジェクトにアタッチ 11 public float friction = -3; 12 13 float inputX, inputY; 14 Vector3 move, velocity; 15 CharacterController controller; 16 bool isGrounded; 17 18 public Transform groundCheck;//playerの子にある空のゲームオブジェクト足元にある 19 public LayerMask groundMask; 20 21 public float groundDistans = 0.4f;//CheckSphere用 22 public float gravity = -9.81f; 23 public float walkSpeed, runSpeed, jumpPower; 24 25 26 bool isWallJump; 27 bool isWallRun, rightWallRun, leftWallRun; 28 public Transform camTrans; //playerの子にあるカメラ 29 public LayerMask wallMask; 30 public float wallDistans = 0.7f;//RayCast用 31 32 public AnimationCurve camShakeCurve;//0から始まり最大1 最小-1 33 public float shakeSpeed; 34 float time = 0; 35 float shakeX, shakeY; 36 37 38 private void Awake() 39 { 40 Cursor.lockState = CursorLockMode.Locked; 41 rotaX = 0.0f; 42 rotaZ = 0.0f; 43 } 44 // Start is called before the first frame update 45 void Start() 46 { 47 controller = GetComponent<CharacterController>(); 48 } 49 50 // Update is called once per frame 51 void Update() 52 { 53 Camangl(); 54 WallRun(); 55 MoveData(); 56 Move(); 57 } 58 59 60 61 62 63 void MoveData() 64 { 65 isGrounded = Physics.CheckSphere(groundCheck.position, groundDistans, groundMask); 66 67 //水平、垂直の値取得 68 inputX = Input.GetAxis("Horizontal"); 69 inputY = Input.GetAxis("Vertical"); 70 71 move = transform.right * inputX + transform.forward * inputY; 72 73 74 //スペースでジャンプ 75 if (Input.GetKey(KeyCode.Space) && isGrounded && !isWallRun) 76 { 77 velocity.y = Mathf.Sqrt(jumpPower * -2 * gravity); 78 } 79 80 81 //壁走りしてなくて床についてなかったら重力を加える 82 if (!isWallRun && !controller.isGrounded) 83 { 84 //壁ジャンプのxの力消し 85 if(velocity.x != 0) 86 { 87 if(velocity.x < 0) 88 velocity.x -= friction * Time.deltaTime; 89 else 90 velocity.x += friction * Time.deltaTime; 91 } 92 93 94 velocity.y += gravity * Time.deltaTime; 95 } 96 //壁走り中は重力ベクトルを消す 97 else if (isWallRun) 98 { 99 velocity.y = 0.0f; 100 } 101 } 102 103 104 105 106 107 void Move() 108 { 109 if (isGrounded && velocity.y < 0) 110 { 111 velocity.x = 0; 112 velocity.y = -6; 113 } 114 115 //シフトキー押して走る 116 if (Input.GetKey(KeyCode.LeftShift)) 117 { 118 if (isGrounded || isWallRun) 119 { 120 CamShake(); 121 } 122 controller.Move(move * runSpeed * Time.deltaTime); 123 } 124 125 //シフトキー押してないときは歩く 126 else 127 { 128 if (isGrounded || isWallRun) 129 { 130 CamShake(); 131 } 132 controller.Move(move * walkSpeed * Time.deltaTime); 133 } 134 135 controller.Move(velocity * Time.deltaTime); 136 } 137 138 //カメラ揺れ 139 void CamShake() 140 { 141 time += Time.deltaTime; 142 143 shakeX = camShakeCurve.Evaluate(time) * Mathf.Abs(shakeSpeed * inputY); 144 shakeY = -camShakeCurve.Evaluate(time) * Mathf.Abs(shakeSpeed * inputY); 145 146 camTrans.localPosition = new Vector3(shakeY, shakeX + 1.5f, 0); 147 148 if (time > 4.0f) 149 time = 0; 150 } 151 152 153 //FPSカメラ 154 private void Camangel() 155 { 156 inputCamX = Input.GetAxis("Mouse X") * sense * Time.deltaTime; 157 inputCamY = Input.GetAxis("Mouse Y") * sense * Time.deltaTime; 158 159 rotaX -= inputCamY; 160 rotaX = Mathf.Clamp(rotaX, -45.3f, 45.3f); 161 162 camTrans.localRotation = Quaternion.Euler(rotaX, 0, rotaZ); 163 camTrans.Rotate(rotaX, 0, rotaZ); 164 165 player.Rotate(0, inputCamX, 0); 166 } 167void WallRun() 168 { 169 //壁があるかどうか 170 leftWallRun = Physics.Raycast(transform.position, -transform.right, wallDistans, wallMask); 171 rightWallRun = Physics.Raycast(transform.position, transform.right, wallDistans, wallMask); 172 173 //右壁走り 174 if (Input.GetKey(KeyCode.D) && rightWallRun) 175 { 176 isWallRun = true; 177 178 179  //カメラ傾き 180 if (camTrans.localEulerAngles.z < 20) 181 { 182 rotaZ += 0.2f; 183 } 184 } 185 186 //左壁走り 187 else if (Input.GetKey(KeyCode.A) && leftWallRun) 188 { 189 isWallRun = true; 190 191 //カメラ傾き 192 if (camTrans.localEulerAngles.z < 10f) 193 rotaZ -= 0.2f; 194 else if (camTrans.localEulerAngles.z > 340) 195 { 196 rotaZ -= 0.2f; 197 } 198 199 //ウォールジャンプ 200 if (Input.GetKey(KeyCode.Space) && !isWallJump) 201 { 202 isWallJump = true; 203 isWallRun = false; 204 velocity.x = 30 * transform.right; 205 velocity.y = 30; 206 } 207 } 208 209 //どっちでもないとき 210 else 211 { 212 isWallJump = false; 213 214 215 //カメラ傾き戻し 216 if(camTrans.localEulerAngles.z > 180 ) 217 { 218 rotaZ += 0.2f; 219 } 220 else if(camTrans.localEulerAngles.z < 180 && camTrans.localEulerAngles.z > 0.2f) 221 { 222 rotaZ -= 0.2f; 223 224 } 225 226 isWallRun = false; 227 } 228 } 229}

補足情報(FW/ツールのバージョンなど)

unity2019.3.9f1personal
visualstudio2019

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

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

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

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

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

guest

回答1

0

自己解決

重力をcharactorcontrollerのMoveで再現してて壁走り中は0にする方法でやってたのですがこれがジャンプ時に発動してました。
なので壁走り中は逆方向に同じ速度で動かしてみたら解決しました。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerAll : MonoBehaviour 6{ 7 8 public float wallJumpMultipleX; 9 public float wallJumpMultipleY; 10 public Camera playerCamera; 11 bool iscleaY; 12 float rotaX,rotaZ; 13 float inputCamX, inputCamY; 14 public float sense = 400; 15 public Transform player; // 空のオブジェクト 16 public float friction = -3; 17 18 float inputX, inputY; 19 Vector3 move, velocity; 20 CharacterController controller; 21 bool isGrounded; 22 23 public Transform groundCheck;//playerの子にある空のゲームオブジェクト足元にある 24 public LayerMask groundMask; 25 26 public float groundDistans = 0.4f;//CheckSphere用 27 public float gravity = -9.81f; 28 public float walkSpeed, runSpeed, jumpPower; 29 30 31 bool isWallJump; 32 bool isWallRun, rightWallRun, leftWallRun; 33 public Transform camTrans; //playerの子にあるカメラ 34 public LayerMask wallMask; 35 public float wallDistans = 0.7f;//RayCast用 36 37 public AnimationCurve camShakeCurve;//0から始まり最大1 最小-1 38 public float shakeSpeed; 39 float time = 0; 40 float shakeX, shakeY; 41 42 43 private void Awake() 44 { 45 Application.targetFrameRate = 60; 46 Cursor.lockState = CursorLockMode.Locked; 47 rotaX = 0.0f; 48 rotaZ = 0.0f; 49 } 50 // Start is called before the first frame update 51 void Start() 52 { 53 controller = GetComponent<CharacterController>(); 54 } 55 56 // Update is called once per frame 57 void Update() 58 { 59 Camangel(); 60 WallRun(); 61 MoveData(); 62 Move(); 63 } 64 65 66 67 68 69 void MoveData() 70 { 71 isGrounded = Physics.CheckSphere(groundCheck.position, groundDistans, groundMask); 72 73 74 75 //水平、垂直の値取得 76 inputY = Input.GetAxis("Vertical"); 77 inputX = Input.GetAxis("Horizontal"); 78 79 80 81 //スペースでジャンプ 82 if (Input.GetKey(KeyCode.Space) && isGrounded && !isWallRun) 83 { 84 velocity.y = Mathf.Sqrt(jumpPower * -2 * gravity); 85 } 86 87 88 89 90 //壁走りしてなくて床についてなかったら重力を加える 91 if (!isWallRun) 92 { 93 94 //壁ジャンプのxの力消し 95 if (velocity.x != 0) 96 { 97 if(velocity.x < 1) 98 velocity.x -= friction * Time.deltaTime; 99 else if(velocity.x > -1) 100 velocity.x += friction * Time.deltaTime; 101 102 } 103 104 if (velocity.z != 0) 105 { 106 if (velocity.z < 1) 107 velocity.z -= friction * Time.deltaTime; 108 else if (velocity.z > -1) 109 velocity.z += friction * Time.deltaTime; 110 } 111 112 velocity.y += gravity * Time.deltaTime; 113 } 114 115 move = transform.right * inputX + transform.forward * inputY; 116 } 117 118 119 120 void Move() 121 { 122 123 if(isGrounded && (velocity.x!=0 || velocity.z != 0)) 124 { 125 velocity.z = 0; 126 velocity.x = 0; 127 } 128 if (isGrounded && velocity.y < 0) 129 { 130 velocity.y = -6; 131 } 132 133 RunAndWalk(); 134 135 } 136 137 138 139 140 141 void WallRun() 142 { 143 //壁があるかどうか 144 leftWallRun = Physics.Raycast(transform.position, -transform.right, wallDistans, wallMask); 145 rightWallRun = Physics.Raycast(transform.position, transform.right, wallDistans, wallMask); 146 147 //右壁走り 148 if (Input.GetKey(KeyCode.D) && rightWallRun) 149 { 150 if (!iscleaY) 151 { 152 iscleaY = true; 153 velocity.y = 0; 154 velocity.x = 0; 155 156 } 157 158 159 isWallRun = true; 160 161 162  //カメラ傾き 163 if (camTrans.localEulerAngles.z < 20) 164 { 165 rotaZ +=2f; 166 } 167 168 if (Input.GetKey(KeyCode.Space) && !isWallJump) 169 { 170 velocity = wallJumpMultipleX * -transform.right; 171 velocity.y = wallJumpMultipleY; 172 isWallJump = true; 173 isWallRun = false; 174 } 175 176 } 177 178 //左壁走り 179 else if (Input.GetKey(KeyCode.A) && leftWallRun) 180 { 181 if (!iscleaY) 182 { 183 iscleaY = true; 184 velocity.y = 0; 185 velocity.x = 0; 186 187 } 188 189 isWallRun = true; 190 191 //カメラ傾き 192 if (camTrans.localEulerAngles.z < 10f) rotaZ -= 2f; 193 else if (camTrans.localEulerAngles.z > 340) rotaZ -= 2f; 194 195 //カメラのFOV切り替え 196 197 198 //ウォールジャンプ 199 if (Input.GetKey(KeyCode.Space) && !isWallJump) 200 { 201 velocity = wallJumpMultipleX * transform.right; 202 velocity.y = wallJumpMultipleY; 203 isWallJump = true; 204 isWallRun = false; 205 } 206 207 } 208 209 //どっちでもないとき 210 else 211 { 212 if (playerCamera.fieldOfView != 80) 213 { 214 playerCamera.fieldOfView -= 2; 215 216 } 217 218 isWallJump = false; 219 220 221 //カメラ傾き戻し 222 if(camTrans.localEulerAngles.z > 180 ) 223 { 224 rotaZ += 2f; 225 } 226 else if(camTrans.localEulerAngles.z < 180 && camTrans.localEulerAngles.z > 0.2f) 227 { 228 rotaZ -= 2f; 229 230 } 231 232 isWallRun = false; 233 234 iscleaY = false; 235 } 236 } 237 238 239 //カメラ揺れ 240 void CamShake() 241 { 242 time += Time.deltaTime; 243 244 shakeX = camShakeCurve.Evaluate(time) * Mathf.Abs(shakeSpeed * inputY); 245 shakeY = -camShakeCurve.Evaluate(time) * Mathf.Abs(shakeSpeed * inputY); 246 247 camTrans.localPosition = new Vector3(shakeY, shakeX + 1f, 0); 248 249 if (time > 4.0f) 250 time = 0; 251 } 252 253 254 //FPSカメラ 255 private void Camangel() 256 { 257 inputCamX = Input.GetAxis("Mouse X") * sense * Time.deltaTime; 258 inputCamY = Input.GetAxis("Mouse Y") * sense * Time.deltaTime; 259 260 rotaX -= inputCamY; 261 262 rotaX = Mathf.Clamp(rotaX, -45.3f, 45.3f); 263 264 camTrans.localRotation = Quaternion.Euler(rotaX, 0, rotaZ); 265 266 camTrans.Rotate(rotaX, 0, rotaZ); 267 268 player.Rotate(0, inputCamX, 0); 269 } 270 271 272 void RunAndWalk() 273 { 274 //シフトキー押して走る 275 if (Input.GetKey(KeyCode.LeftShift)) 276 { 277 if (isGrounded || isWallRun) 278 { 279 280 CamShake(); 281 } 282 controller.Move(move * runSpeed * Time.deltaTime); 283 284 285 286 } 287 288 //シフトキー押してないときは歩く 289 else 290 { 291 if (isGrounded || isWallRun) 292 { 293 CamShake(); 294 } 295 controller.Move(move * walkSpeed * Time.deltaTime); 296 } 297 298 controller.Move(velocity * Time.deltaTime); 299 300 301 } 302}

投稿2021/08/22 12:37

Mr-WoodMan

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問