(Feat) Bed Systeme
This commit is contained in:
@@ -151,6 +151,7 @@ namespace Ashwild.Player
|
||||
public static event Action Died;
|
||||
public static event Action Respawned;
|
||||
public static event Action<bool> DeathChanged;
|
||||
public static event Action<Vector3, Quaternion> RespawnPointChanged; // the local player's respawn pose was reassigned (e.g. claimed a bed)
|
||||
|
||||
// ============================================================
|
||||
// Network / session events
|
||||
@@ -318,6 +319,16 @@ namespace Ashwild.Player
|
||||
DeathChanged?.Invoke(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reassigns the local player's respawn pose (e.g. after claiming a bed). Owner-side only;
|
||||
/// the pose is pure local state and is never networked — each client keeps its own.
|
||||
/// </summary>
|
||||
public static void RaiseRespawnPointChanged(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
Log(nameof(RespawnPointChanged));
|
||||
RespawnPointChanged?.Invoke(position, rotation);
|
||||
}
|
||||
|
||||
public static void RaiseSessionStarting() { Log(nameof(SessionStarting)); SessionStarting?.Invoke(); }
|
||||
public static void RaiseSessionStarted(string code)
|
||||
{
|
||||
|
||||
@@ -2,12 +2,25 @@ using UnityEngine;
|
||||
|
||||
namespace Ashwild.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Owns the local player's death-and-return. It flips locomotion into its dead state when the
|
||||
/// player dies, and on <see cref="Respawn"/> teleports the body back to the current respawn pose,
|
||||
/// revives the stats and clears the dead state. The respawn pose starts at the assigned spawn
|
||||
/// point (or wherever the player begins) and is reassigned live when the player claims a bed —
|
||||
/// pushed in over the bus, so it stays pure local state that never crosses the wire (§3).
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class PlayerLifecycle : MonoBehaviour
|
||||
{
|
||||
#region Serialized Fields
|
||||
|
||||
[Header("Spawn point (auto-captured at scene start if left empty)")]
|
||||
[SerializeField] private Transform spawnPoint;
|
||||
|
||||
#endregion
|
||||
|
||||
#region State
|
||||
|
||||
private PlayerLocomotion locomotion;
|
||||
private Rigidbody rb;
|
||||
|
||||
@@ -15,12 +28,23 @@ namespace Ashwild.Player
|
||||
private Quaternion spawnRotation;
|
||||
private bool isDead;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Lifecycle
|
||||
|
||||
/// <summary>
|
||||
/// Caches the sibling components the respawn drives.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
locomotion = GetComponent<PlayerLocomotion>();
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Seeds the respawn pose from the assigned spawn point, or the player's starting pose when
|
||||
/// none is set, so a death before any bed is claimed still returns somewhere valid.
|
||||
/// </summary>
|
||||
private void Start()
|
||||
{
|
||||
if (spawnPoint != null)
|
||||
@@ -35,9 +59,31 @@ namespace Ashwild.Player
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable() { PlayerEvents.Died += OnDied; }
|
||||
private void OnDisable() { PlayerEvents.Died -= OnDied; }
|
||||
/// <summary>
|
||||
/// Subscribes to death and to respawn-point reassignments (claiming a bed).
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
PlayerEvents.Died += OnDied;
|
||||
PlayerEvents.RespawnPointChanged += HandleRespawnPointChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes — mirrors OnEnable exactly.
|
||||
/// </summary>
|
||||
private void OnDisable()
|
||||
{
|
||||
PlayerEvents.Died -= OnDied;
|
||||
PlayerEvents.RespawnPointChanged -= HandleRespawnPointChanged;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Freezes the player into its dead state once, ignoring repeat death events.
|
||||
/// </summary>
|
||||
private void OnDied()
|
||||
{
|
||||
if (isDead) return;
|
||||
@@ -45,6 +91,21 @@ namespace Ashwild.Player
|
||||
if (locomotion != null) locomotion.SetDead(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adopts a new respawn pose pushed over the bus (the player claimed a bed). Local state
|
||||
/// only — the respawn location is never networked, so each client keeps its own.
|
||||
/// </summary>
|
||||
private void HandleRespawnPointChanged(Vector3 position, Quaternion rotation)
|
||||
=> SetSpawnPoint(position, rotation);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public API
|
||||
|
||||
/// <summary>
|
||||
/// Returns the player to the current respawn pose: zeroes momentum, teleports the body,
|
||||
/// revives the stats and clears the dead state.
|
||||
/// </summary>
|
||||
public void Respawn()
|
||||
{
|
||||
if (rb != null)
|
||||
@@ -52,8 +113,7 @@ namespace Ashwild.Player
|
||||
rb.linearVelocity = Vector3.zero;
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
transform.position = spawnPosition;
|
||||
transform.rotation = spawnRotation;
|
||||
transform.SetPositionAndRotation(spawnPosition, spawnRotation);
|
||||
|
||||
if (PlayerStats.Instance != null) PlayerStats.Instance.Revive();
|
||||
if (locomotion != null) locomotion.SetDead(false);
|
||||
@@ -61,18 +121,15 @@ namespace Ashwild.Player
|
||||
isDead = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the respawn pose directly with a world position and rotation.
|
||||
/// </summary>
|
||||
public void SetSpawnPoint(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
spawnPosition = position;
|
||||
spawnRotation = rotation;
|
||||
}
|
||||
|
||||
public void SetSpawnPoint(Transform t)
|
||||
{
|
||||
if (t == null) return;
|
||||
spawnPoint = t;
|
||||
spawnPosition = t.position;
|
||||
spawnRotation = t.rotation;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user