Single Character Spawn Manager Script

So I have a character selection script that works, and I have a script that can instantiate the chosen character into a Pun Scene but my problem is when I try and connect it to Opsive UCC. I think I need to combined my "Instantiate Script" to your "Single Character Spawn Manager Script". I have tried doing that which just ends in a bunch of errors and problem,s so I was hoping you could tell me how to combined the two scripts in order to load my Opsive prefabs.

Please help me, I think its just a matter of connecting your m_Character, right?

My Script-

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Realtime;
using Photon.Pun;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Collections.Specialized;

public class MultiplayerCharacterSpawnManager : MonoBehaviour
{
public GameObject[] PlayerPrefabs;
public Transform[] InstantiatePositions;

void Start()
{
if (PhotonNetwork.IsConnectedAndReady)
{
object playerSelectionNumber;
if (PhotonNetwork.LocalPlayer.CustomProperties.TryGetValue(RIGame.PLAYER_SELECTION_NUMBER, out playerSelectionNumber))
{
UnityEngine.Debug.Log((int)playerSelectionNumber);

int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber;
Vector3 instantiatePosition = InstantiatePositions[actorNumber - 1].position;

PhotonNetwork.Instantiate(PlayerPrefabs[(int)playerSelectionNumber].name, instantiatePosition, Quaternion.identity);
}
}
}
}


Your Script-

/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------

namespace Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game
{
using UnityEngine;
using Photon.Realtime;

/// <summary>
/// Manages the character instantiation within a PUN room.
/// </summary>
public class SingleCharacterSpawnManager : SpawnManagerBase
{
[Tooltip("A reference to the character that PUN should spawn. This character must be setup using the PUN Multiplayer Manager.")]
[SerializeField] protected GameObject m_Character;

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

/// <summary>
/// Abstract method that allows for a character to be spawned based on the game logic.
/// </summary>
/// <param name="newPlayer">The player that entered the room.</param>
/// <returns>The character prefab that should spawn.</returns>
protected override GameObject GetCharacterPrefab(Player newPlayer)
{
// Return the same character for all instances.
return m_Character;
}
}
}

Thanks
 
I'm not sure if you need this but its my character selection script and another script that are connected to my "Instantiate Script"(the one above yours) just in case you need it so you know how the scripts work.

player selection script-

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

public class PlayerSelection : MonoBehaviour
{
public GameObject[] SelectablePlayers;

public int playerSelectionNumber;

// Start is called before the first frame update
void Start()
{
playerSelectionNumber = 0;

ActivatePlayer(playerSelectionNumber);
}

// Update is called once per frame
void Update()
{

}

private void ActivatePlayer(int x)
{
foreach (GameObject selectablePlayer in SelectablePlayers)
{
selectablePlayer.SetActive(false);
}

SelectablePlayers[x].SetActive(true);

ExitGames.Client.Photon.Hashtable playerSelectionProp = new ExitGames.Client.Photon.Hashtable() { { RIGame.PLAYER_SELECTION_NUMBER, playerSelectionNumber } };
PhotonNetwork.LocalPlayer.SetCustomProperties(playerSelectionProp);
}

public void RightPlayer()
{
playerSelectionNumber += 1;
if (playerSelectionNumber >= SelectablePlayers.Length)
{
playerSelectionNumber = 0;
}

ActivatePlayer(playerSelectionNumber);
}

public void LeftPlayer()
{
playerSelectionNumber -= 1;
if (playerSelectionNumber < 0)
{
playerSelectionNumber = SelectablePlayers.Length - 1;
}

ActivatePlayer(playerSelectionNumber);
}
}

Other Script-

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

public class RIGame : MonoBehaviour
{
public const string PLAYER_SELECTION_NUMBER = "Player_Selection_Number";
}

thanks again
 
If you do a search within this board you should also be able to find a few examples but this page should also help:


It does look like you will need to join your Start with the GetCharactePrefab method.
 
So I read the threads and looked over the link which helped and I have tried a few variations of combining the two methods but it hasn't worked yet let me post my best attempt and see if you can tell me what I did wrong

This is my attempt-

protected override GameObject GetCharacterPrefab(Player newPlayer)

{

if (PhotonNetwork.IsConnectedAndReady)

{

object playerSelectionNumber;

if (PhotonNetwork.LocalPlayer.CustomProperties.TryGetValue(RIGame.PLAYER_SELECTION_NUMBER, out playerSelectionNumber))

{

UnityEngine.Debug.Log((int)playerSelectionNumber);



int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber;

Vector3 instantiatePosition = InstantiatePositions[actorNumber - 1].position;



return m_Character = PhotonNetwork.Instantiate(PlayerPrefabs[(int)playerSelectionNumber].name, instantiatePosition, Quaternion.identity);

}

}

}

Unitys error report from the console-

Assets\Scripts\Networking\MultiplayerCharacterSpawnManager.cs(22,35): error CS0161: 'MultiplayerCharacterSpawnManager.GetCharacterPrefab(Player)': not all code paths return a value


I assume this is close mostly because it only had one error in the console which is the one I didn't know how to fix because when I tried I ended up with 3-4 more errors and this one persisted so any advice would be appreciated.
Thanks
 
It's tough to see with the formatting but it doesn't look like your GetCharacterPrefab returns a value in the all cases. You should always be returning a character value.
 
So I fixed my error and returned a value and got the script to work kind of, I could play the game and then load the Pun Game Scene, the Debug.Log shows the proper playerSelectionNumber but the character didn't load and I got an error about no object set. So I figured that out- PhotonNetwork.Instantiate(PlayerPrefabs[(int)playerSelectionNumber].name, instantiatePosition, Quaternion.identity); needs to be connected- return m_Character; from your code in order to load the character prefab right? so this is where I am now

this is my next attempt-

public class MultiplayerCharacterSpawnManager : SpawnManagerBase
{
[Tooltip("A reference to the character that PUN should spawn. This character must be setup using the PUN Multiplayer Manager.")]
[SerializeField] protected GameObject m_Character;

public GameObject Character { get { return m_Character; } set { m_Character = value; } }
public GameObject[] PlayerPrefabs;
public Transform[] InstantiatePositions;

private int playerSelectionNumber;
private Vector3 instantiatePosition;

protected override int[GameObject] GetCharacterPrefab(Player newPlayer)
{
if (PhotonNetwork.IsConnectedAndReady)
{
if (PhotonNetwork.LocalPlayer.CustomProperties.TryGetValue(RIGame.PLAYER_SELECTION_NUMBER, out playerSelectionNumber))
{
UnityEngine.Debug.Log((int)playerSelectionNumber);

int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber;
Vector3 instantiatePosition = InstantiatePositions[actorNumber - 1].position;

PhotonNetwork.Instantiate(PlayerPrefabs[(int)playerSelectionNumber].name, instantiatePosition, Quaternion.identity);
}
}
return (m_Character = PlayerPrefabs[(int)playerSelectionNumber].name, instantiatePosition, Quaternion.identity);
}
}

Unitys error report from the console-

Assets\Scripts\Networking\MultiplayerCharacterSpawnManager.cs(24,28): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)

I think I understand the problem but I have no idea how to fix it or if fixing that will load the character prefab?
any advice would be appreciated.
Thanks
 
Last edited:
Top