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#
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;
|
||
|
}
|
||
|
}
|
||
|
}
|