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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Unity3D

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

Unity

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

Q&A

解決済

1回答

6611閲覧

Unity:プレイヤーがterrainをすり抜けてしまい しかもカメラもブレる

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2019/04/05 10:56

編集2019/04/06 23:37

Unity3Dでゲームを作っています

ちょうどプレイヤーの操作やカメラ操作が出来上がってきたので 最近terrainを使って地形を作っているのですが
下るときにカメラがブレたりプレイヤーが地形をすり抜けてしまいます

動画で説明した方が早いと思うので YouTubeにあげておきました https://youtu.be/-OoGGfgsopY
こんな感じです
恐らくCharacterControllerやRigitbodyが関係していると思います
ので プレイヤーのインスペクターの画像を置いておきます
イメージ説明
こんな感じです
Rigitbodyはプレイヤーの子オブジェクトであるボーンにつけています

まだUnity初心者なので挙げるべき画像をあげていないかもしれません 不備がありましたらご指摘ください

どなたか分かる方教えて下さい

バージョン

Unity 2018.3.11f1

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

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

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

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

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

Bongo

2019/04/07 04:51

上り坂は問題なさそうなのに下り坂はおかしくなっていますね... PlayerControllerがどうなっているか気になるのですが、コードをご提示いただけるでしょうか?
退会済みユーザー

退会済みユーザー

2019/04/07 13:18 編集

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class PlayerController : MonoBehaviour { float InputHorizontal; float InputVertical; public float MoveSpeed_1 = 2.0f; public float MoveSpeed_2 = 1.0f; public float RotateSpeed = 700.0f; public float gravity = 9.0f; //Animatorを入れる Animator PlayerAnimator; //Rigidbodyを入れる CharacterController PlayerCharacon; //CameraControllerコンポーネントを入れる GameObject CameraCon; Vector3 cameraForward; Vector3 moveForward; // Start is called before the first frame update void Start() { PlayerAnimator = GetComponent<Animator>(); PlayerCharacon = GetComponent<CharacterController>(); CameraCon = GameObject.Find("CameraController"); } // Update is called once per frame void Update() { InputHorizontal = Input.GetAxis("Vertical2"); InputVertical = Input.GetAxis("Horizontal2"); // カメラの方向から、X-Z平面の単位ベクトルを取得 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; // 方向キーの入力値とカメラの向きから、移動方向を決定 moveForward = cameraForward * InputVertical + Camera.main.transform.right * InputHorizontal; if (CheckGrouded()) { if (InputHorizontal == 0 && InputVertical == 0 && !(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) { PlayerAnimator.SetBool("ReadyForBullet", false); PlayerAnimator.SetBool("Run", false); PlayerAnimator.SetBool("Idle", true); } else if (Input.GetKey((KeyCode)KeyCode.Joystick2Button14)) { PlayerAnimator.SetBool("Idle", false); PlayerAnimator.SetBool("Run", false); PlayerAnimator.SetBool("ReadyForBullet", true); PlayerAnimator.SetFloat("X", InputHorizontal); PlayerAnimator.SetFloat("Z", InputVertical); Move_2(moveForward); } else if (!(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) { PlayerAnimator.SetBool("Idle", false); PlayerAnimator.SetBool("ReadyForBullet", false); PlayerAnimator.SetBool("Run", true); //走ってる中はカメラの角度リセット出来ないようにする CameraCon.GetComponent<CameraController>().CameraSet = false; ChangeDirection(moveForward); Move_1(moveForward); } } else { transform.position = new Vector3(transform.position.x,transform.position.y - gravity * Time.deltaTime,transform.position.z); } //落ちたら戻る(多分テスト用) if (transform.position.y < -20) { transform.position = new Vector3(4, 1, 0); } } //移動する関数(早く移動する) void Move_1(Vector3 DistanceToMove) { PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_1); } //(遅い) void Move_2(Vector3 DistanceToMove) { PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_2); } //向きを変える関数 void ChangeDirection(Vector3 DirectionToTurn) { //向きたい方角をQuaternion型に直す Quaternion HogeQ = Quaternion.LookRotation(DirectionToTurn); //向きをHogeQに向けてじわ~っと変化させる transform.rotation = Quaternion.RotateTowards(transform.rotation, HogeQ, RotateSpeed * Time.deltaTime); } public bool CheckGrouded() { if (PlayerCharacon.isGrounded) return true; //放つ光線の初期位置と姿勢 //若干身体にめり込ませた位置から発射しないと正しく判定できない時がある var ray = new Ray(this.transform.position + Vector3.up * 0.1f, Vector3.down); //探索距離 var tolerance = 0.25f; //Raycastがhitするかどうかで判定 //地面にのみ衝突するようにレイヤを指定する return Physics.Raycast(ray, tolerance); } // 衝突が合った際に呼ばれる void OnControllerColliderHit(ControllerColliderHit hit) { if (hit.gameObject.tag == "Stopper" && Input.GetKey((KeyCode)KeyCode.Joystick1Button0)) { SceneManager.LoadScene("HuntScene"); } } }
退会済みユーザー

退会済みユーザー

2019/04/07 13:18

そのまんまコピーしてるので分からないところがおっしゃってください コントローラーはSwitchのJoy-Conです
guest

回答1

0

ベストアンサー

もしかすると、落下処理の部分でtransform.positionを直接操作して移動させているのが接触判定の妨げになっているのかもしれません。
CharacterController.Moveのサンプルコードでは、重力によるY方向移動もMoveの引数ベクトルに組み込んでいるようです。それにならって、下記のように改変してみましたがどうでしょうか?

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5 6public class PlayerController4 : MonoBehaviour 7{ 8 float InputHorizontal; 9 float InputVertical; 10 11 public float MoveSpeed_1 = 2.0f; 12 public float MoveSpeed_2 = 1.0f; 13 public float RotateSpeed = 700.0f; 14 public float gravity = 9.0f; 15 16 //Animatorを入れる 17 Animator PlayerAnimator; 18 19 //Rigidbodyを入れる 20 CharacterController PlayerCharacon; 21 22 //CameraControllerコンポーネントを入れる 23 GameObject CameraCon; 24 25 Vector3 cameraForward; 26 Vector3 moveForward; 27 28 // Start is called before the first frame update 29 void Start() 30 { 31 PlayerAnimator = GetComponent<Animator>(); 32 PlayerCharacon = GetComponent<CharacterController>(); 33 CameraCon = GameObject.Find("CameraController"); 34 } 35 36 // Update is called once per frame 37 void Update() 38 { 39 InputHorizontal = Input.GetAxis("Horizontal"); 40 InputVertical = Input.GetAxis("Vertical"); 41 42 // カメラの方向から、X-Z平面の単位ベクトルを取得 43 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; 44 45 // 方向キーの入力値とカメラの向きから、移動方向を決定 46 moveForward = cameraForward * InputVertical + Camera.main.transform.right * InputHorizontal; 47 48 if (CheckGrouded()) 49 { 50 if (InputHorizontal == 0 && InputVertical == 0 && !(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) 51 { 52 PlayerAnimator.SetBool("ReadyForBullet", false); 53 PlayerAnimator.SetBool("Run", false); 54 PlayerAnimator.SetBool("Idle", true); 55 } 56 else if (Input.GetKey((KeyCode)KeyCode.Joystick2Button14)) 57 { 58 PlayerAnimator.SetBool("Idle", false); 59 PlayerAnimator.SetBool("Run", false); 60 PlayerAnimator.SetBool("ReadyForBullet", true); 61 62 PlayerAnimator.SetFloat("X", InputHorizontal); 63 PlayerAnimator.SetFloat("Z", InputVertical); 64 65 // Move_2の代わりに、moveForwardにスピードをかけるだけにする 66 moveForward *= this.MoveSpeed_2; 67 } 68 else if (!(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) 69 { 70 PlayerAnimator.SetBool("Idle", false); 71 PlayerAnimator.SetBool("ReadyForBullet", false); 72 PlayerAnimator.SetBool("Run", true); 73 74 //走ってる中はカメラの角度リセット出来ないようにする 75 CameraCon.GetComponent<CameraController>().CameraSet = false; 76 77 ChangeDirection(moveForward); 78 79 // Move_1の代わりに、moveForwardにスピードをかけるだけにする 80 moveForward *= this.MoveSpeed_1; 81 } 82 } 83 else 84 { 85 moveForward = Vector3.zero; 86 } 87 88 // 上記の接地判定ブロックの後で、落下効果も含めて移動させる 89 PlayerCharacon.Move(new Vector3(moveForward.x, -gravity, moveForward.z) * Time.deltaTime); 90 91 //落ちたら戻る(多分テスト用) 92 if (transform.position.y < -20) 93 { 94 transform.position = new Vector3(4, 1, 0); 95 } 96 } 97 98 //移動する関数(早く移動する) 99 /* 100 void Move_1(Vector3 DistanceToMove) 101 { 102 PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_1); 103 } 104 */ 105 //(遅い) 106 /* 107 void Move_2(Vector3 DistanceToMove) 108 { 109 PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_2); 110 } 111 */ 112 113 //向きを変える関数 114 void ChangeDirection(Vector3 DirectionToTurn) 115 { 116 //向きたい方角をQuaternion型に直す 117 Quaternion HogeQ = Quaternion.LookRotation(DirectionToTurn); 118 119 //向きをHogeQに向けてじわ~っと変化させる 120 transform.rotation = Quaternion.RotateTowards(transform.rotation, HogeQ, RotateSpeed * Time.deltaTime); 121 } 122 123 public bool CheckGrouded() 124 { 125 if (PlayerCharacon.isGrounded) return true; 126 127 //放つ光線の初期位置と姿勢 128 //若干身体にめり込ませた位置から発射しないと正しく判定できない時がある 129 130 var ray = new Ray(this.transform.position + Vector3.up * 0.1f, Vector3.down); 131 //探索距離 132 var tolerance = 0.25f; 133 //Raycastがhitするかどうかで判定 134 //地面にのみ衝突するようにレイヤを指定する 135 return Physics.Raycast(ray, tolerance); 136 } 137 138 // 衝突が合った際に呼ばれる 139 void OnControllerColliderHit(ControllerColliderHit hit) 140 { 141 if (hit.gameObject.tag == "Stopper" && Input.GetKey((KeyCode)KeyCode.Joystick1Button0)) 142 { 143 SceneManager.LoadScene("HuntScene"); 144 } 145 } 146}

蛇足かもしれませんが、落下の動きが「-9m/s^2の等加速度運動」ではなく「-9m/sの等速度運動」になっていたようです。
ゲームデザインによるかと思いますが、もし常に一定の速さで落下するのではなく、時間経過とともに下へ加速しながら落下する方が望ましいようでしたら、一例としてさらに下記のように変更してみる手があるでしょう(もし今後ジャンプ機能を追加する予定でしたら、おそらく等速度落下よりも等加速度落下の方がそれっぽい動きにしやすいんじゃないかと思います)。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5 6public class PlayerController : MonoBehaviour 7{ 8 9 float InputHorizontal; 10 float InputVertical; 11 12 public float MoveSpeed_1 = 2.0f; 13 public float MoveSpeed_2 = 1.0f; 14 public float RotateSpeed = 700.0f; 15 public float gravity = 9.0f; 16 17 //Animatorを入れる 18 Animator PlayerAnimator; 19 20 //Rigidbodyを入れる 21 CharacterController PlayerCharacon; 22 23 //CameraControllerコンポーネントを入れる 24 GameObject CameraCon; 25 26 Vector3 cameraForward; 27 Vector3 moveForward; 28 29 // Y方向速度を追加 30 float velocityY; 31 32 // Start is called before the first frame update 33 void Start() 34 { 35 PlayerAnimator = GetComponent<Animator>(); 36 PlayerCharacon = GetComponent<CharacterController>(); 37 CameraCon = GameObject.Find("CameraController"); 38 } 39 40 // Update is called once per frame 41 void Update() 42 { 43 InputHorizontal = Input.GetAxis("Horizontal"); 44 InputVertical = Input.GetAxis("Vertical"); 45 46 // カメラの方向から、X-Z平面の単位ベクトルを取得 47 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; 48 49 // 方向キーの入力値とカメラの向きから、移動方向を決定 50 moveForward = cameraForward * InputVertical + Camera.main.transform.right * InputHorizontal; 51 52 if (CheckGrouded()) 53 { 54 // 接地状態の場合、velocityYを0にリセットする 55 velocityY = 0.0f; 56 57 if (InputHorizontal == 0 && InputVertical == 0 && !(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) 58 { 59 PlayerAnimator.SetBool("ReadyForBullet", false); 60 PlayerAnimator.SetBool("Run", false); 61 PlayerAnimator.SetBool("Idle", true); 62 } 63 else if (Input.GetKey((KeyCode)KeyCode.Joystick2Button14)) 64 { 65 PlayerAnimator.SetBool("Idle", false); 66 PlayerAnimator.SetBool("Run", false); 67 PlayerAnimator.SetBool("ReadyForBullet", true); 68 69 PlayerAnimator.SetFloat("X", InputHorizontal); 70 PlayerAnimator.SetFloat("Z", InputVertical); 71 72 moveForward *= this.MoveSpeed_2; 73 } 74 else if (!(Input.GetKey((KeyCode)KeyCode.Joystick2Button14))) 75 { 76 PlayerAnimator.SetBool("Idle", false); 77 PlayerAnimator.SetBool("ReadyForBullet", false); 78 PlayerAnimator.SetBool("Run", true); 79 80 //走ってる中はカメラの角度リセット出来ないようにする 81 CameraCon.GetComponent<CameraController>().CameraSet = false; 82 83 ChangeDirection(moveForward); 84 moveForward *= this.MoveSpeed_1; 85 } 86 } 87 else 88 { 89 moveForward = Vector3.zero; 90 } 91 92 // velocityYを重力の分だけ減らし、それをMove引数のY成分とする 93 velocityY -= gravity * Time.deltaTime; 94 PlayerCharacon.Move(new Vector3(moveForward.x, velocityY, moveForward.z) * Time.deltaTime); 95 96 //落ちたら戻る(多分テスト用) 97 if (transform.position.y < -20) 98 { 99 transform.position = new Vector3(4, 1, 0); 100 } 101 } 102 103 //移動する関数(早く移動する) 104 /* 105 void Move_1(Vector3 DistanceToMove) 106 { 107 PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_1); 108 } 109 */ 110 //(遅い) 111 /* 112 void Move_2(Vector3 DistanceToMove) 113 { 114 PlayerCharacon.Move(DistanceToMove * Time.deltaTime * MoveSpeed_2); 115 } 116 */ 117 118 //向きを変える関数 119 void ChangeDirection(Vector3 DirectionToTurn) 120 { 121 //向きたい方角をQuaternion型に直す 122 Quaternion HogeQ = Quaternion.LookRotation(DirectionToTurn); 123 124 //向きをHogeQに向けてじわ~っと変化させる 125 transform.rotation = Quaternion.RotateTowards(transform.rotation, HogeQ, RotateSpeed * Time.deltaTime); 126 } 127 128 public bool CheckGrouded() 129 { 130 if (PlayerCharacon.isGrounded) return true; 131 132 //放つ光線の初期位置と姿勢 133 //若干身体にめり込ませた位置から発射しないと正しく判定できない時がある 134 135 var ray = new Ray(this.transform.position + Vector3.up * 0.1f, Vector3.down); 136 //探索距離 137 var tolerance = 0.25f; 138 //Raycastがhitするかどうかで判定 139 //地面にのみ衝突するようにレイヤを指定する 140 return Physics.Raycast(ray, tolerance); 141 } 142 143 // 衝突が合った際に呼ばれる 144 void OnControllerColliderHit(ControllerColliderHit hit) 145 { 146 if (hit.gameObject.tag == "Stopper" && Input.GetKey((KeyCode)KeyCode.Joystick1Button0)) 147 { 148 SceneManager.LoadScene("HuntScene"); 149 } 150 } 151}

投稿2019/04/07 21:38

編集2019/04/07 23:18
Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2019/04/08 09:52

無事、無事バグを直すことが出来ました! 本当にありがとうございました!僕一人ではどうにも出来ませんでした! 本当に本当に感謝します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問