Files
blackhole-escape/Assets/Scripts/Scripts/EnemyColliderManager.cs
iDunnoDev fb3415c7b2 Added new sounds needed for game
Added blackhole swirl texture and materials
Added Magnet, Hunter and Drop core powerups and script overhaul for powerups in general
Added Scenes and Cinematic changes for the game, win and death screens
Added a score
Changed the way enemy spawns work
Removed unused scripts
2022-07-14 17:31:10 +01:00

336 lines
12 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyColliderManager : ColliderManager
{
public GameObject shipCore;
public float bounceForce;
public float coreSpawnDelayTime;
public ParticleSystem effectA;
public ParticleSystem effectB;
public AudioClip shipDeathSFX;
public AudioClip coreSpawnedSFX;
private bool _enemyDestroyed = false;
private TimerHelper _deathTimer;
private TimerHelper _particleTimer;
// The position the enemy died
private Vector3 _deathPos;
private float _deathHeight;
public List<GameObject> enemyLoot;
public List<float> enemyLootChance;
public float magnetizedTime;
private bool _magnetHit = false;
private TimerHelper _magnetizeTime;
public bool Dying
{
get
{
return _enemyDestroyed;
}
}
public bool Magnetized
{
get
{
return _magnetHit;
}
}
private void Start()
{
_deathTimer = new TimerHelper(coreSpawnDelayTime, false);
_magnetizeTime = new TimerHelper(magnetizedTime, false);
}
/// <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;
}
if (!Dying)
{
switch (direction)
{
// We were hit from the top
case CollisionDirection.Top:
switch (collisionGO.tag)
{
case "Player":
// We were killed by the player above
PlayerColliderManager playerColliderManager = collisionGO.GetComponent<PlayerColliderManager>();
if (playerColliderManager)
{
if (!playerColliderManager.Dying)
{
DestoryEnemy(true);
}
}
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)
{
if (playerColliderManager.Deadly)
{
DestoryEnemy(true);
}
else
{
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 "Player":
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);
}
private void SpawnCore()
{
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);
ObjectSpawning attachedShared = gameObject.GetComponent<EnemyObjectShared>().Spawner;
if (attachedShared)
{
// Reduce the spawner objects count
attachedShared.ReduceSpawnedCount();
}
Destroy(gameObject);
}
public void MagnetizeEnemy()
{
if (!_magnetHit)
{
_magnetHit = true;
_magnetizeTime.RestartTimer();
}
}
private void SpawnLoot()
{
int currentLootCount = 0;
foreach (GameObject currentLoot in enemyLoot)
{
float currentRoll = Random.Range(0.0f, 1.0f) * 100.0f;
if (currentRoll <= enemyLootChance[currentLootCount])
{
GameObject newLoot = Instantiate(currentLoot);
PowerUpHoverMovement lootMovement = newLoot.GetComponent<PowerUpHoverMovement>();
if (lootMovement)
{
lootMovement.startPositionVector = _deathPos;
lootMovement.startHeight = _deathHeight;
}
newLoot.SetActive(true);
AudioSource newLootAS = newLoot.GetComponent<AudioSource>();
newLootAS.PlayOneShot(coreSpawnedSFX);
}
currentLootCount++;
}
}
private void Update()
{
if (_enemyDestroyed)
{
if (_deathTimer.HasTicked(Time.deltaTime))
{
SpawnCore();
SpawnLoot();
}
else
{
if (!_particleTimer.Started || _particleTimer.HasTicked(Time.deltaTime))
{
int randDir = Random.Range(0, 4);
float randOffset = Random.Range(0.0f, 2.0f);
Vector3 offsetDir;
switch (randDir)
{
case 1:
offsetDir = Vector3.down * randOffset;
break;
case 2:
offsetDir = Vector3.right * randOffset;
break;
case 3:
offsetDir = Vector3.left * randOffset;
break;
default:
case 0:
offsetDir = Vector3.up * randOffset;
break;
}
ParticleSystem boomboom = Instantiate(effectA);
ParticleSystem boomboom2 = Instantiate(effectB);
boomboom.transform.position = _deathPos + offsetDir;
boomboom2.transform.position = _deathPos + offsetDir;
if (_attachedAudioSource)
{
_attachedAudioSource.PlayOneShot(shipDeathSFX);
}
if (!_particleTimer.Started)
{
_particleTimer.HasTicked(Time.deltaTime);
}
}
}
}
if (_magnetHit)
{
if (_magnetizeTime.HasTicked(Time.deltaTime))
{
_magnetHit = false;
}
}
}
/// <summary>
/// Method for destroying the enemy game object, it starts a coroutine to allow for an animation to be played.
/// </summary>
public void DestoryEnemy(bool addScore = false)
{
if (!_enemyDestroyed)
{
if (addScore)
{
EnemyObjectShared currentEnemyOS = gameObject.GetComponent<EnemyObjectShared>();
if (currentEnemyOS != null)
{
GameManager.Instance.AddScore(GameManager.Instance.GetCurrentLevelEnemyStats(currentEnemyOS.enemyTypeName).Score);
}
}
// Store the position of death since the AI still moves after the models been deactivated.
_deathPos = transform.position;
HoverMovement currentHoverMovement = gameObject.GetComponent<HoverMovement>();
currentHoverMovement.freezeMovement = true;
_deathHeight = currentHoverMovement.GetCurrentHeight();
shipModel.SetActive(false);
_particleTimer = new TimerHelper(0.3f);
gameObject.tag = "Dead";
gameObject.layer = LayerMask.NameToLayer("NoCollide");
_enemyDestroyed = true;
}
}
}