You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity第三人称玩家如何锁定位置防滑移且按移动键可恢复控制

解决方案

你这个场景无需修改物理材质,改材质会全局影响所有和地形碰撞的物体,后续容易出现隐藏问题,直接通过控制玩家组件和刚体约束即可实现需求,具体实现步骤如下:

1. 预先声明所需变量

在你的脚本头部添加以下变量,组件引用可以提前在Inspector面板拖拽赋值,也可以在Awake/Start方法中通过GetComponent获取:

// 玩家组件引用,提前赋值
public ThirdPersonUserControl userControl;
public ThirdPersonCharacter character;
public Rigidbody playerRb;
public Animator playerAnim;

private Vector3 lockedPosition;
private bool isPlayerLocked = false;

2. 在标注// Here的位置添加锁定逻辑

这里采用「刚体位置锁死+控制组件禁用+根运动临时关闭」的三重保险方案,完全避免idle动画带动位移或者物理滑移:

// 记录当前玩家位置作为锁定坐标
lockedPosition = player.transform.position;
// 锁死刚体的位置和旋转(旋转保留你原本的锁定规则即可)
playerRb.constraints = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation;
// 禁用玩家输入控制组件,拦截用户移动操作
userControl.enabled = false;
character.enabled = false;
// 如果你的Animator开启了Apply Root Motion,临时关闭避免动画驱动位移
// 没开的话可以删掉这行
playerAnim.applyRootMotion = false;
// 标记当前为锁定状态
isPlayerLocked = true;

3. 添加移动输入监听逻辑,触发自动解锁

在Update方法中新增锁定状态下的输入检测逻辑,只要检测到玩家按下移动键就自动解锁:

// 锁定状态下检测移动输入
if (isPlayerLocked)
{
    // 读取Unity默认移动轴输入,适配键鼠和手柄
    float horizontal = Input.GetAxis("Horizontal");
    float vertical = Input.GetAxis("Vertical");
    // 输入大于阈值判定为玩家主动移动,触发解锁
    if (Mathf.Abs(horizontal) > 0.1f || Mathf.Abs(vertical) > 0.1f)
    {
        UnlockPlayer();
    }
    // 额外强制固定位置,避免极端情况出现漂移
    player.transform.position = lockedPosition;
}

4. 单独封装解锁方法

把恢复玩家状态的逻辑封装为独立方法,方便复用:

void UnlockPlayer()
{
    // 恢复刚体默认约束,仅保留旋转锁定
    playerRb.constraints = RigidbodyConstraints.FreezeRotation;
    // 恢复控制组件
    userControl.enabled = true;
    character.enabled = true;
    // 恢复Animator根运动设置(没开的话删掉这行)
    playerAnim.applyRootMotion = true;
    // 取消锁定标记
    isPlayerLocked = false;

    // 这里可以直接复用你原本退出交互的逻辑,和原有逻辑对齐
    if (securityKeyPad1 != null)
    {
        securityKeyPad1.SetActive(false);
    }
    if (virtualCam != null)
        virtualCam.enabled = false;
    camerasContorl.enabled = true;
    freeLookCam2.enabled = true;
    Cursor.visible = false;
    playAnimOnce = false;
    if (securityKeypadSystem != null)
        securityKeypadSystem.ResetCode();
}

注意事项

  • 输入检测的阈值0.1f可以根据需求调整,避免手柄死区或者误触
  • 所有组件引用建议提前缓存,不要频繁调用GetComponent影响性能

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:39:02