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

Unity Photon Pun2 硬币收集系统问题:销毁硬币时PhotonView异常

Unity Photon Pun2 硬币收集系统问题解决:销毁硬币但保留PhotonView

问题说明

开发基于Unity Photon Pun2的玩家硬币收集系统,需求为玩家收集足够硬币后生成钥匙。当前遇到核心问题:第一个硬币被销毁时,其附带的PhotonView也被一同销毁,导致收集第二个硬币时触发错误:

Illegal view ID:0 method: CollectCoin GO:Coin (2)

错误原因

当前代码中使用PhotonNetwork.Destroy(gameObject)销毁整个硬币对象,连带销毁了绑定在该对象上的PhotonView。Photon的View ID与对象强绑定,对象销毁后View ID失效,后续对该View ID的RPC调用会触发非法ID错误。此外,未对硬币添加“已收集”标记,可能导致重复触发收集逻辑。

解决方案

核心思路是不销毁整个硬币对象,仅禁用其交互和显示组件,保留PhotonView以维持RPC通信的有效性:

  • 添加isCollected标记,防止硬币被重复触发收集
  • 在DeactivateCoin中禁用碰撞体、渲染组件,而非销毁对象
  • 修正玩家硬币收集逻辑的调用链路

修改后的代码

Coin 脚本

using UnityEngine;
using Photon.Pun;

public class Coin : MonoBehaviourPun
{
    private bool isCollected = false; // 标记硬币是否已被收集

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (isCollected) return; // 已收集的硬币直接返回,不再响应触发
        if (other.gameObject.CompareTag("Player"))
        {
            Debug.Log("Player collided with coin");
            if (PhotonNetwork.IsMasterClient)
            {
                photonView.RPC("CollectCoin", RpcTarget.All, other.gameObject.GetComponent<PhotonView>().ViewID);
            }
        }
    }

    [PunRPC]
    public void CollectCoin(int playerViewID)
    {
        if (isCollected) return;
        isCollected = true;

        // 找到对应的玩家并调用收集方法
        CoinCollect playerCoinCollection = PhotonView.Find(playerViewID).gameObject.GetComponent<CoinCollect>();
        playerCoinCollection.CollectCoin();

        photonView.RPC("DeactivateCoin", RpcTarget.All);
    }

    [PunRPC]
    void DeactivateCoin()
    {
        // 禁用碰撞体,防止重复触发
        GetComponent<Collider2D>().enabled = false;
        // 禁用所有渲染组件,隐藏硬币
        foreach (Renderer renderer in GetComponentsInChildren<Renderer>())
        {
            renderer.enabled = false;
        }
        // 若有粒子特效、动画等组件,可在此一并禁用
    }
}

CoinCollect 脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class CoinCollect : MonoBehaviourPunCallbacks, IPunObservable
{
    public GameObject keyPrefab;
    private int coinCount;
    private int playerCount;
    private int coinsNeeded;

    void Start()
    {
        // 若房间未完全初始化,可改用OnJoinedRoom回调获取玩家数量
        playerCount = PhotonNetwork.PlayerList.Length; 

        switch (playerCount)
        {
            case 1:
                coinsNeeded = 1;
                break;
            case 2:
                coinsNeeded = 2;
                break;
            case 3:
                coinsNeeded = 15;
                break;
            case 4:
                coinsNeeded = 20;
                break;
            default:
                Debug.LogError("Unsupported player count: " + playerCount);
                break;
        }
    }

    // 玩家收集硬币时触发
    public void CollectCoin()
    {
        coinCount++;
        CheckCoinCount();
    }

    private void CheckCoinCount()
    {
        if (coinCount >= coinsNeeded)
        {
            SpawnKey();
        }
    }

    private void SpawnKey()
    {
        PhotonNetwork.Instantiate(keyPrefab.name, new Vector3(0, 0, 0), Quaternion.identity);
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            stream.SendNext(coinCount);
        }
        else
        {
            this.coinCount = (int)stream.ReceiveNext();
        }
    }
}

关键修改点

  1. 添加收集标记:isCollected变量确保每个硬币仅被处理一次,避免重复RPC调用
  2. 替换销毁逻辑:将PhotonNetwork.Destroy(gameObject)改为禁用组件,保留PhotonView的有效性
  3. 修复调用链路:在CollectCoin中正确调用玩家的CollectCoin()方法,实现硬币计数累加

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:22:46