I have made a simple ray character control script, where when I use the left mouse button, the character follows the mouse point and wants to reach the destination.
Here’s the simple code:
public class PlayerMovement : MonoBehaviour
{
NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
agent = GetComponent<NavMeshAgent> ();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
agent.SetDestination(hit.point);
}
}
}
}
Now I want to enhance my character, so that when I use my right mouse button the character no longer want’s to reach the previous destination, locks in one place (except rotates to the mouse pointer), while casting a spell/shoot/hit etc.
Right now I can shoot a fireball, but the character continuously rotates to my mouse and if I shoot, the character won’t stop, until it reaches the previous destination.
I’m looking for a general answer, what should I check or where should I begin, what kind of scripts do I need.
I always use aaa tap d ddd tap a, but i never use www s/sss w. i kind of got used to a style that i never walk straight forward if im encountering an enemy, if i peek i always only do a/d + my mouse movement. just because it feels so weird to to the www s/sss w somehow https://www.krogereschedule.us/
Having a variable to keep track of your player states might help. When you want it to stop moving, just set agent.isStopped = true;
I’ve put together a basic skeleton that you could reference in this, just bundle the various things that the player should do into separate methods that would change depending on the player’s actions
enum PlayerState {Moving, Stopped, Shooting}
PlayerState currentState = PlayerState.Stopped;
bool isShooting = false; //Variable to prevent spam
void Update()
{
if(Input.GetMouseButton(0))
{
Move();
}
//If you hold right click, you aim
if(Input.GetMouseButton(1))
{
Aim();
}
//I'm assuming your system is hold down and release, so upon releasing you can do the shooting here
if(Input.GetMouseButtonUp(1))
{
Shoot();
}
if(currentState == PlayerState.Stopped || currentState == PlayerState.Shooting)
{
agent.isStopped = true;
}
}
void Shoot(){
//Since this is called in update you should make sure it's called one at a time
if(isShooting)
{
return;
}
isShooting = true;
StartCoroutine("ShootCo");
}
//How I would do it is a coroutine so there is a delay before your character moves again
IEnumerator ShootCo()
{
//Do the shooting
currentState = PlayerState.Shooting;
yield return new WaitForSeconds(1f);
currentState = PlayerState.Stopped; //You're back to stopped state and awaiting further action
}
void Aim(){
currentState = PlayerState.Stopped;
//Do the aiming stuff here
}
void Move()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
agent.isStopped = false; //If the player was stopped before make it continue
agent.SetDestination(hit.point);
currentState = PlayerState.Moving; //Mark player as moving
}
}