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

Unity OnCollisionEnter2D设置父物体后玩家缩放变小解决方法

问题原因

玩家站到平台上尺寸异常缩小,是Transform层级的缩放继承机制导致的:

  • 当你把玩家设置为平台的子物体后,玩家的全局尺寸会乘算父物体(包括平台自身、平台所有上级节点)的缩放值,只要平台侧任意父节点的localScale不是标准的(1,1,1),玩家的实际显示/碰撞尺寸就会被连带改变
  • 如果你碰撞检测拿到的collision.transform是玩家身上挂碰撞体的子节点而非玩家根节点,绑定子节点到平台后,子节点缩放受平台影响,也会导致玩家整体尺寸异常
修复方案

你可以根据项目实际需求二选一:

方案1:最小改动适配(适合平台无运行时缩放的场景)

直接修改你的父子绑定逻辑,绑定/解绑时强制保持玩家的世界空间位置、旋转、缩放不变,额外加一层缩放校验抵消父级缩放的影响,改动量最小。
修正后的代码:

private void OnCollisionEnter2D(Collision2D collision)
{
    if (!collision.transform.CompareTag("Player")) return;
    // 绑定父级时保持玩家原有世界空间变换属性不变
    collision.transform.SetParent(transform, true);
    // 手动校准局部缩放,保证玩家全局尺寸不受父级缩放影响
    Vector3 platformGlobalScale = transform.lossyScale;
    Vector3 playerOriginalGlobalScale = collision.transform.lossyScale;
    collision.transform.localScale = new Vector3(
        playerOriginalGlobalScale.x / platformGlobalScale.x,
        playerOriginalGlobalScale.y / platformGlobalScale.y,
        playerOriginalGlobalScale.z / platformGlobalScale.z
    );
}

private void OnCollisionExit2D(Collision2D collision)
{
    if (!collision.transform.CompareTag("Player")) return;
    // 解绑时同样保持世界空间属性不变,避免脱离瞬间尺寸/位置跳变
    collision.transform.SetParent(null, true);
}

注意:

  1. 请确保碰撞检测命中的是玩家的根节点Transform,不要绑定玩家的子物体,否则依然会出现变换异常
  2. 如果你的移动平台运行时会动态修改缩放值,这个方案无法抵消实时缩放带来的尺寸变化,请使用方案2

方案2:无层级绑定实现(稳定性最高,推荐)

完全放弃父子绑定逻辑,通过记录平台每帧的移动增量,直接把移动量同步给站在平台上的玩家,从根源上规避层级缩放、旋转继承的所有问题,不会出现任何尺寸异常。
参考实现代码:

private Vector3 _lastFramePlatformPos;
private Transform _currentPlayerOnPlatform;

private void Start()
{
    _lastFramePlatformPos = transform.position;
}

private void FixedUpdate()
{
    // 和物理更新同频计算平台移动增量,避免玩家抖动
    Vector3 moveDelta = transform.position - _lastFramePlatformPos;
    // 同步移动增量给站在平台上的玩家
    if (_currentPlayerOnPlatform != null)
    {
        _currentPlayerOnPlatform.position += moveDelta;
    }
    _lastFramePlatformPos = transform.position;
}

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.transform.CompareTag("Player"))
    {
        _currentPlayerOnPlatform = collision.transform;
    }
}

private void OnCollisionExit2D(Collision2D collision)
{
    if (collision.transform.CompareTag("Player"))
    {
        _currentPlayerOnPlatform = null;
    }
}

这个方案不需要修改玩家的层级关系,不管平台本身有没有缩放、运行时会不会改缩放/旋转,都能保证玩家同步移动的同时尺寸完全正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:54:25