使用 photon pun2 选择角色并将角色上传到场景

Character selection and uploading characters to the scene with photon pun2

我正在尝试使用 Unity 开发一款 3D 多人游戏。我对Photon了解不多,有和我要问的类似的问题,但我仍然没有找到解决方案。如果你能帮忙,我会很高兴。 我有两个名为“菜单”和“游戏”的场景。在菜单场景中,用户通过playfab认证后进行角色选择。完成选择后,他们连接到大厅并设置房间并加载游戏场景。至此一切顺利。但是,在加载游戏场景时,我很难将用户选择的角色加载到场景中。

这是我让用户选择角色的代码文件:

public class choose : MonoBehaviour {

private GameObject[] characterList;
private int index;
PhotonView PV;

private void Awake()
{
    PV = GetComponent<PhotonView>();
}

private void Start()
{   
    index = PlayerPrefs.GetInt("CharacterSelected");
    characterList = new GameObject[transform.childCount];

    for (int i=0; i< transform.childCount; i++) 
        characterList[i] = transform.GetChild(i).gameObject;
    foreach (GameObject go in characterList)
        go.SetActive (false);
    if (characterList [index])
        characterList [index].SetActive (true);
 }


public void ToggleLeft(){
    characterList [index].SetActive (false);
    index--;
    if (index < 0)
        index = characterList.Length - 1;
    characterList [index].SetActive (true);
}

public void ToggleRight(){
    characterList [index].SetActive (false);
    index++;
    if (index == characterList.Length)
        index = 0;
    characterList [index].SetActive (true);
}


public void kaydetbuton() {
    PlayerPrefs.SetInt ("CharacterSelected", index);
    
    
} }

这是我让游戏中的角色移动的代码文件:

public class control : MonoBehaviour {

public FixedJoystick LeftJoystick;
private GameObject leftjoystick;
public FixedButton Button;
private GameObject button;
public FixedTouchField TouchField;
private GameObject touchField;
protected ThirdPersonUserControl Control;

protected float CameraAngle;
protected float CameraAngleSpeed = 0.2f;

PhotonView PV;

void Awake()
{

    PV = GetComponent<PhotonView>();
}
void Start()
{
    if (!PV.IsMine)
        return;
    Control = GetComponent<ThirdPersonUserControl>();

    leftjoystick = GameObject.Find("Fixed Joystick");
    if (leftjoystick != null)
    {
        LeftJoystick = leftjoystick.GetComponent<FixedJoystick>();
    }
    button = GameObject.Find("Handle (1)");
    if (button != null)
    {
        Button = button.GetComponent<FixedButton>();
    }
    touchField = GameObject.Find("tfield");
    if (touchField != null)
    {
        TouchField = touchField.GetComponent<FixedTouchField>();
    }
}
  void FixedUpdate() {

    if (PV.IsMine)
    {
        Control.m_Jump = Button.Pressed;
        Control.Hinput = LeftJoystick.Direction.x;
        Control.Vinput = LeftJoystick.Direction.y;

        CameraAngle += TouchField.TouchDist.x * CameraAngleSpeed;

        Camera.main.transform.position = transform.position + Quaternion.AngleAxis(CameraAngle, Vector3.up) * new Vector3(1, 2, 3);
        Camera.main.transform.rotation = Quaternion.LookRotation(transform.position + Vector3.up * 2f - Camera.main.transform.position, Vector3.up);
    }
} }

菜单场景中有一个名为“karakteryükle”的游戏对象。名为“选择”的代码文件在此对象中。这个游戏对象中有 4 个角色。每个角色都有一个名为“control”的代码文件,photon view,photon transform view,animator view组件。并且名为“karakteryükle”的游戏对象也可以作为 Resources 文件夹中的预制件使用。

I am sharing the picture of the components loaded on each character

I shared a picture of the game object named "karakter yükle"

我正在尝试在加载名为 game 的场景时加载“karakter yükle”

PhotonNetwork.Instantiate("karakteryükle", new Vector3((float)-0.43, (float)1.1, (float)-25.84), Quaternion.identity, 0, null);

结果:“karakteryükle”加载到舞台上,但为每个玩家加载相同的角色,没有加载每个玩家选择的角色。 我需要你对此的意见。

每个玩家只知道自己的索引设置,因为他们使用 PlayerPrefs 中设置的值。

private void Start()
{   
    index = PlayerPrefs.GetInt("CharacterSelected");
}

这适用于我们的本地播放器,没问题。但是当不同的玩家进入场景时会发生什么。

  1. playerObject 在每个客户端上生成。
  2. 每个客户端在本地处理该 playerObject(这就是 IsMine 存在的原因)。
  3. Player1 在他们的 Player2 副本上执行 index = PlayerPrefs.GetInt(..)

您可以做的是发送缓冲的 RPC 以在这些远程副本上设置所选字符。我们想缓冲 rpc,以便新玩家将每个人的远程副本更改为适当的角色。

myPhotonView.RPC("SetCharacterIndex", RpcTarget.OthersBuffered, index);

以及对应的RPC方法

[PunRPC]
private void SetCharacterIndex(int index)
{
    // Disable other characters and enable the one at this index
}

最后你会得到类似

的东西
void Start()
{
    characterList = new GameObject[transform.childCount];

    for (int i=0; i< transform.childCount; i++) 
    {
        characterList[i] = transform.GetChild(i).gameObject;
        characterList[i].SetActive(false);
    }

    if (isMine)
    {
        index = PlayerPrefs.GetInt("CharacterSelected");
        
        // Notify all remote copies of us to change their index
        //
        photonView.RPC("SetCharacterIndex", RpcTarget.OthersBuffered, index);

        // Set the index locally
        //
        SetCharacterIndex(index);
    }
}
[PunRPC]
private void SetCharacterIndex(int index)
{
    if (characterList [index])
        characterList [index].SetActive (true);
}

希望这有助于弄清发生这种情况的原因(网络有时会令人困惑)。