figured I’d add some documentation here as well since I almost lost this all 3 nights ago. Here’s the full arenamanager and teleport script just incase I get sloppy again!
using UnityEngine;
using UnityEngine.UI;
using Mirror;
using System.Collections.Generic;
namespace GameZero
{
[DisallowMultipleComponent]
public class ArenaManager : NetworkBehaviour
{
[SerializeField] private bool allowSolo;
[SerializeField] private Instance arena1;
[SerializeField] private Instance arena2;
[SerializeField] private Instance arena3;
[SerializeField] private Instance arena4;
[SerializeField] private GameObject preview1Prefab;
[SerializeField] private GameObject preview2Prefab;
[SerializeField] private GameObject preview3Prefab;
[SerializeField] private GameObject preview4Prefab;
[SyncVar] public int instanceId = -1;
private RawImage selectedPreview;
private Instance selectedArena;
public static ArenaManager singleton;
private void Awake()
{
// Initialize singleton
if (singleton == null) singleton = this;
}
private void Start()
{
// Hide all preview images at start
preview1Prefab.SetActive(false);
preview2Prefab.SetActive(false);
preview3Prefab.SetActive(false);
preview4Prefab.SetActive(false);
}
[Command(requiresAuthority = false)]
public void CmdSetSelectedArena(int instanceId)
{
Instance arena = GetInstanceTemplate(instanceId);
if (arena != null)
{
GameObject previewPrefab = GetPreviewPrefabForArena(arena);
// Update the selected arena on the client only
selectedArena = arena;
selectedPreview = previewPrefab.GetComponent<RawImage>();
this.instanceId = instanceId;
// Show the preview image of the selected arena
previewPrefab.SetActive(true);
// Hide the preview images of other arenas
if (arena != arena1) preview1Prefab.SetActive(false);
if (arena != arena2) preview2Prefab.SetActive(false);
if (arena != arena3) preview3Prefab.SetActive(false);
if (arena != arena4) preview4Prefab.SetActive(false);
// Update the preview images on all clients
imagepreviewsRpc();
}
}
[ClientRpc]
public void imagepreviewsRpc()
{
if (instanceId == 1)
preview1Prefab.SetActive(selectedPreview == preview1Prefab.GetComponent<RawImage>());
else if (instanceId == 2)
preview2Prefab.SetActive(selectedPreview == preview2Prefab.GetComponent<RawImage>());
else if (instanceId == 3)
preview3Prefab.SetActive(selectedPreview == preview3Prefab.GetComponent<RawImage>());
else if (instanceId == 4)
preview4Prefab.SetActive(selectedPreview == preview4Prefab.GetComponent<RawImage>());
}
private GameObject GetPreviewPrefabForArena(Instance arena)
{
if (arena == arena1)
return preview1Prefab;
else if (arena == arena2)
return preview2Prefab;
else if (arena == arena3)
return preview3Prefab;
else if (arena == arena4)
return preview4Prefab;
else
return null;
}
public void OnArena1ButtonClicked()
{
Debug.Log("Arena 1 selected");
CmdSetSelectedArena(arena1.instanceId);
}
public void OnArena2ButtonClicked()
{
Debug.Log("Arena 2 selected");
CmdSetSelectedArena(arena2.instanceId);
}
public void OnArena3ButtonClicked()
{
Debug.Log("Arena 3 selected");
CmdSetSelectedArena(arena3.instanceId);
}
public void OnArena4ButtonClicked()
{
Debug.Log("Arena 4 selected");
CmdSetSelectedArena(arena4.instanceId);
}
public void OnRandomArenaButtonClicked()
{
Instance[] arenas = new Instance[] { arena1, arena2, arena3, arena4 };
int index = Random.Range(0, arenas.Length);
CmdSetSelectedArena(arenas[index].instanceId);
}
public void CreateInstance()
{
if (selectedArena != null)
{
arenaonoff.onoff.SetArena(selectedArena.arenaName);
arenaonoff.onoff.StartArena();
}
else
{
Debug.LogError("No selected arena!");
}
}
public Instance GetInstanceTemplate(int instanceId)
{
Debug.Log("GetInstanceTemplate called with instanceId = " + instanceId);
List<Instance> availableInstances = new List<Instance> { arena1, arena2, arena3, arena4 };
foreach (Instance availableInstance in availableInstances)
{
Debug.Log("Checking instance: " + availableInstance.instanceId);
if (availableInstance.instanceId == instanceId)
{
Debug.Log("Found instance: " + availableInstance);
return availableInstance;
}
}
Debug.Log("Instance not found for instanceId = " + instanceId);
return null;
}
}
}
using UnityEngine;
using Mirror;
using HeathenEngineering.SteamworksIntegration;
using System;
using System.Linq;
namespace GameZero
{
[DisallowMultipleComponent]
public class PlayerArenaNpcTeleport : NetworkBehaviour
{
[Header("Components")]
public Player player;
[SyncVar] public int partyIdToJoin = -1; // initialize to -1 to indicate that it is not set yet
private Vector3 targetPos;
public static PlayerArenaNpcTeleport singleton;
// Start is called before the first frame update
void Awake()
{
// initialize singleton
if (singleton == null) singleton = this;
}
[Command(requiresAuthority = false)]
public void CmdLobbyCreator()
{
Debug.Log("Player assigned: " + player.name);
if (player != null) { PartySystem.FormParty(player.name); }
partyIdToJoin = player.party.party.partyId;
Debug.Log($"partyId = {partyIdToJoin}");
}
[Command(requiresAuthority = false)]
public void CmdLobbyJoiner()
{
Player[] players = FindObjectsOfType<Player>();
// loop through each player and do something with them
foreach (Player player in players)
{
if (!player.party.InParty())
{
PartySystem.AddToParty(partyIdToJoin, player.name);
}
}
}
[Command(requiresAuthority = false)]
public void CmdPartySetup()
{
//ArenaManager am = GameObject.FindWithTag("GameManager").GetComponent<ArenaManager>();
Instance instanceTemplate = ArenaManager.singleton.GetInstanceTemplate(ArenaManager.singleton.instanceId);
Debug.Log("Cmdpartysetup called");
Debug.Log("instanceTemplate = " + instanceTemplate);
Player[] playersInParty = PartySystem.GetPlayersInParty(partyIdToJoin);
Debug.Log("Number of players in party: " + playersInParty.Length);
foreach (Player player in playersInParty)
{
Debug.Log("player name = " + player.name);
// loop through each player and do something with them
Debug.Log("player isServer: " + player.isServer + " hasAuthority: " + player.hasAuthority + " isClient: " + player.isClient + " isLocalPlayer: " + player.isLocalPlayer);
// collider might be in player's bone structure. look in parents.
if (player != null)
{
Debug.Log("player is not null");
// only call this for server and for local player. not for other
// players on the client. no need in locally creating their
// instances too.
if (player.isServer || player.isLocalPlayer)
{
Debug.Log("player is server or local player");
// required level?
if (player.level.current >= instanceTemplate.requiredLevel)
{
Debug.Log("player met level requirement");
// can only enter with a party
if (player.party.InParty())
{
Debug.Log("player is in a party");
// is there an instance for the player's party yet?
if (instanceTemplate.instances.TryGetValue(player.party.party.partyId, out Instance existingInstance))
{
// teleport player to instance entry
if (player.isServer)
{
Debug.Log("player has authority!!");
Vector3 entry1Pos = existingInstance.entry1?.position ?? Vector3.zero;
Vector3 entry2Pos = existingInstance.entry2?.position ?? Vector3.zero;
// Determine the target position for the player based on the player index
int playerIndex = Array.IndexOf(playersInParty, player);
Vector3 targetPos = (playerIndex % 2 == 0) ? entry2Pos : entry1Pos;
// Call the CmdWarpToEntry() method to move the player to the target position
if (player.isServer || (player.isClient && player.hasAuthority))
{
// Call the CmdWarpDrive() method only if the player is owned by a client
player.movement.Warp(targetPos);
}
Debug.Log("Teleporting " + player.name + " to existing instance=" + existingInstance.name + " with partyId=" + player.party.party.partyId);
}
}
// otherwise create a new one
else
{
Instance instance = Instance.CreateInstance(instanceTemplate, player.party.party.partyId);
NetworkServer.Spawn(instance.gameObject);
if (instance != null)
{
Debug.Log("instance is not null");
// teleport player to instance entry
Debug.Log("player isServer: " + player.isServer + " hasAuthority: " + player.hasAuthority + " isClient: " + player.isClient + " isLocalPlayer: " + player.isLocalPlayer + "isowned" + player.isOwned);
if (player.isServer)
{
Debug.Log("has authority");
// Get the entry positions for the instance
Vector3 entry1Pos = instance.entry1?.position ?? Vector3.zero;
Vector3 entry2Pos = instance.entry2?.position ?? Vector3.zero;
// Determine the target position for the player based on the player index
int playerIndex = Array.IndexOf(playersInParty, player);
Vector3 targetPos = (playerIndex % 2 == 0) ? entry2Pos : entry1Pos;
// Call the CmdWarpToEntry() method to move the player to the target position
if (player.isServer || (player.isClient && player.hasAuthority))
{
if (player.GetComponent<NetworkIdentity>().hasAuthority)
{
Debug.Log("client has authority for cmdwarpdrive");
// Check if client is still connected
if (!NetworkServer.connections.ContainsKey(player.GetComponent<NetworkIdentity>().connectionToClient.connectionId))
{
// Client has disconnected, do something
Debug.Log("client has disconnected, do something!");
}
else
{
// Call the CmdWarpDrive() method only if the player is owned by a client
player.movement.Warp(targetPos);
Debug.Log("player passed all checks, warping successfully");
}
}
Debug.Log("player didn't have authority, still warping just in case");
player.movement.Warp(targetPos);
}
Debug.Log("Teleporting " + player.name + " to new instance=" + instance.name + " with partyId=" + player.party.party.partyId);
}
else { Debug.Log("player is not server!!"); }
}
else if (player.isServer) player.chat.TargetMsgInfo("There are already too many " + instance.name + " instances. Please try again later.");
}
}
else
{
Debug.LogError("No existing instance found!");
}
}
}
}
}
}
}
}