Files
VOIDRPG/Assets/90 - Scripts/Generic/Objects/Abstract/AbstractObject.cs
T
2026-07-09 21:33:33 +02:00

142 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Sirenix.Utilities;
using UnityEngine;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Triggers;
namespace VOID.Generic.Objects.Abstract
{
[SelectionBase]
[DisallowMultipleComponent]
[RequireComponent(typeof(Rigidbody))]
public abstract class AbstractObject : MonoBehaviour
{
[Title("=== BasicObject properties ===")]
public AbstractObjectData basicData;
public AbstractObjectEvents basicEvents;
public AbstractObjectStatusManager statusManager;
public AbstractObjectState basicState;
protected void OnValidate()
{
gameObject.GetComponent<Rigidbody>().hideFlags = HideFlags.NotEditable;
// Init RigidBody
var rb = GetComponent<Rigidbody>();
rb.mass = 0;
rb.linearDamping = 0;
rb.angularDamping = 0;
rb.automaticCenterOfMass = true;
rb.automaticInertiaTensor = true;
rb.useGravity = false;
rb.isKinematic = true;
rb.interpolation = RigidbodyInterpolation.None;
rb.constraints = RigidbodyConstraints.FreezeAll;
}
private void Awake()
{
GetObjectComponents().ForEach(component => component.SetParent(this));
GetObjectComponents().ForEach(component => component.DoSelfInitialize());
GetObjectComponents().ForEach(component => component.DoEventInitialize());
GetObjectComponents().ForEach(component => component.DoInitialize());
}
private void Start()
{
// Finally when this object is fully initialized then we can
basicEvents.onSpawn.Invoke();
}
protected void FixedUpdate()
{
basicEvents.onFixedUpdate.Invoke();
}
protected virtual List<ObjectComponent> GetObjectComponents()
{
return new List<ObjectComponent>
{
basicData,
basicEvents,
statusManager,
basicState
};
}
[Button]
public void TakeDamage(DamageEvent damageEvent)
{
if (basicState.isDead) return;
if (!basicData.canBeDestroyed) return;
basicEvents.onDamagedBefore.Invoke(damageEvent);
if (damageEvent.attacker) damageEvent.attacker.unitEvents.onDamageBefore.Invoke(damageEvent);
if (damageEvent.prevented) return;
var damage = damageEvent.amount;
var resistance = 1 - basicData.resistances.Get(damageEvent.damageType);
basicData.UseResource(BasicResourceType.Health, damage * resistance, true);
basicEvents.onDamagedAfter.Invoke(damageEvent);
if (damageEvent.attacker) damageEvent.attacker.unitEvents.onDamageAfter.Invoke(damageEvent);
if (basicData.currentResources.health <= 0f) Death();
}
[Button]
public void Death()
{
if (basicState.isDead) return;
if (!basicData.canBeDestroyed) return;
var deathEvent = new DeathEvent { obj = this };
basicEvents.onDeathBefore.Invoke(deathEvent);
if (deathEvent.prevented) return;
basicEvents.onDeathAfter.Invoke(deathEvent);
basicData.currentResources.health = 0f;
}
[Button]
public void Revive()
{
if (basicState.isDead == false) return;
basicData.SetResourcePercentage(BasicResourceType.Health, 0.3f);
basicEvents.onRevive.Invoke(new ReviveEvent { obj = this });
}
[Button]
public void Remove()
{
var removeEvent = new RemoveEvent { obj = this };
basicEvents.onRemove.Invoke(removeEvent);
Destroy(gameObject);
}
private void OnTriggerEnter(Collider other)
{
other.GetComponentsInParent<IDynamicTrigger>().ForEach(triggerArea => {
if (basicState.isDead == false) triggerArea.OnObjectEnter(this);
basicEvents.onTriggerEnter.Invoke(new TriggerEvent { obj = this, triggerArea = triggerArea });
});
}
private void OnTriggerExit(Collider other)
{
other.GetComponentsInParent<IDynamicTrigger>().ForEach(triggerArea => {
if (basicState.isDead == false) triggerArea.OnObjectExit(this);
basicEvents.onTriggerExit.Invoke(new TriggerEvent { obj = this, triggerArea = triggerArea });
});
}
}
}