Files
blackhole-escape/Assets/Assets_And_Scenes/Scripts/Scripts/EnemyColliderManager.cs
2022-06-18 15:55:39 +01:00

216 lines
8.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyColliderManager : ColliderManager
{
public GameObject shipCore;
public GameObject shipModel;
public float bounceForce;
public float coreSpawnDelayTime;
public ParticleSystem effectA;
public ParticleSystem effectB;
public AudioClip shipDeathSFX;
public AudioClip coreSpawnedSFX;
private bool _enemyDestroyed = false;
// The position the enemy died
private Vector3 _deathPos;
private float _deathHeight;
/// <summary>
/// Trigger the enemy death without a collision, this is mostly for the debug menu and testing but could be called in a case where you need it to die.
/// </summary>
public override void TriggerDeath()
{
DestoryEnemy();
base.TriggerDeath();
}
/// <summary>
/// Process the Enemy collision.
/// </summary>
/// <param name="direction">Direction the collision happened, typically checking if hit from above or below.</param>
/// <param name="collision">Collision object holding the details on the collided object.</param>
/// <param name="wasChild">Was the hit collider a child of this game object.</param>
public override void ProcessCollision(CollisionDirection direction, Collision collision, bool wasChild)
{
GameObject collisionGO;
if (wasChild)
{
collisionGO = collision.transform.parent.gameObject;
}
else
{
collisionGO = collision.gameObject;
}
switch (direction)
{
// We were hit from the top
case CollisionDirection.Top:
switch (collisionGO.tag)
{
case "Player":
// We were killed by the player above
DestoryEnemy();
break;
case "Enemy":
// Bounce other enemies back
BounceAway(collision.contacts[0].normal);
break;
case "Core":
case "Dead":
// Now handled by the layer NoCollide
// Ignore the physics between this and the core or dead players
//Physics.IgnoreCollision(collision.collider, gameObject.GetComponent<Collider>());
break;
}
break;
// We were hit from the bottom
case CollisionDirection.Bottom:
switch (collisionGO.tag)
{
case "Player":
// Kill the player because we were on top
PlayerColliderManager playerColliderManager = collisionGO.GetComponent<PlayerColliderManager>();
if (playerColliderManager)
{
playerColliderManager.PlayerHit();
}
break;
case "Enemy":
// Bounce the enemy away
EnemyColliderManager enemyColliderManager = collisionGO.GetComponent<EnemyColliderManager>();
if (enemyColliderManager)
{
enemyColliderManager.BounceAway(-collision.contacts[0].normal);
}
break;
case "Core":
case "Dead":
// Now handled by the layer NoCollide
//Physics.IgnoreCollision(collision.collider, gameObject.GetComponent<Collider>());
break;
}
break;
// Hits coming from any direction
default:
switch (collisionGO.tag)
{
case "Mine":
MineColliderManager mineColliderManager = collisionGO.GetComponent<MineColliderManager>();
if (mineColliderManager)
{
mineColliderManager.HitMine();
}
break;
case "Asteroid":
AsteroidColliderManager asteroidColliderManager = collisionGO.GetComponent<AsteroidColliderManager>();
if (asteroidColliderManager)
{
asteroidColliderManager.BounceAway(gameObject, -collision.contacts[0].normal);
}
break;
case "Enemy":
EnemyColliderManager enemyColliderManager = collisionGO.GetComponent<EnemyColliderManager>();
if (enemyColliderManager)
{
enemyColliderManager.BounceAway(-collision.contacts[0].normal);
}
break;
case "Core":
case "Dead":
// Handled by the layers now
//Physics.IgnoreCollision(collision.collider, gameObject.GetComponent<Collider>());
break;
}
break;
}
}
/// <summary>
/// Bounce away from the given position.
/// </summary>
/// <param name="collisionPos">Vector position the collision happened at.</param>
public void BounceAway(Vector3 collisionPos)
{
gameObject.GetComponent<Rigidbody>().AddForce(collisionPos * bounceForce, ForceMode.Impulse);
}
/// <summary>
/// Delayed core spawning method, this allows the ship to "die" and play its animation and then for the spawn to appear.
/// </summary>
/// <returns></returns>
public IEnumerator DelayedCoreSpawn()
{
bool timeWaited = false;
bool waitEnded = false;
while (!waitEnded)
{
if (timeWaited)
{
// Spawn a new core at the death location
GameObject newCore = Instantiate(shipCore);
CoreHoverMovement coreMovement = newCore.GetComponent<CoreHoverMovement>();
if (coreMovement)
{
coreMovement.startPositionVector = _deathPos;
coreMovement.startHeight = _deathHeight;
}
newCore.SetActive(true);
AudioSource newCoreAS = newCore.GetComponent<AudioSource>();
newCoreAS.PlayOneShot(coreSpawnedSFX);
StopCoroutine("DelayedCoreSpawn");
ObjectSpawning attachedShared = gameObject.GetComponent<EnemyObjectShared>().Spawner;
if (attachedShared)
{
// Reduce the spawner objects count
attachedShared.ReduceSpawnedCount();
}
Destroy(gameObject);
waitEnded = true;
}
else
{
timeWaited = true;
}
yield return new WaitForSeconds(coreSpawnDelayTime);
}
}
/// <summary>
/// Method for destroying the enemy game object, it starts a coroutine to allow for an animation to be played.
/// </summary>
public void DestoryEnemy()
{
if (!_enemyDestroyed)
{
// Store the position of death since the AI still moves after the models been deactivated.
_deathPos = transform.position;
_deathHeight = gameObject.GetComponent<HoverMovement>().GetCurrentHeight();
if (_attachedAudioSource)
{
_attachedAudioSource.PlayOneShot(shipDeathSFX);
}
// Start the delayed core spawn coroutine, this can probs be replaced once the death animations are in to spawn once that has ended.
StartCoroutine("DelayedCoreSpawn");
ParticleSystem boomboom = Instantiate(effectA);
ParticleSystem boomboom2 = Instantiate(effectB);
boomboom.transform.position = _deathPos;
boomboom2.transform.position = _deathPos;
shipModel.SetActive(false);
gameObject.tag = "Dead";
gameObject.layer = LayerMask.NameToLayer("NoCollide");
_enemyDestroyed = true;
}
}
}