Movement glitch (and fix!)

Hey there,
I thought it’s worth noting that at the end of the video click-to-move does work.
However, after the character reaches near the radius and stops, it will stay locked to this position unless
we click-to-move on another location, meaning WASD movement will not work (the character will run back to
the last click destination).

The reason is because in PlayerMovement.cs we keep calling:
m_Character.Move(playerToClickPoint, false, false);
which keeps the character locked to that point.

My solution to this problem was to keep a bool value (I called it ‘reachedDestination’), initialize it to false,
and once near the walkMoveStopRadius set reachedDestination to true.
After that, we check the value of reachedDestination, and only if it’s false then we move the character.
Also, when we detect that cameraRaycaster.layerHit hits a walkable layer again,
we’ll need to set reachedDestination to false to allow movement again.

Here is my version of FixedUpdate (entire PlayerMovement.cs attached):

using System;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

[RequireComponent(typeof (ThirdPersonCharacter))]
public class PlayerMovement : MonoBehaviour
{
	[SerializeField] float walkMoveStopRadius = 0.2f;

    ThirdPersonCharacter m_Character;   // A reference to the ThirdPersonCharacter on the object
    CameraRaycaster cameraRaycaster;
    Vector3 currentClickTarget;
	bool reachedDestination;
    
    private void Start()
    {
        cameraRaycaster = Camera.main.GetComponent<CameraRaycaster>();
        m_Character = GetComponent<ThirdPersonCharacter>();
        currentClickTarget = transform.position;
        reachedDestination = true;
    }

// Fixed update is called in sync with physics
private void FixedUpdate()
{
    if (Input.GetMouseButton(0))
    {
		print("Cursor raycast hit: " + cameraRaycaster.hit.collider.gameObject.name.ToString() + ", layer: " + cameraRaycaster.hit.collider.gameObject.layer);
		switch (cameraRaycaster.layerHit) {
			case Layer.Walkable:
				currentClickTarget = cameraRaycaster.hit.point;
				reachedDestination = false;
				break;
			case Layer.Enemy:
				print("Ignoring enemy click!");
				break;
			default:
			print("Unexpected layer clicked!");
				break;
		}

    }
	Vector3 playerToClickPoint = currentClickTarget - transform.position;
	if (playerToClickPoint.magnitude < walkMoveStopRadius) {
		reachedDestination = true;
	}
	if (reachedDestination == false) {
		m_Character.Move(playerToClickPoint, false, false);
	}
  }
}

Nice idea. But this wouldn’t allow you to control character using WASD while click movement is in progress and it might result in some funny behavior. I would suggest using a bool (named, for example isControlledByKeyboard) and setting it to true when either of WASD is pressed down and back to false when it is released. This should allow you to use WASD even when click movement is in progress. But then again, depends on what you want to achieve :slight_smile:.

Privacy & Terms