见Photon RPC and RaiseEvent => "你可以添加多个参数只要PUN可以序列化它们" -> 见Photon - Supported Types for Serialization
=> 不,这是不可能的。
解决方案
您总是需要一种方法来告诉其他设备您指的是哪个对象,因为它们与您的引用不同。
如果您指的是您的光子播放器的对象,但您可以改为发送
PhotonNetwork.LocalPlayer.ActorNumber
另一方面,通过ActorNumber 获取GameObject。
有多种方法可以做到这一点。
我曾经通过像这样的中心类来做到这一点
public class PhotonUserManager : IInRoomCallbacks, IMatchmakingCallbacks
{
private static PhotonUserManager _instance;
private readonly Dictionary<int, GameObject> _playerObjects = new Dictionary<int, GameObject>();
public static bool TryGetPlayerObject(int actorNumber, out GameObject gameObject)
{
return _instance._playerObjects.TryGetValue(actorNumber, out gameObject);
}
[RuntimeInitializeOnLoadMethod]
private static void Init()
{
_instance = new PhotonUserManager();
PhotonNetwork.AddCallbackTarget(_instance);
}
public void OnCreateRoomFailed(short returnCode, string message){ }
public void OnJoinRoomFailed(short returnCode, string message){ }
public void OnCreatedRoom() { }
public void OnJoinedRoom()
{
Refresh();
}
public void OnLeftRoom()
{
_playerObjects.Clear();
}
public void OnJoinRandomFailed(short returnCode, string message){ }
public void OnFriendListUpdate(List<FriendInfo> friendList) { }
public void OnPlayerEnteredRoom(Player newPlayer)
{
Refresh();
}
public void OnPlayerLeftRoom(Player otherPlayer)
{
if(_playerObjects.ContainsKey(otherPlayer.ActorNumber))
{
_playerObjects.Remove(otherPlayer.ActorNumber);
}
}
public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged){ }
public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps){ }
public void OnMasterClientSwitched(Player newMasterClient){ }
private void Refresh()
{
var photonViews = UnityEngine.Object.FindObjectsOfType<PhotonView>();
foreach (var view in photonViews)
{
var player = view.owner;
//Objects in the scene don't have an owner, its means view.owner will be null => skip
if(player == null) continue;
// we already know this player's object -> nothing to do
if(_playerObjects.ContainsKey(player.ActorNumber)) continue;
var playerObject = view.gameObject;
_playerObjects[player.ActorNumber] = playerObject;
}
}
}
这会自动收集加入玩家拥有的GameObject。当然有一个限制:如果玩家自己生成任何东西并拥有它......它可能会失败,因为那时每个玩家有多个PhotonViews => 在这种情况下使用具有最低 NetworkIdendity 的那个。在 Photon 中,viewID 由第一个数字 = ActorNumber + 3 个数字 id 组成;)
以后做
if(!PhotonUserManager.TryGetPlayerObject(out var obj))
{
Debug.LogError($"Couldn't get object for actor number {receivedActorNumber}");
}
作为另一种选择,您可以使用OnPhotonInstantiate
public class SomeComponentOnYourPlayerPrefab : PunBehaviour
{
public override void OnPhotonInstantiate(PhotonMessageInfo info)
{
// only set if not already set in order to not
// overwrite the tag for a player that spawns something later
if(info.sender.TagObject == null)
{
info.sender.TagObject = gameObject;
}
}
}
然后再做
var obj = PhotonNetwork.LocalPlayer.Get(receivedActorNumber).TagObject;