Files
daluandou/Assets/Script/ShieldBarrier.cs
T
2026-09-01 18:17:34 +08:00

139 lines
3.1 KiB
C#

using UnityEngine;
public class ShieldBarrier : MonoBehaviour
{
[Header("盾牌状态")]
[Min(0f)]
public float maxDurability = 220f;
[Min(0f)]
public float currentDurability;
[Min(0f)]
public float duration = 6f;
[Range(-1f, 1f)]
public float frontDotThreshold = 0.15f;
private UnitBase owner;
private Collider barrierCollider;
private float remainingTime;
public UnitBase Owner => owner;
public float CurrentDurability => currentDurability;
public bool IsActive =>
isActiveAndEnabled &&
barrierCollider != null &&
barrierCollider.enabled &&
currentDurability > 0f &&
remainingTime > 0f;
public void Configure(UnitBase shieldOwner, Collider shieldCollider)
{
owner = shieldOwner;
barrierCollider = shieldCollider;
}
public void Refresh(float durability, float activeDuration, Vector3 localPosition, Vector3 localSize)
{
if (barrierCollider == null)
{
barrierCollider = GetComponent<Collider>();
}
if (owner == null)
{
owner = GetComponentInParent<UnitBase>();
}
transform.localPosition = localPosition;
transform.localRotation = Quaternion.identity;
BoxCollider boxCollider = barrierCollider as BoxCollider;
if (boxCollider != null)
{
boxCollider.center = Vector3.zero;
boxCollider.size = localSize;
boxCollider.isTrigger = true;
}
maxDurability = Mathf.Max(0.01f, durability);
currentDurability = maxDurability;
duration = Mathf.Max(0.01f, activeDuration);
remainingTime = duration;
gameObject.SetActive(true);
if (barrierCollider != null)
{
barrierCollider.enabled = true;
}
}
public bool TryBlock(GameObject attacker, float damage)
{
if (!IsActive || damage <= 0f)
{
return false;
}
if (attacker != null && !IsIncomingFromFront(attacker))
{
return false;
}
currentDurability -= damage;
if (currentDurability <= 0f)
{
DisableBarrier();
}
return true;
}
public void DisableBarrier()
{
currentDurability = 0f;
remainingTime = 0f;
if (barrierCollider != null)
{
barrierCollider.enabled = false;
}
gameObject.SetActive(false);
}
private void Update()
{
if (!IsActive)
{
return;
}
remainingTime -= Time.deltaTime;
if (remainingTime <= 0f)
{
DisableBarrier();
}
}
private bool IsIncomingFromFront(GameObject attacker)
{
if (owner == null)
{
return true;
}
Vector3 direction = attacker.transform.position - owner.transform.position;
direction.y = 0f;
if (direction.sqrMagnitude <= 0.0001f)
{
return true;
}
return Vector3.Dot(owner.transform.forward, direction.normalized) >= frontDotThreshold;
}
}