Hi Guys,
This epizod of the course make’s me crazy.
I do like always 1:1 everythink, but this time:
-Enemy don’t die
-Animation doesn’t Cancel.
How to fix it ?
Paste in your Fighter.cs script and your Health.cs script and we’ll have a look.
For future scripts, please paste them directly into this QA. It makes them much easier to access and work with.
Take a look at your Fighter.cs Update script:
private void Update()
{
timeSinceLastAttack += Time.deltaTime;
if (target == null) return;
if (target.IsDead()) return;
if (!GetIsInRange())
{
GetComponent<Mover>().MoveTo(target.transform.position);
}
else
{
GetComponent<Mover>().Cancel();
AttackBehaviour();
}
}
The trick is to make a slight adjustment in the if(target.IsDead()) statement:
if(target.IsDead())
{
Cancel(); //this will StopAttack and reset the target to null
return;
}
Please paste the text of the file into your reply.
Its on the up
The second script was identical to the first. Make your Fighter Update() look like this:
private void Update()
{
timeSinceLastAttack += Time.deltaTime;
if (target == null) return;
if (target.IsDead())
{
Cancel();
return;
}
if (!GetIsInRange())
{
GetComponent<Mover>().MoveTo(target.transform.position);
}
else
{
GetComponent<Mover>().Cancel();
AttackBehaviour();
}
}
Please do not upload your script to a third party like file.io and pass a link. I will not open another one. You can paste code directly in this editor by selecting all in your code editor and pasting it directly into these forums. Thank you.
using UnityEngine;
using RPG.Movement;
using RPG.Core;
namespace RPG.Combat
{
public class Fighter : MonoBehaviour, IAction
{
[SerializeField] float weaponRange = 2f;
[SerializeField] float timeBetweenAttacks = 1f;
[SerializeField] float weaponDamage = 5f;
Health target;
float timeSinceLastAttack = 0;
private void Update()
{
timeSinceLastAttack += Time.deltaTime;
if (target == null) return;
if(target.IsDead())
{
Cancel(); //this will StopAttack and reset the target to null
return;
}
if (!GetIsInRange())
{
GetComponent<Mover>().MoveTo(target.transform.position);
}
else
{
GetComponent<Mover>().Cancel();
AttackBehaviour();
}
}
private void AttackBehaviour()
{
transform.LookAt(target.transform);
if (timeSinceLastAttack > timeBetweenAttacks)
{
// This will trigger the Hit() event.
TriggerAttack();
timeSinceLastAttack = 0;
}
}
private void TriggerAttack()
{
GetComponent<Animator>().ResetTrigger("stopAttack");
GetComponent<Animator>().SetTrigger("attack");
}
// Animation Event
void Hit()
{
if(target == null) { return; }
target.TakeDamage(weaponDamage);
}
private bool GetIsInRange()
{
return Vector3.Distance(transform.position, target.transform.position) < weaponRange;
}
public bool CanAttack(CombatTarget combatTarget)
{
if (combatTarget == null) { return false; }
Health targetToTest = combatTarget.GetComponent<Health>();
return targetToTest != null && !targetToTest.IsDead();
}
public void Attack(CombatTarget combatTarget)
{
GetComponent<ActionScheduler>().StartAction(this);
target = combatTarget.GetComponent<Health>();
}
public void Cancel()
{
StopAttack();
target = null;
}
private void StopAttack()
{
GetComponent<Animator>().ResetTrigger("attack");
GetComponent<Animator>().SetTrigger("stopAttack");
}
}
}
public class Health : MonoBehaviour
{
[SerializeField] float healthPoints = 100f;
bool isDead = false;
public bool IsDead()
{
return isDead;
}
public void TakeDamage(float damage)
{
healthPoints = Mathf.Max(healthPoints - damage, 0);
if(healthPoints == 0)
{
Die();
}
}
private void Die()
{
if (isDead) return;
isDead = true;
GetComponent<Animator>().SetTrigger("die");
}
}
}
If it’s still not working, then we’ll need to do some Debugs to see what might be going wrong…
In Fighter.Hit()
void Hit()
{
if(target==null)
{
Debug.Log($"{name} Has hit, but has no target");
return;
}
Debug.Log($"{name} is doing {weaponDamage} to {target.name}");
target.TakeDamage(weaponDamage);
}
Then in Health.TakeDamage
public void TakeDamage(float damage)
{
healthPoints = Mathf.Max(healthPoints - damage, 0);
if(healthPoints == 0)
{
Debug.Log($"{name} has taken {damage} points of damage, killing him");
Die();
} else
{
Debug.Log($"{name} has been hit for {damage} points of damage. {healthPoints} health points remaining");
}
}
While testing these Debugs, I recommend only having one Enemy active so the console isn’t too cluttered and you can see what’s going on.
This topic was automatically closed after 18 days. New replies are no longer allowed.