113 lines
3.1 KiB
C#
113 lines
3.1 KiB
C#
using UnityEngine;
|
|
|
|
public class GlassPiece : MonoBehaviour
|
|
{
|
|
public int PieceIndex { get; private set; }
|
|
public bool IsBroken { get; private set; }
|
|
|
|
[SerializeField] private float maxHealth = 1000f;
|
|
|
|
[Header("Damage Visuals")]
|
|
[SerializeField] private float damagedAlpha = 0.85f;
|
|
|
|
private float currentHealth;
|
|
private Rigidbody rb;
|
|
private Renderer rend;
|
|
private Vector3 originalScale;
|
|
|
|
private Color intactColor = Color.white;
|
|
|
|
private void Awake()
|
|
{
|
|
rb = GetComponent<Rigidbody>();
|
|
rend = GetComponent<Renderer>();
|
|
|
|
if (rend == null)
|
|
rend = GetComponentInChildren<Renderer>();
|
|
|
|
originalScale = transform.localScale;
|
|
|
|
if (rend != null)
|
|
{
|
|
if (rend.material.HasProperty("_BaseColor"))
|
|
intactColor = rend.material.GetColor("_BaseColor");
|
|
else if (rend.material.HasProperty("_Color"))
|
|
intactColor = rend.material.color;
|
|
}
|
|
}
|
|
|
|
public void Initialize(int index, float startHealth)
|
|
{
|
|
PieceIndex = index;
|
|
maxHealth = startHealth;
|
|
currentHealth = startHealth;
|
|
IsBroken = false;
|
|
|
|
if (rb != null)
|
|
{
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
rb.linearVelocity = Vector3.zero;
|
|
rb.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
transform.localScale = originalScale;
|
|
UpdateVisual();
|
|
}
|
|
|
|
public bool ApplyDamage(float damage, Vector3 hitPoint, Vector3 impulseDirection, float impulseStrength)
|
|
{
|
|
if (IsBroken) return false;
|
|
|
|
currentHealth = Mathf.Max(0f, currentHealth - damage);
|
|
UpdateVisual();
|
|
|
|
if (currentHealth <= 0f)
|
|
{
|
|
Break(hitPoint, impulseDirection, impulseStrength);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void UpdateVisual()
|
|
{
|
|
if (rend == null) return;
|
|
|
|
float damage01 = 1f - (currentHealth / maxHealth);
|
|
float visualT = Mathf.Pow(damage01, 0.8f);
|
|
|
|
Color targetColor = new Color(1f, 1f, 1f, damagedAlpha);
|
|
Color finalColor = Color.Lerp(intactColor, targetColor, visualT);
|
|
|
|
if (rend.material.HasProperty("_BaseColor"))
|
|
rend.material.SetColor("_BaseColor", finalColor);
|
|
else if (rend.material.HasProperty("_Color"))
|
|
rend.material.color = finalColor;
|
|
|
|
float shrink = Mathf.Lerp(1f, 0.92f, visualT * 0.25f);
|
|
transform.localScale = originalScale * shrink;
|
|
}
|
|
|
|
private void Break(Vector3 hitPoint, Vector3 impulseDirection, float impulseStrength)
|
|
{
|
|
if (IsBroken) return;
|
|
|
|
IsBroken = true;
|
|
|
|
transform.SetParent(null, true);
|
|
|
|
if (rb != null)
|
|
{
|
|
rb.isKinematic = false;
|
|
rb.useGravity = true;
|
|
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
|
|
|
if (impulseDirection.sqrMagnitude < 0.0001f)
|
|
impulseDirection = transform.forward;
|
|
|
|
rb.AddForceAtPosition(impulseDirection.normalized * impulseStrength, hitPoint, ForceMode.Impulse);
|
|
}
|
|
}
|
|
} |