EventCenter.cs
using System;
using Client.Event.EventArgs;
using Client.Event.EventHandler;
using Client.Object;
using UnityEngine;
namespace Client.Event
{
public class EventCenter : MonoBehaviour
{
#region 单例
private static readonly object Lock = new();
private static EventCenter _instance;
public static EventCenter Instance
{
get
{
lock (Lock)
{
if (_instance != null) return _instance;
_instance = FindObjectOfType<EventCenter>() ??
new GameObject("EventCenter").AddComponent<EventCenter>();
return _instance;
}
}
}
private void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(gameObject);
}
else
{
_instance = this;
}
}
#endregion
public event PlayerHpChangeEventHandler OnPlayerHpChange;
public event Action<ulong> OnPlayerDie;
public event TouchPlayerEventHandler OnTouchPlayer;
public int PlayerHpChange(int hp, ulong playerID)
{
if (OnPlayerHpChange == null) return hp;
var newHp = OnPlayerHpChange(new PlayerHpChangeEventArgs(hp, playerID));
if (newHp <= 0) PlayerDie(playerID);
return newHp;
}
private void PlayerDie(ulong playerID)
{
OnPlayerDie?.Invoke(playerID);
}
public Player TouchPlayer(Player player, ulong playerID)
{
return OnTouchPlayer?.Invoke(new TouchPlayerEventArgs(player, playerID));
}
}
}
PlayerHpChangeEventArgs.cs
namespace Client.Event.EventArgs
{
public class PlayerHpChangeEventArgs : System.EventArgs
{
public int Hp { get; }
public ulong PlayerID { get; }
public PlayerHpChangeEventArgs(int hp, ulong playerID)
{
Hp = hp;
PlayerID = playerID;
}
}
}
TouchPlayerEventArgs.cs
using Client.Object;
namespace Client.Event.EventArgs
{
public class TouchPlayerEventArgs : System.EventArgs
{
public Player Player { get; }
public ulong PlayerID { get; }
public TouchPlayerEventArgs(Player player, ulong playerID)
{
Player = player;
PlayerID = playerID;
}
}
}
PlayerHpChangeEventHandler.cs
using Client.Event.EventArgs;
namespace Client.Event.EventHandler
{
public delegate int PlayerHpChangeEventHandler(PlayerHpChangeEventArgs e);
}
TouchPlayerEventHandler.cs
using Client.Event.EventArgs;
using Client.Object;
namespace Client.Event.EventHandler
{
public delegate Player TouchPlayerEventHandler(TouchPlayerEventArgs e);
}
Player.cs
using Client.Event;
using Client.Event.EventArgs;
using Unity.Netcode;
using UnityEngine;
namespace Client.Object
{
public class Player : NetworkBehaviour
{
private int _hp = 4;
#region 订阅
private void OnEnable()
{
EventCenter.Instance.OnPlayerHpChange += HandlePlayerHpChange;
EventCenter.Instance.OnPlayerDie += HandlePlayerDie;
}
private void OnDisable()
{
EventCenter.Instance.OnPlayerHpChange -= HandlePlayerHpChange;
EventCenter.Instance.OnPlayerDie -= HandlePlayerDie;
}
#endregion
private int HandlePlayerHpChange(PlayerHpChangeEventArgs e)
{
Debug.Log("HandlePlayerHpChange");
if (e.PlayerID != GetPlayerID()) return e.Hp;
Debug.Log(_hp);
return _hp += e.Hp;
}
private void HandlePlayerDie(ulong playerID)
{
if (playerID == GetPlayerID())
{
Debug.Log("HandlePlayerDie");
}
}
public int GetPlayerHp()
{
return _hp;
}
public ulong GetPlayerID()
{
return NetworkManager.Singleton.LocalClientId;
}
}
}
Enemy.cs
using Client.Event;
using Client.Event.EventArgs;
using UnityEngine;
namespace Client.Object
{
public class Enemy : MonoBehaviour
{
private void OnEnable()
{
EventCenter.Instance.OnTouchPlayer += HandleTouchPlayer;
}
private void OnDisable()
{
EventCenter.Instance.OnTouchPlayer -= HandleTouchPlayer;
}
public int damage = 1;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.TryGetComponent<Player>(out var player))
{
EventCenter.Instance.TouchPlayer(player, player.GetPlayerID());
}
}
private Player HandleTouchPlayer(TouchPlayerEventArgs e)
{
Debug.Log("HandleTouchPlayer");
EventCenter.Instance.PlayerHpChange(-damage, e.PlayerID);
return e.Player;
}
}
}