Files
BlueArchiveMiniGame/Assets/ThirdParty/DestroyIt/Demos (safe to delete)/Scripts/Behaviors/MeleeArea.cs
2025-09-17 18:56:28 +08:00

104 lines
4.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace DestroyIt
{
public class MeleeArea : MonoBehaviour
{
public int damageAmount = 30;
public int repairAmount = 20;
public float meleeRadius = 1.3f;
public float additionalForceAmount = 150f;
public float additionalForceRadius = 2f;
public ParticleSystem repairEffect;
public void OnMeleeDamage()
{
Collider[] objectsInRange = Physics.OverlapSphere(transform.position, meleeRadius);
List<Destructible> damagedObjects = new List<Destructible>(); // Keep track of what objects have been damaged so we don't do damage multiple times per collider.
bool hasPlayedHitEffect = false;
foreach (Collider col in objectsInRange)
{
// Ignore terrain colliders
if (col is TerrainCollider) continue;
// Ignore trigger colliders
if (col.isTrigger) continue;
// Ignore the player's character controller (ie, don't allow hitting yourself)
if (col is CharacterController && col.tag == "Player") continue;
if (!hasPlayedHitEffect) // Only play the hit effect once per melee attack.
{
// Play hit effects
HitEffects hitEffects = col.gameObject.GetComponentInParent<HitEffects>();
if (hitEffects != null && hitEffects.effects.Count > 0)
hitEffects.PlayEffect(HitBy.Axe, transform.position, transform.forward * -1);
hasPlayedHitEffect = true;
}
// Apply impact force to rigidbody hit
Rigidbody rbody = col.attachedRigidbody;
if (rbody != null)
rbody.AddForceAtPosition(transform.forward * 3f, transform.position, ForceMode.Impulse);
// Apply damage if object hit was Destructible
// Only do this for active and enabled Destructible scripts found in parent objects
// Special Note: Destructible scripts are turned off on terrain trees by default (to save resources), so we will make an exception for them and process the hit anyway
Destructible[] destObjs = col.gameObject.GetComponentsInParent<Destructible>(false);
foreach (Destructible destObj in destObjs)
{
if (damagedObjects.Contains(destObj)) continue;
if (!destObj.isActiveAndEnabled && !destObj.isTerrainTree) continue;
damagedObjects.Add(destObj);
ImpactDamage meleeImpact = new ImpactDamage() { DamageAmount = damageAmount, AdditionalForce = additionalForceAmount,
AdditionalForcePosition = transform.position, AdditionalForceRadius = additionalForceRadius };
destObj.ApplyDamage(meleeImpact);
}
}
}
private void OnMeleeRepair()
{
Collider[] objectsInRange = Physics.OverlapSphere(transform.position, meleeRadius);
List<Destructible> repairedObjects = new List<Destructible>(); // Keep track of what objects have been repaired so we don't repair multiple times per collider.
bool hasPlayedRepairEffect = false;
// Repair items within range
foreach (Collider col in objectsInRange)
{
// Ignore terrain colliders
if (col is TerrainCollider) continue;
// Ignore trigger colliders
if (col.isTrigger) continue;
// Ignore the player's character controller (ie, don't allow hitting yourself)
if (col is CharacterController && col.tag == "Player") continue;
// Repair object if it is a Destructible
Destructible destObj = col.gameObject.GetComponentInParent<Destructible>();
if (destObj != null && !repairedObjects.Contains(destObj) && destObj.CurrentHitPoints < destObj.TotalHitPoints && destObj.canBeRepaired)
{
repairedObjects.Add(destObj);
destObj.RepairDamage(repairAmount);
// Play repair particle effect
if (repairEffect != null && !hasPlayedRepairEffect)
{
repairEffect.GetComponent<ParticleSystem>().Clear(true);
repairEffect.Play(true);
hasPlayedRepairEffect = true;
}
}
}
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, meleeRadius);
}
}
}