您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

127 行
3.8 KiB

using System;
using Unity.Multiplayer.Samples.Utilities;
using Unity.Netcode;
using UnityEngine;
namespace Unity.Multiplayer.Samples.BossRoom.Visual
{
/// <summary>
/// Visualization class for Breakables. Breakables work by swapping a "broken" prefab at the moment of breakage. The broken prefab
/// then handles the pesky details of actually falling apart.
/// </summary>
[RequireComponent(typeof(NetcodeHooks))]
public class ClientBreakableVisualization : MonoBehaviour
{
[SerializeField]
private GameObject m_BrokenPrefab;
[SerializeField]
[Tooltip("If set, will be used instead of BrokenPrefab when new players join, skipping transition effects.")]
private GameObject m_PrebrokenPrefab;
[SerializeField]
[Tooltip("We use this transform's position and rotation when creating the prefab. (Defaults to self)")]
private Transform m_BrokenPrefabPos;
[SerializeField]
private GameObject[] m_UnbrokenGameObjects;
[SerializeField]
private NetworkBreakableState m_NetState;
private GameObject m_CurrentBrokenVisualization;
NetcodeHooks m_Hooks;
void Awake()
{
m_Hooks = GetComponent<NetcodeHooks>();
m_Hooks.OnNetworkSpawnHook += OnSpawn;
m_Hooks.OnNetworkDespawnHook += OnDespawn;
}
void OnSpawn()
{
if (!NetworkManager.Singleton.IsClient)
{
enabled = false;
}
else
{
m_NetState.IsBroken.OnValueChanged += OnBreakableStateChanged;
if (m_NetState.IsBroken.Value == true)
{
PerformBreak(true);
}
}
}
private void OnBreakableStateChanged(bool wasBroken, bool isBroken)
{
if (!wasBroken && isBroken)
{
PerformBreak(false);
}
else if (wasBroken && !isBroken)
{
PerformUnbreak();
}
}
void OnDespawn()
{
if (m_NetState)
{
m_NetState.IsBroken.OnValueChanged -= OnBreakableStateChanged;
}
}
void OnDestroy()
{
m_Hooks.OnNetworkSpawnHook -= OnSpawn;
m_Hooks.OnNetworkDespawnHook -= OnDespawn;
}
private void PerformBreak(bool onStart)
{
foreach (var gameObject in m_UnbrokenGameObjects)
{
if (gameObject)
gameObject.SetActive(false);
}
if (m_CurrentBrokenVisualization)
Destroy(m_CurrentBrokenVisualization); // just a safety check, should be null when we get here
GameObject brokenPrefab = (onStart && m_PrebrokenPrefab != null) ? m_PrebrokenPrefab : m_BrokenPrefab;
if (brokenPrefab)
{
m_CurrentBrokenVisualization = Instantiate(brokenPrefab, m_BrokenPrefabPos.position, m_BrokenPrefabPos.rotation, transform);
}
}
private void PerformUnbreak()
{
if (m_CurrentBrokenVisualization)
{
Destroy(m_CurrentBrokenVisualization);
}
foreach (var gameObject in m_UnbrokenGameObjects)
{
if (gameObject)
gameObject.SetActive(true);
}
}
#if UNITY_EDITOR
private void OnValidate()
{
if (!m_NetState)
m_NetState = GetComponent<NetworkBreakableState>();
if (!m_BrokenPrefabPos)
m_BrokenPrefabPos = transform;
}
#endif
}
}