``` chore(config): 更新配置文件设置 - 调整项目配置参数 - 优化构建流程设置 - 更新依赖包版本信息 ``` 注意:由于未提供具体的代码差异信息,此为示例模板。实际使用时请根据具体变更内容调整type、scope、subject和body部分。
141 lines
3.4 KiB
C#
141 lines
3.4 KiB
C#
using UnityEngine;
|
|
|
|
public class StatusEffectController : MonoBehaviour
|
|
{
|
|
[Header("通用眩晕显示")]
|
|
[SerializeField] private bool showStunIndicator = true;
|
|
[SerializeField] private float indicatorHeight = 0.35f;
|
|
[SerializeField] private float indicatorSize = 0.5f;
|
|
|
|
private Animator animator;
|
|
private float stunnedRemaining;
|
|
private float animatorSpeedBeforeStun = 1f;
|
|
private GameObject stunIndicator;
|
|
private Transform indicatorTransform;
|
|
|
|
public bool IsStunned => stunnedRemaining > 0f;
|
|
public float StunnedRemaining => Mathf.Max(0f, stunnedRemaining);
|
|
|
|
private void Awake()
|
|
{
|
|
animator = GetComponent<Animator>();
|
|
}
|
|
|
|
public void ApplyStun(float duration)
|
|
{
|
|
if (duration <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!IsStunned && animator != null)
|
|
{
|
|
animatorSpeedBeforeStun = animator.speed;
|
|
}
|
|
|
|
stunnedRemaining = Mathf.Max(stunnedRemaining, duration);
|
|
if (animator != null)
|
|
{
|
|
animator.speed = 0f;
|
|
}
|
|
|
|
if (showStunIndicator)
|
|
{
|
|
EnsureIndicator();
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!IsStunned)
|
|
{
|
|
return;
|
|
}
|
|
|
|
stunnedRemaining -= Time.deltaTime;
|
|
if (animator != null)
|
|
{
|
|
animator.speed = 0f;
|
|
}
|
|
|
|
if (stunnedRemaining <= 0f)
|
|
{
|
|
stunnedRemaining = 0f;
|
|
if (animator != null)
|
|
{
|
|
animator.speed = Mathf.Max(0.01f, animatorSpeedBeforeStun);
|
|
}
|
|
DestroyIndicator();
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (indicatorTransform == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Bounds bounds = new Bounds(transform.position, Vector3.zero);
|
|
Renderer[] renderers = GetComponentsInChildren<Renderer>(true);
|
|
if (renderers.Length > 0)
|
|
{
|
|
bounds = renderers[0].bounds;
|
|
for (int i = 1; i < renderers.Length; i++)
|
|
{
|
|
bounds.Encapsulate(renderers[i].bounds);
|
|
}
|
|
}
|
|
|
|
indicatorTransform.position = new Vector3(
|
|
bounds.center.x,
|
|
bounds.max.y + indicatorHeight,
|
|
bounds.center.z);
|
|
|
|
Camera camera = Camera.main;
|
|
if (camera != null)
|
|
{
|
|
indicatorTransform.rotation = Quaternion.LookRotation(
|
|
camera.transform.position - indicatorTransform.position,
|
|
camera.transform.up)
|
|
* Quaternion.Euler(0f, 0f, Time.unscaledTime * 180f);
|
|
}
|
|
}
|
|
|
|
private void EnsureIndicator()
|
|
{
|
|
if (stunIndicator != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
stunIndicator = new GameObject("StunIndicator_Star");
|
|
indicatorTransform = stunIndicator.transform;
|
|
|
|
TextMesh text = stunIndicator.AddComponent<TextMesh>();
|
|
text.text = "★";
|
|
text.anchor = TextAnchor.MiddleCenter;
|
|
text.alignment = TextAlignment.Center;
|
|
text.fontSize = 64;
|
|
text.characterSize = indicatorSize;
|
|
text.fontStyle = FontStyle.Bold;
|
|
text.color = new Color(1f, 0.85f, 0.05f, 1f);
|
|
}
|
|
|
|
private void DestroyIndicator()
|
|
{
|
|
if (stunIndicator != null)
|
|
{
|
|
Destroy(stunIndicator);
|
|
}
|
|
|
|
stunIndicator = null;
|
|
indicatorTransform = null;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
DestroyIndicator();
|
|
}
|
|
}
|