Merge pull request #71 from dnutiu/enemy-death-animation
Implement enemy death animation
This commit is contained in:
commit
7395be7496
10 changed files with 152 additions and 130 deletions
|
@ -29,7 +29,7 @@ AnimatorState:
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: Dumber
|
m_Name: Normal
|
||||||
m_Speed: 1
|
m_Speed: 1
|
||||||
m_CycleOffset: 0
|
m_CycleOffset: 0
|
||||||
m_Transitions: []
|
m_Transitions: []
|
||||||
|
@ -59,7 +59,7 @@ AnimatorStateMachine:
|
||||||
m_ChildStates:
|
m_ChildStates:
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: 1102746068587636566}
|
m_State: {fileID: 1102746068587636566}
|
||||||
m_Position: {x: 200, y: 0, z: 0}
|
m_Position: {x: 336, y: 24, z: 0}
|
||||||
m_ChildStateMachines: []
|
m_ChildStateMachines: []
|
||||||
m_AnyStateTransitions: []
|
m_AnyStateTransitions: []
|
||||||
m_EntryTransitions: []
|
m_EntryTransitions: []
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace src.Ammo
|
||||||
{
|
{
|
||||||
Debug.Log("Hit something");
|
Debug.Log("Hit something");
|
||||||
var key = hit.collider.GetComponent<IExplosable>();
|
var key = hit.collider.GetComponent<IExplosable>();
|
||||||
key?.onExplosion();
|
key?.OnExplosion();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,11 +68,11 @@ namespace src.Ammo
|
||||||
{
|
{
|
||||||
if (!_exploded && other.CompareTag("Explosion"))
|
if (!_exploded && other.CompareTag("Explosion"))
|
||||||
{
|
{
|
||||||
onExplosion();
|
OnExplosion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExplosion()
|
public void OnExplosion()
|
||||||
{
|
{
|
||||||
CancelInvoke(nameof(Explode));
|
CancelInvoke(nameof(Explode));
|
||||||
Explode();
|
Explode();
|
||||||
|
|
|
@ -1,52 +1,71 @@
|
||||||
using src.Helpers;
|
using System.Collections;
|
||||||
using src.Managers;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using src.Helpers;
|
||||||
|
using src.Managers;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public abstract class EnemyBase : MonoBehaviour, IExplosable
|
namespace src.Base
|
||||||
{
|
{
|
||||||
|
public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||||
protected Vector2[] _directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right };
|
{
|
||||||
protected readonly GameStateManager gameStateManager = GameStateManager.Instance;
|
private readonly Vector2[] _directions = {Vector3.up, Vector3.down, Vector3.left, Vector3.right};
|
||||||
|
private readonly GameStateManager _gameStateManager = GameStateManager.Instance;
|
||||||
|
|
||||||
protected Rigidbody2D Rigidbody2d { get; set; }
|
protected Rigidbody2D Rigidbody2d { get; set; }
|
||||||
|
private Collider2D Collider2D { get; set; }
|
||||||
|
private Animator Animator { get; set; }
|
||||||
protected float Speed { get; set; }
|
protected float Speed { get; set; }
|
||||||
protected Vector2 Direction { get; set; }
|
protected Vector2 Direction { get; set; }
|
||||||
|
|
||||||
private List<Vector3> _allowedDirections = new List<Vector3>();
|
private readonly List<Vector3> _allowedDirections = new List<Vector3>();
|
||||||
private bool _isStucked = false;
|
private bool _isStuck;
|
||||||
private System.Random _random = new System.Random();
|
private bool _isDead;
|
||||||
|
|
||||||
|
private static readonly int AnimExplode = Animator.StringToHash("animExplode");
|
||||||
|
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
protected void Start()
|
protected void Start()
|
||||||
{
|
{
|
||||||
Direction = _directions.ChoseRandom();
|
Direction = _directions.ChoseRandom();
|
||||||
Rigidbody2d = GetComponent<Rigidbody2D>();
|
Rigidbody2d = GetComponent<Rigidbody2D>();
|
||||||
|
Collider2D = GetComponent<Collider2D>();
|
||||||
|
Animator = GetComponentInChildren<Animator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
protected void FixedUpdate()
|
protected void FixedUpdate()
|
||||||
{
|
{
|
||||||
if (gameStateManager.IsGamePaused || gameStateManager.IsPlayerMovementForbidden) {return;}
|
if (_gameStateManager.IsGamePaused || _gameStateManager.IsPlayerMovementForbidden || _isDead)
|
||||||
if(_isStucked)
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isStuck)
|
||||||
{
|
{
|
||||||
Unstuck();
|
Unstuck();
|
||||||
}
|
}
|
||||||
Rigidbody2d.MovePosition(Rigidbody2d.position + Speed * Time.deltaTime * Direction);
|
HandleMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function is implemented by subclasses and should provided personalized movement logic.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void HandleMovement();
|
||||||
|
|
||||||
public void OnTriggerEnter2D(Collider2D other)
|
public void OnTriggerEnter2D(Collider2D other)
|
||||||
{
|
{
|
||||||
if (other.CompareTag("Explosion"))
|
if (other.CompareTag("Explosion"))
|
||||||
{
|
{
|
||||||
onExplosion();
|
OnExplosion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExplosion()
|
public void OnExplosion()
|
||||||
{
|
{
|
||||||
Destroy(gameObject);
|
Collider2D.enabled = false;
|
||||||
|
_isDead = true;
|
||||||
|
Animator.SetTrigger(AnimExplode);
|
||||||
|
Destroy(gameObject, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnCollisionEnter2D(Collision2D col)
|
public void OnCollisionEnter2D(Collision2D col)
|
||||||
|
@ -63,10 +82,11 @@ public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||||
|
|
||||||
protected void MoveToCenterOfTheCell()
|
protected void MoveToCenterOfTheCell()
|
||||||
{
|
{
|
||||||
var absX = Mathf.RoundToInt(transform.position.x);
|
var position = transform.position;
|
||||||
var absY = Mathf.RoundToInt(transform.position.y);
|
var absX = Mathf.RoundToInt(position.x);
|
||||||
Vector2 position = new Vector2(absX, absY);
|
var absY = Mathf.RoundToInt(position.y);
|
||||||
transform.SetPositionAndRotation(position, Quaternion.identity);
|
var newPosition = new Vector2(absX, absY);
|
||||||
|
transform.SetPositionAndRotation(newPosition, Quaternion.identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 ChooseRandomDirection()
|
protected Vector2 ChooseRandomDirection()
|
||||||
|
@ -86,24 +106,24 @@ public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||||
StartCoroutine(CheckForObstacle(Vector3.left));
|
StartCoroutine(CheckForObstacle(Vector3.left));
|
||||||
StartCoroutine(CheckForObstacle(Vector3.up));
|
StartCoroutine(CheckForObstacle(Vector3.up));
|
||||||
StartCoroutine(CheckForObstacle(Vector3.right));
|
StartCoroutine(CheckForObstacle(Vector3.right));
|
||||||
if(_allowedDirections.Count == 0)
|
if (_allowedDirections.Count == 0)
|
||||||
{
|
{
|
||||||
_isStucked = true;
|
_isStuck = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var index = _random.Next(_allowedDirections.Count);
|
Direction = _allowedDirections.PeekRandom();
|
||||||
Direction = _allowedDirections[index];
|
_isStuck = false;
|
||||||
_isStucked = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator CheckForObstacle(Vector3 direction)
|
private IEnumerator CheckForObstacle(Vector3 direction)
|
||||||
{
|
{
|
||||||
var layerMask = (1 << 8) | (1 << 9);
|
const int layerMask = 1 << 8; // Block layer
|
||||||
var currentPosition = transform.position;
|
var currentPosition = transform.position;
|
||||||
|
|
||||||
var hit = Physics2D.Raycast(new Vector2(currentPosition.x + 0.5f, currentPosition.y + 0.5f), direction, 1, layerMask);
|
var hit = Physics2D.Raycast(new Vector2(currentPosition.x + 0.5f, currentPosition.y + 0.5f),
|
||||||
|
direction, 1, layerMask);
|
||||||
|
|
||||||
if (!hit.collider)
|
if (!hit.collider)
|
||||||
{
|
{
|
||||||
|
@ -112,4 +132,5 @@ public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||||
|
|
||||||
yield return new WaitForSeconds(0.05f);
|
yield return new WaitForSeconds(0.05f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ namespace src.Base
|
||||||
{
|
{
|
||||||
if (other.CompareTag("Explosion"))
|
if (other.CompareTag("Explosion"))
|
||||||
{
|
{
|
||||||
onExplosion();
|
OnExplosion();
|
||||||
}
|
}
|
||||||
if (other.CompareTag("Enemy"))
|
if (other.CompareTag("Enemy"))
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace src.Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExplosion()
|
public void OnExplosion()
|
||||||
{
|
{
|
||||||
DebugHelper.LogInfo("Player hit by explosion");
|
DebugHelper.LogInfo("Player hit by explosion");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
namespace src.Enemy
|
using src.Base;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace src.Enemy
|
||||||
{
|
{
|
||||||
public class CollisionMovementEnemy : EnemyBase
|
public class CollisionMovementEnemy : EnemyBase
|
||||||
/* Enemy that will change direction only on collision. */
|
/* Enemy that will change direction only on collision. */
|
||||||
|
@ -9,10 +12,9 @@
|
||||||
base.Start();
|
base.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected new void FixedUpdate()
|
protected override void HandleMovement()
|
||||||
{
|
{
|
||||||
base.FixedUpdate();
|
Rigidbody2d.MovePosition(Rigidbody2d.position + Speed * Time.deltaTime * Direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,21 @@
|
||||||
using UnityEngine;
|
using src.Base;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Assets.Scripts.src.Enemy.Dummy
|
namespace src.Enemy.Dummy
|
||||||
{
|
{
|
||||||
//This kind of enemy is used just for testing purposes
|
//This kind of enemy is used just for testing purposes
|
||||||
//This enemy will go just in one direction or stays in place
|
//This enemy will go just in one direction or stays in place
|
||||||
//To make it stay in place, don't assign any direction in OneDirection slot or assign Vector2.zero
|
//To make it stay in place, don't assign any direction in OneDirection slot or assign Vector2.zero
|
||||||
public class OneDirectionEnemy : EnemyBase
|
public class OneDirectionEnemy : EnemyBase
|
||||||
{
|
{
|
||||||
public Vector2 OneDirection = Vector2.zero;
|
|
||||||
|
|
||||||
protected new void Start()
|
protected new void Start()
|
||||||
{
|
{
|
||||||
Speed = 4.0f;
|
Speed = 4.0f;
|
||||||
Rigidbody2d = GetComponent<Rigidbody2D>();
|
Rigidbody2d = GetComponent<Rigidbody2D>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected new void FixedUpdate()
|
protected override void HandleMovement()
|
||||||
{
|
{
|
||||||
if (OneDirection != Vector2.zero)
|
|
||||||
{
|
|
||||||
if (gameStateManager.IsGamePaused || gameStateManager.IsPlayerMovementForbidden) { return; }
|
|
||||||
Rigidbody2d.MovePosition(Rigidbody2d.position + OneDirection * Speed * Time.deltaTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using src.Helpers;
|
using src.Base;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace src.Enemy
|
namespace src.Enemy
|
||||||
|
@ -13,12 +13,11 @@ namespace src.Enemy
|
||||||
base.Start();
|
base.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected new void FixedUpdate()
|
protected override void HandleMovement()
|
||||||
{
|
{
|
||||||
var pos = transform.position;
|
var pos = transform.position;
|
||||||
var x = pos.x;
|
var x = pos.x;
|
||||||
var y = pos.y;
|
var y = pos.y;
|
||||||
if (gameStateManager.IsGamePaused || gameStateManager.IsPlayerMovementForbidden) { return; }
|
|
||||||
if (Math.Abs(x - Mathf.Floor(x)) < 0.1 && Math.Abs(y - Mathf.Floor(y)) < 0.1)
|
if (Math.Abs(x - Mathf.Floor(x)) < 0.1 && Math.Abs(y - Mathf.Floor(y)) < 0.1)
|
||||||
{
|
{
|
||||||
if (RandomChange())
|
if (RandomChange())
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace src.Helpers
|
||||||
var max = list.Count - 1;
|
var max = list.Count - 1;
|
||||||
for (var i = min; i < max; i++)
|
for (var i = min; i < max; i++)
|
||||||
{
|
{
|
||||||
var randomPos = Mathf.FloorToInt(Random.Range(min, max));
|
var randomPos = Random.Range(min, max);
|
||||||
|
|
||||||
/* Swap elements in list */
|
/* Swap elements in list */
|
||||||
var aux = list[randomPos];
|
var aux = list[randomPos];
|
||||||
|
@ -23,10 +23,16 @@ namespace src.Helpers
|
||||||
|
|
||||||
public static T PopRandom<T>(this IList<T> list)
|
public static T PopRandom<T>(this IList<T> list)
|
||||||
{
|
{
|
||||||
var randomIndex = Mathf.FloorToInt(Random.Range(0, list.Count - 1));
|
var randomIndex = Random.Range(0, list.Count - 1);
|
||||||
var elem = list[randomIndex];
|
var elem = list[randomIndex];
|
||||||
list.RemoveAt(randomIndex);
|
list.RemoveAt(randomIndex);
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T PeekRandom<T>(this IList<T> list)
|
||||||
|
{
|
||||||
|
var randomIndex = Random.Range(0, list.Count - 1);
|
||||||
|
return list[randomIndex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,5 +4,5 @@ using UnityEngine;
|
||||||
|
|
||||||
public interface IExplosable
|
public interface IExplosable
|
||||||
{
|
{
|
||||||
void onExplosion();
|
void OnExplosion();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace src.Wall
|
||||||
// _animator.speed = 10;
|
// _animator.speed = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExplosion()
|
public void OnExplosion()
|
||||||
{
|
{
|
||||||
DebugHelper.LogInfo($"Destructible wall hit by explosion {transform.position}");
|
DebugHelper.LogInfo($"Destructible wall hit by explosion {transform.position}");
|
||||||
PlayDestroyAnimation();
|
PlayDestroyAnimation();
|
||||||
|
|
Loading…
Reference in a new issue