
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
336 lines
12 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|