Same Character for different player

aledg

New member
Hi guys, I'm using PUN.
To spwaning different characters I'm using the class in the documentation like this.


C#:
using UnityEngine;
using Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game;
using Photon.Realtime;

public class MySpawnManager : SpawnManagerBase
{
    
    protected override GameObject GetCharacterPrefab(Player newPlayer)
    {
        GameObject m_Character = Resources.Load<GameObject>(GlobalControl.MyAvatarModel);
        return m_Character;
    }

}


<< GlobalControl.MyAvatarModel is a String variables set in the prev scene.

It works and I can load different dynamic characters, but the problem is that the two users don't see different characters but they see the same characters that they have also selected for the opponent ...

1471

1472
 
What does GlobalControl.MyAvatarModel return? You'll need to ensure that you return a different model based on the Player parameter.
 
Return a different model, in fact the player plays with the correct avatar, the problem that all other users have the same Avatar ...

For example

User1 selects blue avatar
User2 selects red avatar


User1 plays with blue avatar (but also sees User2 with blue avatar)
User2 plays with red avatar (but also sees User2 with red avatar)
 
How does that property know which model to select for each player? The same GetCharacterPrefab method is called for both the local and remote players so you need to ensure it is returning the correct model based on the player id. If you place a breakpoint in this method I bet that GetCharacterPrefab is returning the same object no matter what client joins.
 
Thank right now it's clear, but Where I can find example or documentation to do that? I suppose that I've to binding the ID of the user to the character model and inside MySpawnManager class I've to spawn the right model
 
It really depends on your game implementation but it can be something as simple as:

Code:
[SerializedField] protected GameObject[] m_Characters;
...
    protected override GameObject GetCharacterPrefab(Player newPlayer)
    {
        return m_Characters[newPlayer.ActorNumber];
    }
 
Hello,

I'm having the same problem, did someone managed to solve this issue?
I would really appriciate if there is a solution for this problem.
 
Been scratching my head on this one for a few hours myself now; I can get to the point of loading different Player prefabs in the game editor but when I build and try to run two instances the second one does not load the selected character. I've been trying to do it with the integer of the prefab to load but can not figure out a simple solution to select a character!!
 
Ok so I have made some progress and can get the character to spawn but am getting some minor errors that I know are caused by the Instantiate method. My code so far:

Code:
public class CharacterSelection : MonoBehaviour
{
    public static CharacterSelection CS;
    public int mySelectedCharacter;
    public GameObject[] aCharacters;


    private void OnEnable()
    {
        if(CharacterSelection.CS == null)
        {
            CharacterSelection.CS = this;
        }

        else
        {
            if(CharacterSelection.CS != this)
            {
                Destroy(CharacterSelection.CS.gameObject);
                CharacterSelection.CS = this;
            }
        }
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    private void Update()
    {
        if (PlayerPrefs.HasKey("MyCharacter"))
        {
            mySelectedCharacter = PlayerPrefs.GetInt("MyCharacter");
        }

        else
        {
            mySelectedCharacter = 0;
            PlayerPrefs.SetInt("MyCharacter", mySelectedCharacter);
        }
    }
}

Code:
public class CharacterSpawnManager : SpawnManagerBase
{
    [SerializeField]
    protected GameObject m_Character;
    [SerializeField]
    protected GameObject[] m_Characters;

    public GameObject Character { get { return m_Character; } set { m_Character = value; } }

    protected override GameObject GetCharacterPrefab(Player newPlayer)
    {
        m_Characters = new GameObject[CharacterSelection.CS.aCharacters.Length];

        for(int i = 0; i < CharacterSelection.CS.aCharacters.Length; i ++)
        {
            m_Characters[i] = Instantiate(CharacterSelection.CS.aCharacters[CharacterSelection.CS.mySelectedCharacter]) as GameObject;
        }

        //m_Character = CharacterSelectionManager.CSM.characterSelected;
        Debug.Log("Current Character:" + CharacterSelectionManager.CSM.characterSelected.name);
        // Return the same character for all instances.
        return m_Characters[newPlayer.ActorNumber];
        //return m_Character;
    }
}

So in My CharacterSelection script I am setting up the array and updating the selected character. I am then passing that over to the CharacterSpawnmanager. I am still newish but can figure things out in Unity scripting so I may be wrong but I think the issue lies with Instantiate.

The errors are ViewID errors: "Illegal view ID:0 method: LoadDefaultLoadoutRPC GO:"

If someone could be so kind as to give me a push in the right direction it would be greatly appreciated; I'm getting close on my own I can feel it!
 
You do not want to do the actual instantiation within GetCharacterPrefab - the add-on will instantiate for you.
 
Thank you Justin!! All I needed was that push in the right direction! For those who are looking for a solution here is the code:
Code:
public class CharacterSpawnManager : SpawnManagerBase
{
    [SerializeField]
    protected GameObject[] m_Characters;

    protected override GameObject GetCharacterPrefab(Player newPlayer)
    {
        m_Characters = new GameObject[CharacterSelection.CS.aCharacters.Length];

        for (int i = 0; i < CharacterSelection.CS.aCharacters.Length; i++)
        {
            //m_Characters[i] = CharacterSelection.CS.aCharacters[4];
            m_Characters[i] = CharacterSelection.CS.aCharacters[CharacterSelection.CS.mySelectedCharacter];
        }

        Debug.Log("My Selected Character:" + CharacterSelection.CS.mySelectedCharacter);
        // Return the same character for all instances.
        return m_Characters[newPlayer.ActorNumber];
        //return m_Character;
    }
}
 
Actually, where did you set ActorNumber ?
ActorNumber as my understanding is the player number in the current room..

Also, you should only intantiate m_Characters once per client and not for each GetCharacterPrefab, abit overhead..
 
I think that's where I am getting lost; I can't figure out how to set the actor number and google isn't much help as to doing it either. The sad part is that if I start from scratch without this character controller I can get it to work, but using this controller and add-on just isn't working...
 
Ok so I have set the new ActorNumber but get an error saying that the ActorNumber has already been added! This seems a little more complicated than it should be; I have been thinking of PhotonViews and was wondering if it could be done that way as in the video below? I can get it to work this way without the Third Person Character so in theory it should work, correct?

 
Arachai or Justin, my scenario is this: I have three characters for a co-op game. In the menu I have buttons set up to save in playerprefs the selected id of the character. Then the player is spawned with the selected character using your code but when I join with other instance of the game it occurs as the main post, both instances see the same different character. I'm want to set the player custom property on join reading it from playerprefs. Can anyone help?
 
Arachai or Justin, my scenario is this: I have three characters for a co-op game. In the menu I have buttons set up to save in playerprefs the selected id of the character. Then the player is spawned with the selected character using your code but when I join with other instance of the game it occurs as the main post, both instances see the same different character. I'm want to set the player custom property on join reading it from playerprefs. Can anyone help?

Never mind I got it working with SetCustomPropery for LocalPlayer passing the ID of the selected Character and then selecting it from an array on GetCharacaterPrefab
 
Never mind I got it working with SetCustomPropery for LocalPlayer passing the ID of the selected Character and then selecting it from an array on GetCharacaterPrefab
Can you please post your code, because I have the same problem and I can't get it to work...
Thank you!
 
Select character code(OnClick event on button):
C#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class CharacterSelector : MonoBehaviour
{
   
    private ExitGames.Client.Photon.Hashtable _myCustomProperties = new ExitGames.Client.Photon.Hashtable();
    public void SelectCharacter(int index){
        PlayerPrefs.SetInt("MyCharacter", index);
        Debug.Log("Player prefs: "+ PlayerPrefs.GetInt("MyCharacter"));
        _myCustomProperties["ID"] = index;
        PhotonNetwork.LocalPlayer.CustomProperties = _myCustomProperties;
    }
}

Custom Character Spawn Manager
C#:
public class CharacterSpawnManager : SpawnManagerBase
{
    [SerializeField]
    protected GameObject[] m_Characters;

    protected override GameObject GetCharacterPrefab(Player newPlayer)
    {
       
        if(newPlayer.CustomProperties.ContainsKey("ID")){
            int result = (int)newPlayer.CustomProperties["ID"];
            Debug.Log("Character ID : "+result);
            return m_Characters[result];
        }else{
            return m_Characters[0];
        }
    }
}
Characters Prefabs are assigned manually in the editor to m_Characters.


Hope it helps you!
 
Top