Unity 3D角色地面检测问题:isOnGround始终为false
Unity碰撞检测无法识别角色是否在地面的问题
正在制作一款简单的移动射击游戏,目前遇到阻碍开发进度的问题——Collider无法检测到角色处于地面上。已为地面添加Mesh Collider,为角色添加Cylinder Collider,但isOnGround始终为false,尝试多种OnCollision相关方法均未解决。
问题代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Movement : MonoBehaviour { public float speed = 10; public float forward; public float right; private int jumpcount; public bool isOnGround; bool isAlive; Rigidbody player; // Start is called before the first frame update void Start() { isAlive = true; player = GetComponent<Rigidbody>(); } // Update is called once per frame void Update() { movement(); if (Input.GetKeyDown(KeyCode.Space) && isOnGround){ player.AddForce(Vector3.up, ForceMode.Impulse); } } void movement() { forward = Input.GetAxisRaw("Vertical"); right = Input.GetAxisRaw("Horizontal"); transform.Translate(Vector3.forward * forward * speed * Time.deltaTime); transform.Translate(Vector3.right * right * speed * Time.deltaTime); } private void OnCollisionstay(Collision other) { if (other.transform.tag == "Ground") { isOnGround = true; } else { isOnGround = false; } } }
解决方案
- 修正方法名拼写:Unity的碰撞消息方法大小写敏感,你写的
OnCollisionstay应该改为OnCollisionStay(首字母S大写),否则方法不会被系统调用。 - 检查碰撞体与Rigidbody设置:
- 确保地面的Mesh Collider和角色的Cylinder Collider都未勾选
Is Trigger,OnCollision系列方法仅对非Trigger碰撞体生效。 - 角色的Rigidbody必须开启
Use Gravity,且不能设置为Kinematic,否则物理系统不会处理碰撞交互。
- 确保地面的Mesh Collider和角色的Cylinder Collider都未勾选
- 改用物理方式移动角色:当前用
transform.Translate直接修改Transform位置会绕过物理系统,导致碰撞检测异常。建议改用Rigidbody的MovePosition实现移动:
void movement() { forward = Input.GetAxisRaw("Vertical"); right = Input.GetAxisRaw("Horizontal"); Vector3 moveDir = transform.forward * forward + transform.right * right; player.MovePosition(player.position + moveDir.normalized * speed * Time.deltaTime); }
(添加normalized避免斜向移动速度过快)
- 优化碰撞检测逻辑:使用
OnCollisionEnter和OnCollisionExit替代OnCollisionStay,更精准控制isOnGround状态,避免与其他物体碰撞时误修改:
private void OnCollisionEnter(Collision other) { if (other.transform.CompareTag("Ground")) { isOnGround = true; } } private void OnCollisionExit(Collision other) { if (other.transform.CompareTag("Ground")) { isOnGround = false; } }
- 验证标签正确性:确认地面物体的标签是
Ground,拼写完全一致(大小写敏感),无多余空格或符号。
内容的提问来源于stack exchange,提问作者JaketheJeff
相关产品推荐
相关产品推荐

