Files
beyond/Assets/Scripts/Invector/vDestructableObject.cs
2025-02-13 14:40:31 +01:00

222 lines
7.1 KiB
C#

using Invector;
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
namespace Beyond
{
[RequireComponent(typeof(vHealthController))]
[RequireComponent(typeof(AudioSource))]
public class vDestructableObject : MonoBehaviour
{
[System.Serializable]
public class SpawnDescriptor
{
public GameObject prefab;
public float chance = 1f;
}
// Start is called before the first frame update
public vHealthController m_healthController;
public int mMaxHP = 10;
//[Tooltip("If empty, accepts all damage types")] public string damageType = "";
public AudioClip m_DestroySound;
public AudioClip m_DestroySound2;
public AudioClip[] hitSounds;
public GameObject[] m_ShardsGroup;
public GameObject[] objectsToEnable;
public GameObject[] objectsToDisable;
public AudioSource m_AudioSource;
public UnityEvent m_onDestroy;
//public GameObject[] m_prefabToSpawn;
public SpawnDescriptor[] m_objectsToSpawn;
public int m_minObjectsToSpawn = 1;
public int m_maxObjectsToSpawn = 2;
public Transform m_spawnPoint;
int m_HP = 10;
public int explosiveDamage = 0;
public float randomPositionOffset = 0.2f;
public int points = 20;
int mDestroySoundIdx = 0;
AudioClip GetRandomSound(AudioClip[] audioClips)
{
return audioClips[UnityEngine.Random.Range(0, audioClips.Length)];
}
void Start()
{
m_healthController = GetComponent<vHealthController>();
m_healthController.onReceiveDamage.AddListener(TakeDamage);
gameObject.SetLayerRecursively(LayerMask.NameToLayer("Enemy"));
m_HP = mMaxHP;
//normalize random chances
float chanceSum = 0f;
foreach (var o in m_objectsToSpawn)
{
chanceSum += o.chance;
}
foreach (var o in m_objectsToSpawn)
{
o.chance /= chanceSum;
}
}
public void TakeDamage(vDamage damage)
{
if (m_HP <= 0)
return;
//if (damageType)
m_HP -= damage.damageValue;
// if (PointMgr.instance)
// PointMgr.instance.SuccessfulHit(true);
if (m_HP <= 0)
Die();
else
Hit();
}
void Hit()
{
if (hitSounds.Length > 0)
{
m_AudioSource.clip = GetRandomSound(hitSounds);
m_AudioSource.Play();
}
}
private void SpawnRandomObjects()
{
if (m_objectsToSpawn != null && m_objectsToSpawn.Length > 0)
{
int numToSpawn = UnityEngine.Random.Range(m_minObjectsToSpawn, m_maxObjectsToSpawn);
Vector3 pos = transform.position;
Quaternion q = transform.rotation;
if (m_spawnPoint != null)
{
pos = m_spawnPoint.position;
q = m_spawnPoint.rotation;
}
for (int i=0; i<numToSpawn; i++)
{
//select random object
float rnd = UnityEngine.Random.Range(0f, 1f);
float sum = 0f;
GameObject prefab = null;
for (int j=0; j<m_objectsToSpawn.Length; j++)
{
var obj = m_objectsToSpawn[j];
//this is the object
if (rnd > sum && rnd < sum+obj.chance)
{
prefab = obj.prefab;
break;
}
sum+=obj.chance;
}
if (prefab != null)
{
var inst = Instantiate(prefab, pos + Random.onUnitSphere * randomPositionOffset, q);
var rb = inst.GetComponent<Rigidbody>();
if (rb)
{
rb.AddExplosionForce(explosiveDamage, transform.position, 20f);
}
}
}
}
}
[Button]
public virtual void Die()
{
SoundListPlayer soundListPlayer = null;
if (m_ShardsGroup.Length > 0)
{
GameObject shards = m_ShardsGroup[UnityEngine.Random.Range(0, m_ShardsGroup.Length)];
//mAudioSource = shards.AddComponent<AudioSource>();
soundListPlayer = shards.AddComponent<SoundListPlayer>();
shards.SetActive(true);
shards.transform.parent = null;
}
else
{
soundListPlayer = gameObject.AddComponent<SoundListPlayer>();
}
//use new method
//if (m_prefabToSpawn != null && m_prefabToSpawn.Length > 0)
{
SpawnRandomObjects();
}
/*
else if (m_prefabToSpawn != null && m_prefabToSpawn.Length > 0)
{
Vector3 pos = transform.position;
Quaternion q = transform.rotation;
if (m_spawnPoint != null)
{
pos = m_spawnPoint.position;
q = m_spawnPoint.rotation;
}
var pref = m_prefabToSpawn[UnityEngine.Random.Range(0, m_prefabToSpawn.Length)];
if (pref != null)
Instantiate(pref, pos, q);
}
*/
//if (PointMgr.instance && points != 0)
// PointMgr.instance.ShowPoints(points, transform.position);
foreach (GameObject o in objectsToEnable)
{
o.SetActive(true);
}
foreach (GameObject o in objectsToDisable)
{
o.SetActive(false);
}
if (m_onDestroy != null)
{
m_onDestroy.Invoke();
}
//thats ugly, but I couldn't add array because all set mDestroySound whould have been lost
if (m_DestroySound != null)
{
soundListPlayer.clips = new AudioClip[2];
soundListPlayer.clips[0] = m_DestroySound;
if (m_DestroySound2 != null)
{
soundListPlayer.clips[1] = m_DestroySound2;
}
soundListPlayer.Play();
}
Destroy(gameObject);
}
public void OnExplosion(Vector3 position, float power)
{
if (m_HP <= 0)
return;
m_HP -= (int)power;
if (m_HP <= 0)
Die();
else
Hit();
}
}
}