216 lines
8.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|