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); }
注意:
- 请确保碰撞检测命中的是玩家的根节点Transform,不要绑定玩家的子物体,否则依然会出现变换异常
- 如果你的移动平台运行时会动态修改缩放值,这个方案无法抵消实时缩放带来的尺寸变化,请使用方案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
相关产品推荐
相关产品推荐

