Skip to content
Snippets Groups Projects
Verified Commit 03917028 authored by Adrian Paschkowski's avatar Adrian Paschkowski :thinking:
Browse files

Fighters: Add AntiPlayer movement, improve attack logic

Now immediately attacks once the Fighter can attack, instead of waiting until the next Attack tick
parent 3c257179
No related branches found
No related tags found
No related merge requests found
...@@ -69,7 +69,6 @@ GameObject: ...@@ -69,7 +69,6 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 8413529789942519730} - component: {fileID: 8413529789942519730}
- component: {fileID: 9043920546160527475}
- component: {fileID: 7070326077254508316} - component: {fileID: 7070326077254508316}
- component: {fileID: 2655505060201611074} - component: {fileID: 2655505060201611074}
- component: {fileID: 2954181336601895002} - component: {fileID: 2954181336601895002}
...@@ -101,23 +100,6 @@ Transform: ...@@ -101,23 +100,6 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9043920546160527475
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6323719953710832613}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0f5034bc83802944c9bca57c55e08978, type: 3}
m_Name:
m_EditorClassIdentifier:
m_speed: 4
m_jumpForce: 7.5
m_rollForce: 6
m_noBlood: 0
m_slideDust: {fileID: 1038168246061390451, guid: 8b8c8cc6774fb074cb9139cc631b108e, type: 3}
--- !u!114 &7070326077254508316 --- !u!114 &7070326077254508316
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -135,6 +117,7 @@ MonoBehaviour: ...@@ -135,6 +117,7 @@ MonoBehaviour:
baseAttackDamage: 10 baseAttackDamage: 10
baseArmor: 1 baseArmor: 1
currentHealth: 100 currentHealth: 100
maxDistanceToEnemy: 1
--- !u!95 &2655505060201611074 --- !u!95 &2655505060201611074
Animator: Animator:
serializedVersion: 3 serializedVersion: 3
......
...@@ -9,7 +9,6 @@ GameObject: ...@@ -9,7 +9,6 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 4805181885227780} - component: {fileID: 4805181885227780}
- component: {fileID: 114850797635947820}
- component: {fileID: 6293755257358992638} - component: {fileID: 6293755257358992638}
- component: {fileID: 95346456782871180} - component: {fileID: 95346456782871180}
- component: {fileID: 212259381048184306} - component: {fileID: 212259381048184306}
...@@ -37,20 +36,6 @@ Transform: ...@@ -37,20 +36,6 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &114850797635947820
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1689866831511430}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ba8b435a8dc3f604e9a13c4acd7081c2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_speed: 4
m_jumpForce: 7.5
--- !u!114 &6293755257358992638 --- !u!114 &6293755257358992638
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -79,7 +79,6 @@ GameObject: ...@@ -79,7 +79,6 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 4588935210562790} - component: {fileID: 4588935210562790}
- component: {fileID: 114999745408315450}
- component: {fileID: 1594948182104342364} - component: {fileID: 1594948182104342364}
- component: {fileID: 95734438044755836} - component: {fileID: 95734438044755836}
- component: {fileID: 212652212501150786} - component: {fileID: 212652212501150786}
...@@ -107,20 +106,6 @@ Transform: ...@@ -107,20 +106,6 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &114999745408315450
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1463392086428580}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ba8b435a8dc3f604e9a13c4acd7081c2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_speed: 4
m_jumpForce: 7.5
--- !u!114 &1594948182104342364 --- !u!114 &1594948182104342364
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -2,14 +2,68 @@ using System.Collections; ...@@ -2,14 +2,68 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class AntiPlayer : Fighter public class AntiPlayer : Fighter, IFighterCallback
{ {
string[] attacks = new string[] { "Attack1", "Attack2", "Attack3" }; [SerializeField, Tooltip("How close the AntiPlayer has to be to start attacking, or how far away it has to be to start running towards the target")]
float maxDistanceToEnemy = 1f;
[SerializeField] float movementSpeed = 4f;
List<Fighter> enemies = new List<Fighter>();
Fighter currentTargetEnemy;
string[] attackAnimationTriggers = new string[] { "Attack1", "Attack2", "Attack3" };
protected override void Awake()
{
base.Awake();
// TODO Eventually, the player will be able to place enemies _after_ the AntiPlayer has been created.
// Idea: Create a global GameManager-like class where scripts can register an IGameState callback,
// which has a `OnRoundStart()` callback.
foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
{
enemies.Add(enemy.GetComponent<Fighter>());
}
CalculateClosestEnemy();
animator.SetBool("Grounded", true);
}
protected override void Update()
{
base.Update();
var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
spriteRenderer.flipX = vectorToNextEnemy.x < 0;
if (Mathf.Abs(vectorToNextEnemy.x) > maxDistanceToEnemy)
{
animator.SetInteger("AnimState", 1); // Run
rigidbody.velocity = new Vector2(Mathf.Sign(vectorToNextEnemy.x) * movementSpeed, rigidbody.velocity.y);
} else
{
animator.SetInteger("AnimState", 0);
rigidbody.velocity = new Vector2(0, rigidbody.velocity.y);
}
}
protected override bool CanAttack()
{
// Can only attack when near an Enemy
var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
return Mathf.Abs(vectorToNextEnemy.x) <= maxDistanceToEnemy;
}
protected override void Attack() protected override void Attack()
{ {
animator.SetTrigger(attacks[Random.Range(0, attacks.Length)]); animator.SetTrigger(attackAnimationTriggers[Random.Range(0, attackAnimationTriggers.Length)]);
} }
void CalculateClosestEnemy()
{
enemies.Sort((a, b) => (int)Mathf.Sign(Vector3.Distance(transform.position, a.transform.position) - Vector3.Distance(transform.position, b.transform.position)));
currentTargetEnemy = enemies[0];
}
public void OnFighterDeath(Fighter fighter)
{
enemies.Remove(fighter);
CalculateClosestEnemy();
}
} }
...@@ -11,13 +11,12 @@ public class Bandit : Fighter ...@@ -11,13 +11,12 @@ public class Bandit : Fighter
float playerDistanceToAttack = 1.25f; float playerDistanceToAttack = 1.25f;
GameObject antiPlayer; GameObject antiPlayer;
SpriteRenderer spriteRenderer;
protected override void Awake() protected override void Awake()
{ {
base.Awake(); base.Awake();
spriteRenderer = GetComponent<SpriteRenderer>();
antiPlayer = GameObject.FindGameObjectWithTag("AntiPlayer"); antiPlayer = GameObject.FindGameObjectWithTag("AntiPlayer");
animator.SetBool("Grounded", true);
} }
protected override void Update() protected override void Update()
...@@ -37,12 +36,14 @@ public class Bandit : Fighter ...@@ -37,12 +36,14 @@ public class Bandit : Fighter
spriteRenderer.flipX = transform.position.x < antiPlayer.transform.position.x; spriteRenderer.flipX = transform.position.x < antiPlayer.transform.position.x;
} }
protected override bool CanAttack()
{
return GetDistanceToAntiPlayer() < playerDistanceToAttack;
}
protected override void Attack() protected override void Attack()
{ {
if (GetDistanceToAntiPlayer() < playerDistanceToAttack) animator.SetTrigger("Attack");
{
animator.SetTrigger("Attack");
}
} }
float GetDistanceToAntiPlayer() float GetDistanceToAntiPlayer()
......
...@@ -4,7 +4,7 @@ using UnityEngine; ...@@ -4,7 +4,7 @@ using UnityEngine;
public interface IFighterCallback public interface IFighterCallback
{ {
void OnDeath(); void OnFighterDeath(Fighter fighter);
} }
// Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer. // Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer.
...@@ -21,15 +21,20 @@ public abstract class Fighter : MonoBehaviour ...@@ -21,15 +21,20 @@ public abstract class Fighter : MonoBehaviour
[SerializeField] protected int currentHealth = 100; [SerializeField] protected int currentHealth = 100;
protected Animator animator; protected Animator animator;
protected new Rigidbody2D rigidbody;
protected SpriteRenderer spriteRenderer;
protected bool alive { get => currentHealth > 0; } protected bool alive { get => currentHealth > 0; }
protected FighterTypes fighterType; protected FighterTypes fighterType;
protected abstract bool CanAttack();
protected abstract void Attack(); protected abstract void Attack();
float timeSinceLastAttack = 0f; float timeSinceLastAttack = float.PositiveInfinity;
protected virtual void Awake() protected virtual void Awake()
{ {
animator = GetComponent<Animator>(); animator = GetComponent<Animator>();
rigidbody = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
fighterType = FighterTypes.ENEMY; fighterType = FighterTypes.ENEMY;
} }
...@@ -42,12 +47,19 @@ public abstract class Fighter : MonoBehaviour ...@@ -42,12 +47,19 @@ public abstract class Fighter : MonoBehaviour
{ {
if (alive) if (alive)
{ {
timeSinceLastAttack += Time.deltaTime; if (CanAttack())
var timeUntilNextAttack = baseAttackSpeed - timeSinceLastAttack;
if (timeUntilNextAttack <= 0) // TODO only attack when near opposing faction
{ {
Attack(); timeSinceLastAttack += Time.deltaTime;
timeSinceLastAttack = -timeUntilNextAttack; // To account for overshoot var timeUntilNextAttack = baseAttackSpeed - timeSinceLastAttack;
if (timeUntilNextAttack <= 0)
{
Attack();
timeSinceLastAttack = float.IsInfinity(timeUntilNextAttack) ? 0 : -timeUntilNextAttack; // To account for overshoot
}
}
else
{
timeSinceLastAttack = float.PositiveInfinity;
} }
} }
} }
...@@ -63,7 +75,7 @@ public abstract class Fighter : MonoBehaviour ...@@ -63,7 +75,7 @@ public abstract class Fighter : MonoBehaviour
if (currentHealth == 0) if (currentHealth == 0)
{ {
animator.SetTrigger("Death"); animator.SetTrigger("Death");
callbacks.ForEach(c => c.OnDeath()); callbacks.ForEach(c => c.OnFighterDeath(this));
// TODO (Depending on the death animation) only destroy on round end so that corpses stay on the ground // TODO (Depending on the death animation) only destroy on round end so that corpses stay on the ground
// Destroy(gameObject); // Destroy(gameObject);
} }
...@@ -78,6 +90,7 @@ public abstract class Fighter : MonoBehaviour ...@@ -78,6 +90,7 @@ public abstract class Fighter : MonoBehaviour
return StatsManager.instance.fighterStats[fighterType]; return StatsManager.instance.fighterStats[fighterType];
} }
// TODO Move to new common Enemy subclass which also has reference to AnitPlayer
void OnTriggerEnter2D(Collider2D other) void OnTriggerEnter2D(Collider2D other)
{ {
if (other.CompareTag("AntiPlayer")) if (other.CompareTag("AntiPlayer"))
......
...@@ -11,13 +11,12 @@ public class Tank : Fighter ...@@ -11,13 +11,12 @@ public class Tank : Fighter
float playerDistanceToAttack = 1.25f; float playerDistanceToAttack = 1.25f;
GameObject antiPlayer; GameObject antiPlayer;
SpriteRenderer spriteRenderer;
protected override void Awake() protected override void Awake()
{ {
base.Awake(); base.Awake();
spriteRenderer = GetComponent<SpriteRenderer>();
antiPlayer = GameObject.FindGameObjectWithTag("AntiPlayer"); antiPlayer = GameObject.FindGameObjectWithTag("AntiPlayer");
animator.SetBool("Grounded", true);
} }
protected override void Update() protected override void Update()
...@@ -37,12 +36,14 @@ public class Tank : Fighter ...@@ -37,12 +36,14 @@ public class Tank : Fighter
spriteRenderer.flipX = transform.position.x < antiPlayer.transform.position.x; spriteRenderer.flipX = transform.position.x < antiPlayer.transform.position.x;
} }
protected override bool CanAttack()
{
return GetDistanceToAntiPlayer() < playerDistanceToAttack;
}
protected override void Attack() protected override void Attack()
{ {
if (GetDistanceToAntiPlayer() < playerDistanceToAttack) animator.SetTrigger("Attack");
{
animator.SetTrigger("Attack");
}
} }
float GetDistanceToAntiPlayer() float GetDistanceToAntiPlayer()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment