我正在使用 Unity 2022 和 Pun 2。我的想法是让 2 台设备(PC 和 Android)分别加载不同的场景(ScenePC 和 ScenePhone)。两者都从 LobbyScene 开始并加入同一个 Pun Room 以在两个场景之间交换信息。 我的目标是在 ScenePhone 中有一个对象“A”,它将位置信息发送到共享/同步对象“Sync”,然后将信息发送到 ScenePC 中的对象“B”。 如果您在 ScenePhone 中移动 A,B 也会移动;如果您在 ScenePC 中移动 B,A 也会移动。 稍后在 ScenePhone 上应该是 XRScene.
我的网络管理员看起来像这样:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class NetworkManager : MonoBehaviourPunCallbacks
{
// Start is called before the first frame update
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
private void Awake()
{
PhotonNetwork.AutomaticallySyncScene = false;
}
public override void OnConnectedToMaster()
{
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = 4 });
}
public override void OnJoinedRoom()
{
if (Application.platform == RuntimePlatform.WindowsPlayer)
{
PhotonNetwork.LoadLevel("ScenePC");
}
else
{
PhotonNetwork.LoadLevel("ScenePhone");
}
}
}
ScenePC 中的 GameManager 如下所示:
using UnityEngine;
using Photon.Pun;
public class GameManager : MonoBehaviourPunCallbacks
{
public GameObject Sync;
void Start()
{
PhotonNetwork.Instantiate(Sync.name, new Vector3(0, 5, 0), Quaternion.identity);
}
}
我将位置更新发送到 Sync 的 A 脚本如下所示:
using UnityEngine;
using Photon.Pun;
public class MoveObjectsTogether : MonoBehaviour
{
public GameObject syncObject;
public float speed = 0.5f;
void Start()
{
syncObject = GameObject.Find("Sync(Clone)");
}
void Update()
{
// Get the direction of movement for object A
Vector3 direction = Vector3.zero;
if (Input.GetKey(KeyCode.W)) { direction += Vector3.forward; }
if (Input.GetKey(KeyCode.A)) { direction += Vector3.left; }
if (Input.GetKey(KeyCode.S)) { direction += Vector3.back; }
if (Input.GetKey(KeyCode.D)) { direction += Vector3.right; }
// Move object A
transform.Translate(direction * Time.deltaTime * 4);
// Move Sync in network
if (syncObject != null)
{
syncObject.transform.Translate(direction * Time.deltaTime * 4 * 0.5f);
PhotonView photonView = syncObject.GetComponent<PhotonView>();
if (photonView != null)
{
photonView.RPC("SyncPosition", RpcTarget.Others, syncObject.transform.position);
}
}
}
}
在我的资源文件夹中,有一个名为 Sync 的对象,它在 Gamemanger 中实例化。它包含一个光子视图、一个光子变换视图和以下脚本:
using UnityEngine;
using Photon.Pun;
public class SyncObject : MonoBehaviourPunCallbacks
{
private Vector3 syncPosition;
[PunRPC]
public void SyncPosition(Vector3 position)
{
syncPosition = position;
}
/**
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(transform.position);
}
else if (stream.IsReading)
{
syncPosition = (Vector3)stream.ReceiveNext();
}
}
**/
private void Update()
{
if (photonView.IsMine)
{
syncPosition = transform.position;
}
else
{
transform.position = Vector3.Lerp(transform.position, syncPosition, Time.deltaTime*10);
}
}
}
如果对象 A 移动,则同步移动。如果我构建它两次,一次在 Windows 中,一次在 Unity Editor 中(使用 SceneAndroid),对于 SceneAndroid 一切正常,但在使用 ScenePC 构建时出现错误:
RPC method 'SyncPosition(Vector3)' not found on object with PhotonView 1001. Implement as non-static. Apply [PunRPC]. Components on children are not found. Return type must be void or IEnumerator (if you enable RunRpcCoroutines). RPCs are a one-way message.
我该如何解决这个问题?有更好的方法吗?我真的不想让 A 和 B 成为网络中的一些同步对象。稍后我想将 A 添加到跟踪平原的图像上。
我也尝试过 OnPhotonSerializeView 但这也不起作用。