您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
109 行
2.8 KiB
109 行
2.8 KiB
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace Unity.Multiplayer.Samples.BossRoom.Server
|
|
{
|
|
public class ServerTossedItem : NetworkBehaviour
|
|
{
|
|
[SerializeField]
|
|
int m_DamagePoints;
|
|
|
|
[SerializeField]
|
|
float m_HitRadius = 5f;
|
|
|
|
[SerializeField]
|
|
float m_KnockbackSpeed;
|
|
|
|
[SerializeField]
|
|
float m_KnockbackDuration;
|
|
|
|
[SerializeField]
|
|
LayerMask m_LayerMask;
|
|
|
|
bool m_Started;
|
|
|
|
const int k_MaxCollisions = 16;
|
|
|
|
Collider[] m_CollisionCache = new Collider[k_MaxCollisions];
|
|
|
|
[SerializeField]
|
|
float detonateAfterSeconds = 5f;
|
|
|
|
float m_DetonateAfterSeconds;
|
|
|
|
float m_DestroyAfterSeconds;
|
|
|
|
bool m_Detonated;
|
|
|
|
public UnityEvent detonatedCallback;
|
|
|
|
public override void OnNetworkSpawn()
|
|
{
|
|
if (!IsServer)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
m_Started = true;
|
|
m_Detonated = false;
|
|
|
|
m_DetonateAfterSeconds = Time.fixedTime + detonateAfterSeconds;
|
|
}
|
|
|
|
public override void OnNetworkDespawn()
|
|
{
|
|
m_Started = false;
|
|
m_Detonated = false;
|
|
}
|
|
|
|
void Detonate()
|
|
{
|
|
var hits = Physics.OverlapSphereNonAlloc(transform.position, m_HitRadius, m_CollisionCache, m_LayerMask);
|
|
|
|
for (int i = 0; i < hits; i++)
|
|
{
|
|
if (m_CollisionCache[i].gameObject.TryGetComponent(out IDamageable damageReceiver))
|
|
{
|
|
damageReceiver.ReceiveHP(null, -m_DamagePoints);
|
|
|
|
var serverCharacter = m_CollisionCache[i].gameObject.GetComponentInParent<ServerCharacter>();
|
|
if (serverCharacter)
|
|
{
|
|
serverCharacter.Movement.StartKnockback(transform.position, m_KnockbackSpeed, m_KnockbackDuration);
|
|
}
|
|
}
|
|
}
|
|
|
|
// send client RPC to detonate on clients
|
|
DetonateClientRpc();
|
|
|
|
m_Detonated = true;
|
|
}
|
|
|
|
[ClientRpc]
|
|
void DetonateClientRpc()
|
|
{
|
|
detonatedCallback?.Invoke();
|
|
}
|
|
|
|
void FixedUpdate()
|
|
{
|
|
if (!m_Started)
|
|
{
|
|
return; //don't do anything before OnNetworkSpawn has run.
|
|
}
|
|
|
|
if (!m_Detonated && m_DetonateAfterSeconds < Time.fixedTime)
|
|
{
|
|
Detonate();
|
|
|
|
// despawn after sending detonate RPC
|
|
var networkObject = gameObject.GetComponent<NetworkObject>();
|
|
networkObject.Despawn();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|