139 lines
3.1 KiB
C#
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;
|
|
}
|
|
}
|