You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
3.4 KiB
C#

1 week ago
using System;
using System.Collections.Generic;
using Unity.BossRoom.ConnectionManagement;
using Unity.Multiplayer.Samples.BossRoom;
using Unity.Netcode;
using UnityEngine;
namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
{
/// <summary>
/// Attached to the player-characters' prefab, this maintains a list of active ServerCharacter objects for players.
/// </summary>
/// <remarks>
/// This is an optimization. In server code you can already get a list of players' ServerCharacters by
/// iterating over the active connections and calling GetComponent() on their PlayerObject. But we need
/// to iterate over all players quite often -- the monsters' IdleAIState does so in every Update() --
/// and all those GetComponent() calls add up! So this optimization lets us iterate without calling
/// GetComponent(). This will be refactored with a ScriptableObject-based approach on player collection.
/// </remarks>
[RequireComponent(typeof(ServerCharacter))]
public class PlayerServerCharacter : NetworkBehaviour
{
static List<ServerCharacter> s_ActivePlayers = new List<ServerCharacter>();
[SerializeField]
ServerCharacter m_CachedServerCharacter;
public override void OnNetworkSpawn()
{
if (IsServer)
{
s_ActivePlayers.Add(m_CachedServerCharacter);
}
else
{
enabled = false;
}
}
void OnDisable()
{
s_ActivePlayers.Remove(m_CachedServerCharacter);
}
public override void OnNetworkDespawn()
{
if (IsServer)
{
var movementTransform = m_CachedServerCharacter.Movement.transform;
SessionPlayerData? sessionPlayerData = SessionManager<SessionPlayerData>.Instance.GetPlayerData(OwnerClientId);
if (sessionPlayerData.HasValue)
{
var playerData = sessionPlayerData.Value;
playerData.PlayerPosition = movementTransform.position;
playerData.PlayerRotation = movementTransform.rotation;
playerData.CurrentHitPoints = m_CachedServerCharacter.HitPoints;
playerData.HasCharacterSpawned = true;
SessionManager<SessionPlayerData>.Instance.SetPlayerData(OwnerClientId, playerData);
}
}
}
/// <summary>
/// Returns a list of all active players' ServerCharacters. Treat the list as read-only!
/// The list will be empty on the client.
/// </summary>
public static List<ServerCharacter> GetPlayerServerCharacters()
{
return s_ActivePlayers;
}
/// <summary>
/// Returns the ServerCharacter owned by a specific client. Always returns null on the client.
/// </summary>
/// <param name="ownerClientId"></param>
/// <returns>The ServerCharacter owned by the client, or null if no ServerCharacter is found</returns>
public static ServerCharacter GetPlayerServerCharacter(ulong ownerClientId)
{
foreach (var playerServerCharacter in s_ActivePlayers)
{
if (playerServerCharacter.OwnerClientId == ownerClientId)
{
return playerServerCharacter;
}
}
return null;
}
}
}