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_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Dumber
|
||||
m_Name: Normal
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions: []
|
||||
|
@ -59,7 +59,7 @@ AnimatorStateMachine:
|
|||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 1102746068587636566}
|
||||
m_Position: {x: 200, y: 0, z: 0}
|
||||
m_Position: {x: 336, y: 24, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace src.Ammo
|
|||
{
|
||||
Debug.Log("Hit something");
|
||||
var key = hit.collider.GetComponent<IExplosable>();
|
||||
key?.onExplosion();
|
||||
key?.OnExplosion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -68,11 +68,11 @@ namespace src.Ammo
|
|||
{
|
||||
if (!_exploded && other.CompareTag("Explosion"))
|
||||
{
|
||||
onExplosion();
|
||||
OnExplosion();
|
||||
}
|
||||
}
|
||||
|
||||
public void onExplosion()
|
||||
public void OnExplosion()
|
||||
{
|
||||
CancelInvoke(nameof(Explode));
|
||||
Explode();
|
||||
|
|
|
@ -1,115 +1,136 @@
|
|||
using src.Helpers;
|
||||
using src.Managers;
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using src.Helpers;
|
||||
using src.Managers;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||
namespace src.Base
|
||||
{
|
||||
|
||||
protected Vector2[] _directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right };
|
||||
protected readonly GameStateManager gameStateManager = GameStateManager.Instance;
|
||||
|
||||
protected Rigidbody2D Rigidbody2d { get; set; }
|
||||
protected float Speed { get; set; }
|
||||
protected Vector2 Direction { get; set; }
|
||||
|
||||
private List<Vector3> _allowedDirections = new List<Vector3>();
|
||||
private bool _isStucked = false;
|
||||
private System.Random _random = new System.Random();
|
||||
|
||||
// Start is called before the first frame update
|
||||
protected void Start()
|
||||
public abstract class EnemyBase : MonoBehaviour, IExplosable
|
||||
{
|
||||
Direction = _directions.ChoseRandom();
|
||||
Rigidbody2d = GetComponent<Rigidbody2D>();
|
||||
}
|
||||
private readonly Vector2[] _directions = {Vector3.up, Vector3.down, Vector3.left, Vector3.right};
|
||||
private readonly GameStateManager _gameStateManager = GameStateManager.Instance;
|
||||
|
||||
// Update is called once per frame
|
||||
protected void FixedUpdate()
|
||||
{
|
||||
if (gameStateManager.IsGamePaused || gameStateManager.IsPlayerMovementForbidden) {return;}
|
||||
if(_isStucked)
|
||||
protected Rigidbody2D Rigidbody2d { get; set; }
|
||||
private Collider2D Collider2D { get; set; }
|
||||
private Animator Animator { get; set; }
|
||||
protected float Speed { get; set; }
|
||||
protected Vector2 Direction { get; set; }
|
||||
|
||||
private readonly List<Vector3> _allowedDirections = new List<Vector3>();
|
||||
private bool _isStuck;
|
||||
private bool _isDead;
|
||||
|
||||
private static readonly int AnimExplode = Animator.StringToHash("animExplode");
|
||||
|
||||
// Start is called before the first frame update
|
||||
protected void Start()
|
||||
{
|
||||
Direction = _directions.ChoseRandom();
|
||||
Rigidbody2d = GetComponent<Rigidbody2D>();
|
||||
Collider2D = GetComponent<Collider2D>();
|
||||
Animator = GetComponentInChildren<Animator>();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
protected void FixedUpdate()
|
||||
{
|
||||
if (_gameStateManager.IsGamePaused || _gameStateManager.IsPlayerMovementForbidden || _isDead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isStuck)
|
||||
{
|
||||
Unstuck();
|
||||
}
|
||||
HandleMovement();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is implemented by subclasses and should provided personalized movement logic.
|
||||
/// </summary>
|
||||
protected abstract void HandleMovement();
|
||||
|
||||
public void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (other.CompareTag("Explosion"))
|
||||
{
|
||||
OnExplosion();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnExplosion()
|
||||
{
|
||||
Collider2D.enabled = false;
|
||||
_isDead = true;
|
||||
Animator.SetTrigger(AnimExplode);
|
||||
Destroy(gameObject, 1);
|
||||
}
|
||||
|
||||
public void OnCollisionEnter2D(Collision2D col)
|
||||
{
|
||||
MoveToCenterOfTheCell();
|
||||
Unstuck();
|
||||
}
|
||||
Rigidbody2d.MovePosition(Rigidbody2d.position + Speed * Time.deltaTime * Direction);
|
||||
}
|
||||
|
||||
public void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (other.CompareTag("Explosion"))
|
||||
public void OnCollisionStay2D(Collision2D col)
|
||||
{
|
||||
onExplosion();
|
||||
MoveToCenterOfTheCell();
|
||||
Unstuck();
|
||||
}
|
||||
|
||||
protected void MoveToCenterOfTheCell()
|
||||
{
|
||||
var position = transform.position;
|
||||
var absX = Mathf.RoundToInt(position.x);
|
||||
var absY = Mathf.RoundToInt(position.y);
|
||||
var newPosition = new Vector2(absX, absY);
|
||||
transform.SetPositionAndRotation(newPosition, Quaternion.identity);
|
||||
}
|
||||
|
||||
protected Vector2 ChooseRandomDirection()
|
||||
{
|
||||
return _directions.ChoseRandom();
|
||||
}
|
||||
|
||||
protected Vector2 ChooseRandomExceptCertainDirection(Vector2 direction)
|
||||
{
|
||||
return _directions.ChoseRandomExcept(direction);
|
||||
}
|
||||
|
||||
private void Unstuck()
|
||||
{
|
||||
_allowedDirections.Clear();
|
||||
StartCoroutine(CheckForObstacle(Vector3.down));
|
||||
StartCoroutine(CheckForObstacle(Vector3.left));
|
||||
StartCoroutine(CheckForObstacle(Vector3.up));
|
||||
StartCoroutine(CheckForObstacle(Vector3.right));
|
||||
if (_allowedDirections.Count == 0)
|
||||
{
|
||||
_isStuck = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction = _allowedDirections.PeekRandom();
|
||||
_isStuck = false;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator CheckForObstacle(Vector3 direction)
|
||||
{
|
||||
const int layerMask = 1 << 8; // Block layer
|
||||
var currentPosition = transform.position;
|
||||
|
||||
var hit = Physics2D.Raycast(new Vector2(currentPosition.x + 0.5f, currentPosition.y + 0.5f),
|
||||
direction, 1, layerMask);
|
||||
|
||||
if (!hit.collider)
|
||||
{
|
||||
_allowedDirections.Add(direction);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
}
|
||||
|
||||
public void onExplosion()
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
public void OnCollisionEnter2D(Collision2D col)
|
||||
{
|
||||
MoveToCenterOfTheCell();
|
||||
Unstuck();
|
||||
}
|
||||
|
||||
public void OnCollisionStay2D(Collision2D col)
|
||||
{
|
||||
MoveToCenterOfTheCell();
|
||||
Unstuck();
|
||||
}
|
||||
|
||||
protected void MoveToCenterOfTheCell()
|
||||
{
|
||||
var absX = Mathf.RoundToInt(transform.position.x);
|
||||
var absY = Mathf.RoundToInt(transform.position.y);
|
||||
Vector2 position = new Vector2(absX, absY);
|
||||
transform.SetPositionAndRotation(position, Quaternion.identity);
|
||||
}
|
||||
|
||||
protected Vector2 ChooseRandomDirection()
|
||||
{
|
||||
return _directions.ChoseRandom();
|
||||
}
|
||||
|
||||
protected Vector2 ChooseRandomExceptCertainDirection(Vector2 direction)
|
||||
{
|
||||
return _directions.ChoseRandomExcept(direction);
|
||||
}
|
||||
|
||||
private void Unstuck()
|
||||
{
|
||||
_allowedDirections.Clear();
|
||||
StartCoroutine(CheckForObstacle(Vector3.down));
|
||||
StartCoroutine(CheckForObstacle(Vector3.left));
|
||||
StartCoroutine(CheckForObstacle(Vector3.up));
|
||||
StartCoroutine(CheckForObstacle(Vector3.right));
|
||||
if(_allowedDirections.Count == 0)
|
||||
{
|
||||
_isStucked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var index = _random.Next(_allowedDirections.Count);
|
||||
Direction = _allowedDirections[index];
|
||||
_isStucked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator CheckForObstacle(Vector3 direction)
|
||||
{
|
||||
var layerMask = (1 << 8) | (1 << 9);
|
||||
var currentPosition = transform.position;
|
||||
|
||||
var hit = Physics2D.Raycast(new Vector2(currentPosition.x + 0.5f, currentPosition.y + 0.5f), direction, 1, layerMask);
|
||||
|
||||
if (!hit.collider)
|
||||
{
|
||||
_allowedDirections.Add(direction);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace src.Base
|
|||
{
|
||||
if (other.CompareTag("Explosion"))
|
||||
{
|
||||
onExplosion();
|
||||
OnExplosion();
|
||||
}
|
||||
if (other.CompareTag("Enemy"))
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ namespace src.Base
|
|||
}
|
||||
}
|
||||
|
||||
public void onExplosion()
|
||||
public void OnExplosion()
|
||||
{
|
||||
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
|
||||
/* Enemy that will change direction only on collision. */
|
||||
|
@ -9,10 +12,9 @@
|
|||
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 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
|
||||
public class OneDirectionEnemy : EnemyBase
|
||||
{
|
||||
public Vector2 OneDirection = Vector2.zero;
|
||||
|
||||
protected new void Start()
|
||||
{
|
||||
Speed = 4.0f;
|
||||
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 src.Helpers;
|
||||
using src.Base;
|
||||
using UnityEngine;
|
||||
|
||||
namespace src.Enemy
|
||||
|
@ -13,12 +13,11 @@ namespace src.Enemy
|
|||
base.Start();
|
||||
}
|
||||
|
||||
protected new void FixedUpdate()
|
||||
protected override void HandleMovement()
|
||||
{
|
||||
var pos = transform.position;
|
||||
var x = pos.x;
|
||||
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 (RandomChange())
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace src.Helpers
|
|||
var max = list.Count - 1;
|
||||
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 */
|
||||
var aux = list[randomPos];
|
||||
|
@ -23,10 +23,16 @@ namespace src.Helpers
|
|||
|
||||
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];
|
||||
list.RemoveAt(randomIndex);
|
||||
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
|
||||
{
|
||||
void onExplosion();
|
||||
void OnExplosion();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace src.Wall
|
|||
// _animator.speed = 10;
|
||||
}
|
||||
|
||||
public void onExplosion()
|
||||
public void OnExplosion()
|
||||
{
|
||||
DebugHelper.LogInfo($"Destructible wall hit by explosion {transform.position}");
|
||||
PlayDestroyAnimation();
|
||||
|
|
Loading…
Reference in a new issue