您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
127 行
3.8 KiB
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
|
|
}
|
|
}
|