146 lines
4.3 KiB
C#
146 lines
4.3 KiB
C#
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 印记效果控制器
|
|||
|
/// </summary>
|
|||
|
// 由于常规特效ParticleCleaner需要Hack的部分太多,暂时通过全面重写的方式实现重用特效系统
|
|||
|
public class MarkSfxController : MonoBehaviour, IParticleCleaner
|
|||
|
{
|
|||
|
public float DelayRecoveryTime
|
|||
|
{
|
|||
|
get { return IsDetonated ? delayTime : 0f; }
|
|||
|
}
|
|||
|
public float delayTime = 1.033f;
|
|||
|
private readonly List<MarkSfxCloneController> _cloneList = new List<MarkSfxCloneController>();
|
|||
|
private float _currentRotation;
|
|||
|
private bool _clean;
|
|||
|
public float rotateSpeed = 540f;
|
|||
|
public GameObject source;
|
|||
|
public int TargetCount { get; set; }
|
|||
|
private int _currentCount;
|
|||
|
public bool IsDetonated { get; private set; }
|
|||
|
|
|||
|
private void Start()
|
|||
|
{
|
|||
|
source.SetActive(false);
|
|||
|
CleanState();
|
|||
|
}
|
|||
|
|
|||
|
private void Update()
|
|||
|
{
|
|||
|
if (_clean)
|
|||
|
{
|
|||
|
_clean = false;
|
|||
|
CleanState();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void CleanState()
|
|||
|
{
|
|||
|
IsDetonated = false;
|
|||
|
for (var i = 0; i < _cloneList.Count; i++)
|
|||
|
_cloneList[i].Detonate(false);
|
|||
|
}
|
|||
|
|
|||
|
private void OnDisable()
|
|||
|
{
|
|||
|
_clean = true;
|
|||
|
IsDetonated = false;
|
|||
|
_currentCount = 0;
|
|||
|
for (var i = 0; i < _cloneList.Count; i++)
|
|||
|
{
|
|||
|
_cloneList[i].Clean();
|
|||
|
_cloneList[i].gameObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void LateUpdate()
|
|||
|
{
|
|||
|
if (!IsDetonated)
|
|||
|
{
|
|||
|
_currentRotation += rotateSpeed * Time.deltaTime;
|
|||
|
_currentRotation = CommonUtility.LoopFloat(_currentRotation, 0f, 360f);
|
|||
|
if (TargetCount != _currentCount)
|
|||
|
{
|
|||
|
_currentCount = TargetCount;
|
|||
|
for (var i = _cloneList.Count; i < _currentCount; i++)
|
|||
|
{
|
|||
|
var cloneObj = Instantiate(source);
|
|||
|
cloneObj.transform.SetParent(source.transform.parent, false);
|
|||
|
var clone = new MarkSfxCloneController(cloneObj);
|
|||
|
_cloneList.Add(clone);
|
|||
|
}
|
|||
|
|
|||
|
for (var i = 0; i < _cloneList.Count; i++)
|
|||
|
_cloneList[i].gameObject.SetActive(i < _currentCount);
|
|||
|
}
|
|||
|
}
|
|||
|
for (var i = 0; i < _currentCount; i++)
|
|||
|
_cloneList[i].SetRotation(_currentRotation + i * 360f / _currentCount);
|
|||
|
}
|
|||
|
|
|||
|
public void Detonate(bool isDetonate)
|
|||
|
{
|
|||
|
IsDetonated = isDetonate;
|
|||
|
// 特殊处理,反激活爆破由Clean来处理
|
|||
|
for (var i = 0; i < _currentCount; i++)
|
|||
|
_cloneList[i].Detonate(isDetonate);
|
|||
|
}
|
|||
|
|
|||
|
public void StartDelayRecovery()
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class MarkSfxCloneController
|
|||
|
{
|
|||
|
public const string idleEffect = "Idle";
|
|||
|
public const string activeEffect = "Active";
|
|||
|
private readonly GameObject _activeObject;
|
|||
|
private readonly GameObject _idleObject;
|
|||
|
|
|||
|
private readonly Animator _markAnimator;
|
|||
|
|
|||
|
public readonly GameObject gameObject;
|
|||
|
|
|||
|
public MarkSfxCloneController(GameObject gameObject)
|
|||
|
{
|
|||
|
this.gameObject = gameObject;
|
|||
|
_markAnimator = gameObject.GetComponentInChildren<Animator>();
|
|||
|
var idleTransform = gameObject.transform.Find(idleEffect);
|
|||
|
var activeTransform = gameObject.transform.Find(activeEffect);
|
|||
|
if (idleTransform != null)
|
|||
|
_idleObject = idleTransform.gameObject;
|
|||
|
if (activeTransform != null)
|
|||
|
_activeObject = activeTransform.gameObject;
|
|||
|
}
|
|||
|
|
|||
|
public void SetRotation(float degree)
|
|||
|
{
|
|||
|
var targetRotation = Quaternion.Euler(0f, degree, 0f);
|
|||
|
gameObject.transform.localRotation = targetRotation;
|
|||
|
}
|
|||
|
|
|||
|
public void Detonate(bool isDetonate)
|
|||
|
{
|
|||
|
if (isDetonate && _markAnimator != null)
|
|||
|
_markAnimator.SetBool("Detonate", true);
|
|||
|
if (_idleObject != null)
|
|||
|
_idleObject.SetActive(!isDetonate);
|
|||
|
if (_activeObject != null)
|
|||
|
_activeObject.SetActive(isDetonate);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 反激活时清空状态
|
|||
|
/// </summary>
|
|||
|
public void Clean()
|
|||
|
{
|
|||
|
//if (_markAnimator != null)
|
|||
|
// _markAnimator.SetBool("Detonate", false);
|
|||
|
if (_idleObject != null)
|
|||
|
_idleObject.SetActive(false);
|
|||
|
if (_activeObject != null)
|
|||
|
_activeObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|