Start AI COntroller
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
using UnityEngine;
|
||||
using RPG.Combat;
|
||||
|
||||
public class CombatTarget : MonoBehaviour
|
||||
namespace RPG.Combat
|
||||
{
|
||||
// This class is intentionally left empty.
|
||||
// It serves as a marker to identify combat targets in the game.
|
||||
[RequireComponent(typeof(Health))]
|
||||
public class CombatTarget : MonoBehaviour
|
||||
{
|
||||
// This class is intentionally left empty.
|
||||
// It serves as a marker to identify combat targets in the game.
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,85 @@
|
||||
using UnityEngine;
|
||||
using RPG.Movement;
|
||||
using UnityEngine.Rendering;
|
||||
using RPG.Core;
|
||||
|
||||
namespace RPG.Combat
|
||||
{
|
||||
public class Fighter : MonoBehaviour
|
||||
public class Fighter : MonoBehaviour, IAction
|
||||
{
|
||||
[SerializeField]
|
||||
private float weaponRange = 2f;
|
||||
Transform target;
|
||||
private void Update()
|
||||
[SerializeField] private float timeBetweenAttacks = 1f;
|
||||
[SerializeField] private float weaponRange = 2f;
|
||||
[SerializeField] private float weaponDamage = 5f;
|
||||
Health target;
|
||||
private float timeSinceLastAttack = 0;
|
||||
void Update()
|
||||
{
|
||||
timeSinceLastAttack += Time.deltaTime;
|
||||
if (target == null) return;
|
||||
if (target.IsDead()) return;
|
||||
if (!GetIsInRange())
|
||||
{
|
||||
GetComponent<Mover>().MoveTo(target.position);
|
||||
GetComponent<Mover>().MoveTo(target.transform.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetComponent<Mover>().Stop();
|
||||
GetComponent<Mover>().Cancel();
|
||||
AttackBehaviour();
|
||||
}
|
||||
}
|
||||
|
||||
private void AttackBehaviour()
|
||||
{
|
||||
transform.LookAt(target.transform);
|
||||
if (timeSinceLastAttack > timeBetweenAttacks)
|
||||
{
|
||||
//This will trigger the Hit() event.
|
||||
TriggerAttack();
|
||||
timeSinceLastAttack = 0;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
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.position) <= weaponRange;
|
||||
return Vector3.Distance(transform.position, target.transform.position) <= weaponRange;
|
||||
}
|
||||
|
||||
public void Attack(CombatTarget combatTarget)
|
||||
public bool CanAttack(GameObject combatTarget)
|
||||
{
|
||||
target = combatTarget.transform;
|
||||
if (combatTarget == null) return false;
|
||||
Health targetToTest = combatTarget.GetComponent<Health>();
|
||||
return targetToTest != null && !targetToTest.IsDead();
|
||||
}
|
||||
|
||||
public void Attack(GameObject combatTarget)
|
||||
{
|
||||
GetComponent<ActionScheduler>().StartAction(this);
|
||||
target = combatTarget.GetComponent<Health>();
|
||||
}
|
||||
public void Cancel()
|
||||
{
|
||||
target = null;
|
||||
StopAttack();
|
||||
target = null;
|
||||
}
|
||||
|
||||
private void StopAttack()
|
||||
{
|
||||
GetComponent<Animator>().ResetTrigger("attack");
|
||||
GetComponent<Animator>().SetTrigger("stopAttack");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
Assets/Scripts/Combat/Health.cs
Normal file
32
Assets/Scripts/Combat/Health.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPG.Combat
|
||||
{
|
||||
public class Health : MonoBehaviour
|
||||
{
|
||||
[SerializeField] float health = 100f;
|
||||
bool isDead = false;
|
||||
|
||||
public bool IsDead()
|
||||
{
|
||||
return isDead;
|
||||
}
|
||||
|
||||
public void TakeDamage(float damage)
|
||||
{
|
||||
health = Mathf.Max(health - damage, 0);
|
||||
if(health == 0)
|
||||
{
|
||||
Die();
|
||||
}
|
||||
}
|
||||
|
||||
private void Die()
|
||||
{
|
||||
if (isDead) return;
|
||||
isDead = true;
|
||||
GetComponent<Animator>().SetTrigger("die");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Combat/Health.cs.meta
Normal file
2
Assets/Scripts/Combat/Health.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fc6fa8368af1d9b8a0ecc2745f48ebe
|
||||
39
Assets/Scripts/Control/AIController.cs
Normal file
39
Assets/Scripts/Control/AIController.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using RPG.Combat;
|
||||
using RPG.Core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
namespace RPG.Control
|
||||
{
|
||||
public class AIController : MonoBehaviour,IAction
|
||||
{
|
||||
[SerializeField] float chaseDistance = 5f;
|
||||
Fighter fighter;
|
||||
GameObject player;
|
||||
void Start()
|
||||
{
|
||||
fighter = GetComponent<Fighter>();
|
||||
player = GameObject.FindWithTag("Player");
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (InAttackRangeOfPlayer() && fighter.CanAttack(player))
|
||||
fighter.Attack(player);
|
||||
else
|
||||
{
|
||||
fighter.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private bool InAttackRangeOfPlayer()
|
||||
{
|
||||
float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
|
||||
return distanceToPlayer < chaseDistance;
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Control/AIController.cs.meta
Normal file
2
Assets/Scripts/Control/AIController.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c781eee3ca72ca7a1b692987335cedc1
|
||||
@@ -43,11 +43,14 @@ namespace RPG.Control
|
||||
foreach (RaycastHit hit in hits)
|
||||
{
|
||||
CombatTarget target = hit.transform.GetComponent<CombatTarget>();
|
||||
if (target == null) continue;
|
||||
if (target == null) continue;
|
||||
if (!GetComponent<Fighter>().CanAttack(target.gameObject))
|
||||
continue;
|
||||
|
||||
if (interactAction.WasPressedThisFrame())
|
||||
{
|
||||
//MoveToCursor();
|
||||
GetComponent<Fighter>().Attack(target);
|
||||
GetComponent<Fighter>().Attack(target.gameObject);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
18
Assets/Scripts/Core/ActionScheduler.cs
Normal file
18
Assets/Scripts/Core/ActionScheduler.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPG.Core
|
||||
{
|
||||
public class ActionScheduler : MonoBehaviour
|
||||
{
|
||||
IAction currentAction;
|
||||
public void StartAction(IAction action)
|
||||
{
|
||||
if (currentAction == action) return;
|
||||
if (currentAction != null)
|
||||
{
|
||||
currentAction.Cancel();
|
||||
}
|
||||
currentAction = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Core/ActionScheduler.cs.meta
Normal file
2
Assets/Scripts/Core/ActionScheduler.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ff1a795ab12b59d88076953d397a6d5
|
||||
7
Assets/Scripts/Core/IAction.cs
Normal file
7
Assets/Scripts/Core/IAction.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace RPG.Core
|
||||
{
|
||||
public interface IAction
|
||||
{
|
||||
void Cancel();
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Core/IAction.cs.meta
Normal file
2
Assets/Scripts/Core/IAction.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b307fcbc3bbf912cbad01e283421bba
|
||||
@@ -1,11 +1,11 @@
|
||||
using RPG.Combat;
|
||||
using RPG.Core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace RPG.Movement
|
||||
{
|
||||
public class Mover : MonoBehaviour
|
||||
public class Mover : MonoBehaviour, IAction
|
||||
{
|
||||
[SerializeField] private Transform target;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace RPG.Movement
|
||||
}
|
||||
public void StartMoveAction(Vector3 destination)
|
||||
{
|
||||
GetComponent<Fighter>().Cancel();
|
||||
GetComponent<ActionScheduler>().StartAction(this);
|
||||
MoveTo(destination);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace RPG.Movement
|
||||
navMeshAgent.destination = destination;
|
||||
navMeshAgent.isStopped = false;
|
||||
}
|
||||
public void Stop()
|
||||
public void Cancel()
|
||||
{
|
||||
navMeshAgent.isStopped = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user