Files
GeoSusGame/Assets/GlassPiece.cs
2026-04-26 14:35:54 +02:00

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);
}
}
}