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

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

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

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

Q&A

解決済

2回答

801閲覧

地面判定のCollisionはどうあるべきなのか知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

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

0グッド

1クリップ

投稿2019/11/02 05:32

3Dのアクションゲームを作ってるのですが。地面かどうかの足元の当たり判定はどうあるべきなのでしょうか?今は適当に足元にbox collisionを設定してそれをPlayerスクリプトで受け取っている形をとっているのですが。またPlayerではカプセルコライダーを取っています坂道を上るときに突っかかっていて登れないので。ジャンプとかも入れたく真面目に作ろうとすると地面判定はどすればいいのでしょうか?

イメージ説明
プレイヤースクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { const float walk_speed_max = 10.0f; Rigidbody rb; Vector3 move; float input_h; float input_v; Vector3 move_x; Vector3 move_z; public GameObject gGround; ground spt_g; bool isJump; bool isDush; bool isRay; bool isGround = false; float jump_force = 200.0f; float move_speed = walk_speed_max; Animator ani; private Transform StepHit; private RaycastHit downRay; private Transform Hit; private RaycastHit ray; // const float ray_range = 0.3f;//レイを飛ばす距離 const float ray_range = 1.0f;//レイを飛ばす距離 // 昇れる段差 private float stepOffset = 0.3f; //坂道の角度登れる private float slopeLimit = 65f; // 昇れる段差の位置から飛ばすレイの距離 private float slopeDistance = 0.1f; private Vector3 v; // GameObject go = GameObject.Find("GameObject"); private Transform prev; private Vector3 pre_v; private Vector3 pre_dv; void move_step() { //y軸は逆にしてるプラスが下 Debug.DrawLine(StepHit.position, StepHit.position + StepHit.right * ray_range, Color.red); Debug.DrawLine(StepHit.position, StepHit.position + StepHit.forward * ray_range, Color.blue); float s = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); if (move.z != 0 && isGround == true) { if (Physics.Linecast(StepHit.position, StepHit.position + StepHit.forward * ray_range, out ray,LayerMask.GetMask("Slope"))) { //Debug.Log(Vector3.Angle(transform.up, ray.normal)); float angle = Vector3.Angle(transform.up, ray.normal); if ( angle <= slopeLimit) { v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, ray.normal) * transform.forward * s).y, 0f) + transform.forward * s; //前のyの移動量と今の移動量が違う時 move.y += v.y; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } else if (Physics.Linecast(StepHit.position, StepHit.position + StepHit.right * ray_range, out downRay, LayerMask.GetMask("Slope"))) { Debug.Log(Vector3.Angle(transform.up, downRay.normal)); if (Vector3.Angle(transform.up, downRay.normal) <= slopeLimit) { //Debug.Log("下がる"); v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, ray.normal) * new Vector3(0,-1.0f,0) * s).y, 0f) + transform.forward * s; //前のyの移動量と今の移動量が違う時 move.y += v.y; } // Debug.Log("下がるとき"); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } } // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody>(); spt_g = gGround.GetComponent<ground>(); ani = GetComponent<Animator>(); isJump = false; isDush = false; StepHit = transform.Find("StepRay"); } // Update is called once per frame void Update() { float s = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); // Debug.Log(s); //Debug.Log(transform.up); // Debug.Log(transform.right); isGround = spt_g.isGround; Debug.Log(isGround); //input_h = Input.GetAxis("Horizontal"); //input_v = Input.GetAxis("Vertical"); if(Input.GetKey(KeyCode.LeftArrow)) { input_h = -1; }else if (Input.GetKey(KeyCode.RightArrow)) { input_h = 1; } else { input_h = 0; } if (Input.GetKey(KeyCode.UpArrow)) { input_v = 1; } else if (Input.GetKey(KeyCode.DownArrow)) { input_v = -1; } else { input_v = 0; } move_z = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized * input_v; move_x = Camera.main.transform.right * input_h; move = move_x + move_z; move.x *= move_speed; move.z *= move_speed; Debug.Log(move); // Debug.Log(isRay); if (move != Vector3.zero) { transform.rotation = Quaternion.LookRotation(move.normalized); } // /*走る*/ if(Input.GetKey(KeyCode.RightControl)) { isDush = true; move_speed = 15.0f; } else { isDush = false; move_speed = walk_speed_max; } if(Input.GetKey(KeyCode.Space)) { if(isGround == true && isJump == false) { isJump = true; } } move_step(); Animation_Mng(); } /*アニメーション管理*/ void Animation_Mng() { float speed = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); ani.SetFloat("Move_Speed",speed); ani.SetBool("isDush",isDush); //ani.speed = 2; } private void FixedUpdate() { if (isGround == false) { rb.AddForce(new Vector3(0, -30.0f, 0)); rb.velocity = new Vector3(move.x, rb.velocity.y, move.z); } else { rb.velocity = new Vector3(move.x, move.y, move.z); } } private void OnCollisionEnter(Collision c) { //isGround = true; } private void OnCollisionExit(Collision c) { //isGround = false; // Debug.Log("プレイヤーcollision false"); } }

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

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

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

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

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

guest

回答2

0

突然ですがすみません。
僕が前にジャンプのスクリプトを書いたときには、地面にタグ(groundなど?)をつけておき、くっついていたらtrueなどとしておけばいいと思います!
(下手くそな回答ですみません。)

投稿2019/11/02 06:00

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2019/11/02 06:46

>(下手くそな回答ですみません。) そんなことないです!下手くそなんかじゃないですよ!自分に自信持ってください!!
退会済みユーザー

退会済みユーザー

2019/11/02 07:26

ありがとうございます! いつも自分の回答が質問者さんの聞きたいことと一致しているのかとドキドキしていました、、、 これからも頑張ります!
guest

0

ベストアンサー

  • 地面判定にTagを利用する>>Osr28様の回答を参照
  • 足元のColliderをTriggerにする
  • 足元でない部分(側面や頭部)を覆うようにコライダーを別々に設定
  • 足元のColliderを球にする

などの方法があると思います

投稿2019/11/02 06:14

KanazawaKureha

総合スコア368

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

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

退会済みユーザー

退会済みユーザー

2019/11/02 06:19

Kureha413様のように、プレイヤーオブジェクトの子に子ライダーとジャンプをコントロールするスクリプトをアタッチしてみたらどうですか?
退会済みユーザー

退会済みユーザー

2019/11/02 06:28

質問ですがコライダーを別々とは自分が前質問した空の子のオブジェクトにコライダーを設定するという行為でしょうか? 質問2ジャンプを操作するスクリプトはプレイヤーでほかの操作と一括して行るのと別のスクリプトとどうちがのでしょうか?
退会済みユーザー

退会済みユーザー

2019/11/02 06:34

失礼します。 質問1=そうです。子のオブジェクトを作ってそこにコライダーコンポーネントをつけてください。(足元?) 質問2=一括して行っても良いですが、アニメーションを制御する場合は親に移動スクリプトをアタッチして子のコライダーが付いている方にジャンプのスクリプトをつけたほうがいいということです。
退会済みユーザー

退会済みユーザー

2019/11/02 06:37

また質問3になりますが。子の空のオブジェクトではOnTriggerStayを使って地面についているときはtrue Exitした時はfalseにしてるのですがCollsiionが使えないためこれでいいのでしょうか?
退会済みユーザー

退会済みユーザー

2019/11/02 06:40

多分いいと思いますが、タグで判定しないと他のについたときにもtrueになってしまうので、ちゃんとifで囲っておいたほうがいいと思います! (わかりにくい説明で、しかもスクリプトもついていなくてすみません!)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問