Unity角色跳跃碰墙被吸附粘墙问题的解决方法
Unity角色跳跃碰墙粘滞问题解决方法
你的粘墙问题完全是脚本逻辑错误导致的,不需要改引擎项目设置,按下面两步改完就能解决:
- 落地判断逻辑错误:现有代码里
OnCollisionStay()没有做碰撞面方向判断,只要角色碰到任何碰撞体(墙面、天花板、陡坡)都会被判定为“站在地上”,碰墙时游戏会误以为你踩在地面,持续响应朝墙方向的移动指令,自然会贴在墙上。 - 移动方式违反物理系统规则:你用
transform.Translate直接修改角色坐标,这个方法会完全绕过Unity的物理计算,直接把角色模型往碰撞体里面“塞”,物理引擎检测到穿模后会持续把角色推回碰撞表面,就会出现粘墙、滑墙落不下来的问题。
第一步:修正落地检测逻辑
删掉原来无参数的OnCollisionStay()方法,替换成带碰撞信息检测的版本,只有接触点在角色正下方时才判定为落地,同时补充离开碰撞体的状态重置逻辑:
void OnCollisionStay(Collision collision) { // 遍历当前碰撞的所有接触点 foreach (ContactPoint contact in collision.contacts) { // 用点积判断接触面方向:法线朝上=接触面在脚下,0.7f的阈值允许最大45度的斜坡 if (Vector3.Dot(contact.normal, Vector3.up) > 0.7f) { isGrounded = true; break; } } } void OnCollisionExit(Collision collision) { // 离开碰撞体立刻重置落地状态 isGrounded = false; }
第二步:把移动逻辑改成刚体驱动
用Rigidbody做角色控制器时,绝对不能用transform.Translate直接改坐标,所有移动、跳跃都要通过操作刚体的速度/施加力实现,避免和物理系统冲突。同时把输入检测从FixedUpdate移到Update,固定时间步的FixedUpdate会漏抓按键输入。
直接替换成下面的完整脚本即可,注释已经标清修改点:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RigidbodyPlayerController : MonoBehaviour { public Rigidbody playerRidgidBody; public float movementSpeed = 3f; public float jumpForce; public bool isGrounded; private float horizontalInput; private float verticalInput; private bool jumpPressed; void Awake() { playerRidgidBody.freezeRotation = true; playerRidgidBody.useGravity = true; } void Update() { // 所有输入检测放在Update中,避免丢失按键响应 verticalInput = Input.GetAxis("Vertical"); horizontalInput = Input.GetAxis("Horizontal"); // 跳跃用GetButtonDown,仅在按下瞬间触发,不会出现长按连跳 if (Input.GetButtonDown("Jump") && isGrounded) { jumpPressed = true; } } void OnCollisionStay(Collision collision) { foreach (ContactPoint contact in collision.contacts) { if (Vector3.Dot(contact.normal, Vector3.up) > 0.7f) { isGrounded = true; break; } } } void OnCollisionExit(Collision collision) { isGrounded = false; } void FixedUpdate() { // 跳跃逻辑 if (jumpPressed) { // 跳跃前清零竖直方向速度,避免下落状态下跳跃高度异常 playerRidgidBody.velocity = new Vector3(playerRidgidBody.velocity.x, 0, playerRidgidBody.velocity.z); playerRidgidBody.AddForce(Vector3.up * jumpForce, ForceMode.Impulse); jumpPressed = false; isGrounded = false; } // 移动逻辑:保留刚体原有的竖直速度(重力/跳跃生效),仅修改水平方向速度 Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput; playerRidgidBody.velocity = new Vector3(moveDir.x * movementSpeed, playerRidgidBody.velocity.y, moveDir.z * movementSpeed); } }
可选优化项(新手可以先改完上面两步再调)
- 选中角色的Rigidbody组件,把
Collision Detection从Discrete改成Continuous,高速跳跃碰墙时不会出现穿模、卡墙问题。 - 如果还是有轻微滑墙感,可以新建一个摩擦力为0的Physic Material,拖到角色的碰撞体材质槽里,墙面不会因为摩擦力把角色挂住。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

