Hello.
I’ve got a bug, my attack is not being cancelled. If I serialize Target field it’s still there.
Fighter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Movement;
using RPG.Core;
namespace RPG.Combat
{
public class Fighter : MonoBehaviour, IAction
{
[SerializeField] float weaponRange = 2f;
[SerializeField] Transform target;
private void Update()
{
if (target == null) return;
bool isInRange = IsInRange();
if (target != null && !IsInRange())
{
GetComponent<PlayerMovement>().MovePlayer(target.position);
}
else
{
GetComponent<PlayerMovement>().Cancel();
}
}
public void Attack(CombatTarget _combatTarget)
{
GetComponent<ActionScheduler>().StartAction(this);
target = _combatTarget.transform;
}
public void Cancel()
{
target = null;
}
private bool IsInRange()
{
return Vector3.Distance(transform.position, target.position) < weaponRange;
}
}
}
PlayerController
using RPG.Movement;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Combat;
namespace RPG.Control
{
public class PlayerController : MonoBehaviour
{
void Update()
{
if(InteractWithCombat()) return;
if(InteractWithMovement()) return;
print("Nothing to do...");
}
private bool InteractWithMovement()
{
RaycastHit hit;
bool hasCorrectPosition = Physics.Raycast(GetRay(), out hit);
if (hasCorrectPosition)
{
if (Input.GetMouseButton(0))
{
GetComponent<PlayerMovement>().StartMovementAction(hit.point);
}
return true;
}
return false;
}
private bool InteractWithCombat()
{
RaycastHit[] hits = Physics.RaycastAll(GetRay());
foreach (RaycastHit hit in hits)
{
CombatTarget target = hit.transform.GetComponent<CombatTarget>();
if (target == null) continue;
if (Input.GetMouseButton(0))
{
GetComponent<Fighter>().Attack(target);
}
return true;
}
return false;
}
private static Ray GetRay()
{
return Camera.main.ScreenPointToRay(Input.mousePosition);
}
}
}
PlayerMovement
using RPG.Combat;
using RPG.Core;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
namespace RPG.Movement
{
public class PlayerMovement : MonoBehaviour, IAction
{
NavMeshAgent navMeshAgent;
private void Start()
{
navMeshAgent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
UpdateAnimator();
}
void UpdateAnimator()
{
//Update animator
Vector3 velocity = navMeshAgent.velocity;
Vector3 localVelocity = transform.InverseTransformDirection(velocity);
float speed = localVelocity.z;
GetComponent<Animator>().SetFloat("ForwardSpeed", speed);
}
public void MovePlayer(Vector3 _destination)
{
navMeshAgent.destination = _destination;
navMeshAgent.isStopped = false;
}
public void StartMovementAction(Vector3 _destination)
{
GetComponent<ActionScheduler>().StartAction(this);
MovePlayer(_destination);
}
public void Cancel()
{
navMeshAgent.isStopped = true;
}
}
}
ActionScheduler
using System.Collections;
using System.Collections.Generic;
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();
}
}
}
}
IAction
namespace RPG.Core
{
public interface IAction
{
void Cancel();
}
}
Where’s the issue?