Unity+Photon 2D多人游戏如何避免玩家间碰撞?
Unity+Photon 2D多人游戏:禁用玩家间碰撞解决方案
问题描述
我正在使用Unity和Photon开发一款2D多人游戏,目前遇到玩家互相碰撞的问题,希望禁用该行为。我使用了Unity InputSystem,以下是玩家预制体设置及PlayerController脚本片段:
玩家预制体碰撞设置:
PlayerController脚本片段:
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){ if(stream.isWriting){ stream.SendNext(transform.position); stream.SendNext(localPlayerName.text); } else{ targetPosition = (Vector3)stream.ReceiveNext(); remotePlayerName.SetText((string)stream.ReceiveNext()); } } private void FixedUpdate() { if(PhotonView.isMine){ if(movementInput != Vector2.zero){ int count = gameObject.GetComponent<Rigidbody2D>().Cast( movementInput, movementFilter, castCollisions, moveSpeed * Time.fixedDeltaTime + collisionOffset ); if(count == 0){ transform.position += (Vector3)movementInput * moveSpeed * Time.fixedDeltaTime; } } } else { moveOtherPlayer(); } } private void moveOtherPlayer() { transform.position = Vector3.Lerp(transform.position, targetPosition, 0.25f); } void OnMove(InputValue movementValue){ this.movementInput = movementValue.Get<Vector2>(); }
解决方案
下面是几种直接有效的实现方式:
方法1:利用Unity碰撞层(最推荐)
- 在Unity编辑器的Layers面板新建
Player层,将所有玩家预制体的Layer设为该层 - 打开Edit > Project Settings > Physics 2D,找到Layer Collision Matrix
- 取消
Player层与自身的碰撞勾选(矩阵中Player行和列的交叉点) - 注意:如果代码里的
movementFilter是ContactFilter2D,确保它没有额外冲突的过滤规则
方法2:修改ContactFilter2D适配现有代码
你的移动逻辑用到了Rigidbody2D.Cast和movementFilter,可以直接在过滤器中排除玩家层:
在PlayerController的Start()方法中添加:
void Start() { int playerLayer = LayerMask.NameToLayer("Player"); // 排除Player层的碰撞检测 movementFilter.SetLayerMask(~(1 << playerLayer)); movementFilter.useLayerMask = true; }
这样本地玩家的移动检测就不会识别其他玩家,自然不会触发碰撞阻挡
方法3:动态忽略玩家间碰撞
在玩家预制体的Awake()方法中添加逻辑,让所有玩家实例互相忽略碰撞:
void Awake() { Collider2D selfCollider = GetComponent<Collider2D>(); foreach (GameObject player in GameObject.FindGameObjectsWithTag("Player")) { if (player != gameObject) { Collider2D otherCollider = player.GetComponent<Collider2D>(); if (otherCollider != null) { Physics2D.IgnoreCollision(selfCollider, otherCollider); } } } }
- 记得给玩家预制体添加统一的
Player标签 - 新生成的玩家会自动忽略已有玩家的碰撞,适合动态生成场景
额外优化提示
- 远程玩家用
Vector3.Lerp移动时,建议把远程玩家的Rigidbody2D设为Kinematic(运动学),不需要物理模拟,避免碰撞抖动 - 本地玩家的Rigidbody2D属性设置要匹配移动逻辑,减少意外物理交互
内容的提问来源于stack exchange,提问作者Ahmed Zrouqui
相关产品推荐
相关产品推荐

