UFPS PUN spawns two players instead of one.

Hello,

For some reason it spawns two instances of the player instead of just one i've tested the demo scene and it works fine with my custom player so i'm at a loss. The first player spawns fine then after a few seconds another copy of the player spawns.

Code:
IndexOutOfRangeException: Index was outside the bounds of the array.
Opsive.UltimateCharacterController.Demo.DemoManager.SelectStartingPerspective (System.Boolean firstPersonPerspective, System.Boolean teleport) (at Assets/Opsive/UltimateCharacterController/Demo/Scripts/DemoManager.cs:463)
Opsive.UltimateCharacterController.Demo.DemoManager.InitializeCharacter (UnityEngine.GameObject character, System.Boolean selectStartingPerspective, System.Boolean teleport) (at Assets/Opsive/UltimateCharacterController/Demo/Scripts/DemoManager.cs:274)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Demo.PunDemoManager.OnPlayerEnteredRoom (Photon.Realtime.Player player, UnityEngine.GameObject character) (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Demo/Scripts/PunDemoManager.cs:45)
Opsive.Shared.Events.InvokableAction`2[T1,T2].Invoke (T1 arg1, T2 arg2) (at <27da9e1afec54f2fb2a11d46a234f9df>:0)
Opsive.Shared.Events.EventHandler.ExecuteEvent[T1,T2] (System.String eventName, T1 arg1, T2 arg2) (at <27da9e1afec54f2fb2a11d46a234f9df>:0)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game.SpawnManagerBase.SpawnPlayer (Photon.Realtime.Player newPlayer) (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Scripts/Game/SpawnManagerBase.cs:176)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game.SpawnManagerBase.Start () (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Scripts/Game/SpawnManagerBase.cs:95)

Code:
ArgumentException: An item with the same key has already been added. Key: 1
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <437ba245d8404784b9fbab9b439ac908>:0)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game.SpawnManagerBase.AddPhotonView (Photon.Pun.PhotonView photonView) (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Scripts/Game/SpawnManagerBase.cs:200)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game.SpawnManagerBase.SpawnPlayer (Photon.Realtime.Player newPlayer) (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Scripts/Game/SpawnManagerBase.cs:175)
CharacterSpawnFixer.FixSpawn () (at Assets/TFSB/Scripts/CharacterSpawnFixer.cs:39)
 
CharacterSpawnFixer:

C#:
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

public class CharacterSpawnFixer : MonoBehaviour
{
    [SerializeField]
    private SpawnManagerBase spawnManagerBase;

    private void Start()
    {
        if (!PhotonNetwork.IsMasterClient)
            return;

        Invoke(nameof(FixSpawn), 1f);
    }

    private void FixSpawn()
    {
        var characters = GameObject.FindGameObjectsWithTag("Player");
       Player[] characterPlayers = characters.Select(i => i.GetComponent<PhotonView>()).Where(i => i != null).Select(i => i.Owner)
            .ToArray();

        var players = PhotonNetwork.PlayerList;

        foreach (var player in players)
        {
            if (characterPlayers.Where(i => i.UserId == player.UserId).ToArray().Length > 0)
            {
                Debug.Log("Player found, skip: " + player.NickName);
                continue;
            }

            Debug.Log("Player not found, spawn: " + player.NickName);
            spawnManagerBase.SpawnPlayer(player);
        }
    }
}
 
SpawnManagerBase: Lines 141-213

Code:
// Instantiate the player and let the PhotonNetwork know of the new character.
            var player = GameObject.Instantiate(GetCharacterPrefab(newPlayer), spawnPosition, spawnRotation);
            var photonView = player.GetComponent<PhotonView>();
            photonView.ViewID = PhotonNetwork.AllocateViewID(newPlayer.ActorNumber);
            if (photonView.ViewID > 0) {
                // As of PUN 2.19, when the ViewID is allocated the Owner is not set. Set the owner to null and then to the player so the owner will correctly be assigned.
                photonView.TransferOwnership(null);
                photonView.TransferOwnership(newPlayer);

                // The character has been created. All other clients need to instantiate the character as well.
                var data = new object[]
                {
                    player.transform.position, player.transform.rotation, photonView.ViewID, newPlayer.ActorNumber
                };
                m_RaiseEventOptions.TargetActors = null;
                PhotonNetwork.RaiseEvent(PhotonEventIDs.PlayerInstantiation, data, m_RaiseEventOptions, m_ReliableSendOption);

                // The new player should instantiate all existing characters in addition to their character.
                if (newPlayer != PhotonNetwork.LocalPlayer) {
                    // Deactivate the character until the remote machine has the chance to create it. This will prevent the character from
                    // being active on the Master Client without being able to be controlled.
                    player.SetActive(false);

                    data = new object[m_PlayerCount * 4];
                    for (int i = 0; i < m_PlayerCount; ++i) {
                        data[i * 4] = m_Players[i].transform.position;
                        data[i * 4 + 1] = m_Players[i].transform.rotation;
                        data[i * 4 + 2] = m_Players[i].ViewID;
                        data[i * 4 + 3] = m_Players[i].Owner.ActorNumber;
                    }
                    m_RaiseEventOptions.TargetActors = new int[] { newPlayer.ActorNumber };
                    PhotonNetwork.RaiseEvent(PhotonEventIDs.PlayerInstantiation, data, m_RaiseEventOptions, m_ReliableSendOption);
                }

                AddPhotonView(photonView);
                EventHandler.ExecuteEvent("OnPlayerEnteredRoom", photonView.Owner, photonView.gameObject);
            } else {
                Debug.LogError("Failed to allocate a ViewId.");
                Destroy(player);
            }
        }

        /// <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 abstract GameObject GetCharacterPrefab(Player newPlayer);

        /// <summary>
        /// Adds the PhotonView to the player list.
        /// </summary>
        /// <param name="photonView">The PhotonView that should be added.</param>
        private void AddPhotonView(PhotonView photonView)
        {
            if (m_PlayerCount == m_Players.Length) {
                System.Array.Resize(ref m_Players, m_PlayerCount + 1);
            }
            m_Players[m_PlayerCount] = photonView;
            m_ActorNumberByPhotonViewIndex.Add(photonView.OwnerActorNr, m_PlayerCount);
            m_PlayerCount++;
        }

        /// <summary>
        /// Called when a remote player entered the room. This Player is already added to the playerlist.
        /// </summary>
        /// <param name="newPlayer">The player that entered the room.</param>
        public override void OnPlayerEnteredRoom(Player newPlayer)
        {
            base.OnPlayerEnteredRoom(newPlayer);

            SpawnPlayer(newPlayer);
        }
 
Top