Be the first to post for 'Using Gizmos To Visualise Code'!


Maybe less Gizmos…:joy::joy:

2 Likes

With reference to the following codes, my character will move to the destination and start spinning around (not staying still). This issue was fixed in the last video when a braking distance code was put in place. However, with the new code in this video, the issue is back.

private void WalkToDestination()
{
var playerToClickPoint = currentDestination - transform.position;
if (playerToClickPoint.magnitude >= 0)
{
thirdPersonCharacter.Move(playerToClickPoint, false, false);
}
thirdPersonCharacter.Move(Vector3.zero, false, false);
}

It seems that playerToClickPoint.magnitude drops to a value close to 0, about 0.2, so the code to stop the player movement was never executed. So changing the code to if (playerToClickPoint.magnitude >= 0.2f) will resolve the issue, but is that the correct way to resolve it?

Any advice please?

Thank you!

Hi, I had the same issue as you and I just replace the 0 with the walkMoveStopRadius value (so every time you change it change the value)

The bug occurs because of a logic error in the code. Prior to adding the ShortDestination function, the player would walk toward the destination until he/she was within the walkMoveStopRadius distance away (this is in the line “if (playerToClickPoint >= walkMoveStopRadius)”). With the addition of the ShortDestination function, the calculation for the point occurs before the player attempts to walk to it. So the player is now trying to reach an exact point the walkMoveStopRadius distance away from where you clicked, displayed in the line “if(playerToClickPoint.magnitude >= 0f)”.

Re-adding “if (playerToClickPoint >= walkMoveStopRadius)” as opposed to 0 will fix the issue, BUT now your player will stop twice the walkMoveStopRadius away from where you click. This is because the destination has already been shortened by that amount and then you walk to that distance away from destination again, meaning movement clicks are becoming less precise.

I don’t have a particularly eloquent solution yet, besides reverting the walk movement calculations back to how they were before adding the ShortDestination function and then only using the ShortDestination function for the attack stop calculations. I am hoping a better solution is found later through the lessons.

1 Like

I confirm the problem but i’ve found a solution (not perfect tho)

I’ve added a variable where i store the last computed magnitude distance and then check that value into the WalkToDestination method, in order to prevent the bug happening again, while preserving the correct distance stored in the radius

I past the whole class here for reference

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

[RequireComponent(typeof(ThirdPersonCharacter))]
public class PlayerMovement : MonoBehaviour {
	ThirdPersonCharacter _character;   // A reference to the ThirdPersonCharacter on the object
	CameraRaycaster cameraRaycaster;

	/// <summary>
	/// current player destination
	/// </summary>
	Vector3 currentDestination;

	/// <summary>
	/// location where the mouse has been clicked
	/// </summary>
	Vector3 clickPoint;
	[SerializeField]
	float walkMoveStopRadius = 0.2f;

	[SerializeField]
	float attackMoveStopRadius = 5f;

	/// <summary>
	/// is the player moved by direct commands? (gamepad/keyboard)
	/// </summary>
	bool _isInDirectMode = false;

	private bool _isCrouching;
	private bool _isJumping;

	private float _previousDistanceMagnitude = 0;

	private void Start() {
		cameraRaycaster = Camera.main.GetComponent<CameraRaycaster>();
		_character = GetComponent<ThirdPersonCharacter>();
		currentDestination = transform.position;
	}


	private void Update() {
		if (!_isJumping) {
			_isJumping = CrossPlatformInputManager.GetButtonDown("Jump");
		}

		//G for gamepad.
		// TODO allow player map key
		if (Input.GetKeyDown(KeyCode.G)) {
			_isInDirectMode = !_isInDirectMode;
			currentDestination = transform.position;
		}
	}

	// Fixed update is called in sync with physics
	private void FixedUpdate() {
		_isCrouching = Input.GetKey(KeyCode.LeftControl);

		if (_isInDirectMode) {
			ProcessDirectMovement();
		}
		else {
			ProcessMouseMovement();
		}

		// pass all parameters to the character control script
		_isJumping = false;
	}

	private void ProcessDirectMovement() {
		// read inputs
		float h = Input.GetAxis("Horizontal");
		float v = Input.GetAxis("Vertical");

		// calculate camera relative direction to move:
		Vector3 camForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
		Vector3 move = v * camForward + h * Camera.main.transform.right;

		_character.Move(move, _isCrouching, _isJumping);
	}

	private void ProcessMouseMovement() {
		if (Input.GetMouseButton(0)) {
			clickPoint = cameraRaycaster.hit.point;
			switch (cameraRaycaster.currentLayerHit) {
				case Layer.Walkable:
					currentDestination = ShortDestination(clickPoint, walkMoveStopRadius);
					_previousDistanceMagnitude = float.MaxValue;
					break;
				case Layer.Enemy:
					currentDestination = ShortDestination(clickPoint, attackMoveStopRadius);
					break;
				case Layer.RaycastEndStop:
					break;
				default:
					break;
			}
		}

		WalkToDestination();
	}

	private void WalkToDestination() {
		var playerToClickPoint = currentDestination - transform.position;

		if (_previousDistanceMagnitude > walkMoveStopRadius || (playerToClickPoint.magnitude < _previousDistanceMagnitude)) {
			_character.Move(playerToClickPoint, _isCrouching, _isJumping);
			_previousDistanceMagnitude = playerToClickPoint.magnitude;
		}
		else {
			_character.Move(Vector3.zero, _isCrouching, _isJumping);
		}
	}

	private Vector3 ShortDestination(Vector3 destination, float shortening) {
		Vector3 reductionVector = (destination - transform.position).normalized * shortening;
		return destination - reductionVector;
	}


	void OnDrawGizmos() {
		Gizmos.color = Color.black;
		Gizmos.DrawLine(transform.position, currentDestination);
		Gizmos.color = Color.green;
		Gizmos.DrawSphere(currentDestination, 0.1f);
		Gizmos.color = Color.red;
		Gizmos.DrawSphere(clickPoint, 0.15f);

		//attack Gizmos
		Gizmos.color = Color.red;
		GizmosEx.DrawCircle(transform.position, attackMoveStopRadius);
	}
}

note the _previousDistanceMagnitude variable and check where i use it

P.S.
I borrowed the code posted here by @Rilifaen to draw the circle Gizmo, and to keep it cleaner I’ve created a static class GizmoEx where i want to add other kind of Gizmos in the future, so to keep the code clean and be usable in other places

add a file named GizmosEx.cs in your project with this code

namespace UnityEngine {
	/// <summary>
	/// Extended methods for Gizmos class
	/// </summary>
	public static class GizmosEx {
		public static void DrawCircle(Vector3 center, float radius, float step = 0.1f) {
			float theta = 0.0f;
			float x = radius * Mathf.Cos(theta);
			float y = radius * Mathf.Sin(theta);
			Vector3 position = center + new Vector3(x, 0, y);
			Vector3 newPosition = position;
			Vector3 lastPosition = position;
			for (theta = step; theta < Mathf.PI * 2; theta += step) {
				x = radius * Mathf.Cos(theta);
				y = radius * Mathf.Sin(theta);
				newPosition = center + new Vector3(x, 0, y);
				Gizmos.DrawLine(position, newPosition);
				position = newPosition;
			}
			Gizmos.DrawLine(position, lastPosition);
		}
	}
}

I had choose to do an action-adventure RPG and just made this cone mesh gizmo to help me adjust the line of sight of the player. Very handy.

Is it even possible to have a character movement that includes both one click to run to that point and also hold mouse to run around and stop when mouse is released… i’ve tried everything to get both to work together but it seems impossible .

I’ve implemented the attackMoveStop perfectly and have run through all the code to see where it might be going wrong but I seem to be stuck…

When I click on a walkable layer Ethan moves just fine, when I click on an enemy my clickpoint gizmo appears on the enemy exactly where I clicked but without Ethan moving.

I have as I said checked the code but have also checked layering is correct, also

Anyone else having this issue?


quick take of my gizmos

Does the issue with the player character spinning around on the spot when it gets to its destination get solved in a future lecture?

The change of condition in the WalkToDestination function from playerToClickPoint.magnitude >= walkStopMoveRadius to playerToClickPoint.magnitude >= 0 would seem to make the whole of the if else statement redundant.

I think it does, yes.

Later it switches to the player using a navmesh to move around which appears to resolve it.

hey, hello I don’t know if you fixed this bug already but I had the same issue.
It is easy to fix, just check what I did:
private void WalkToDestination()
{
var playerClickToPoint = currentDestination - transform.position;
if (playerClickToPoint.magnitude > 0.01)
{
thirdPersonCharacter.Move(playerClickToPoint, false, false);
}
else
{
thirdPersonCharacter.Move(Vector3.zero, false, false);
}
}
I put 0.01 because you have to prevent the minimum error possibilities, so it’s very easy. At least it worked for me! hope it helps you. See ya

5 meters seems more like a ranged weapon distance than a melee distance. It just seems YUGE when I try it out and see the gizmo sphere. I would think 1.5 or 2 meters at the very most If you’re hitting the enemy with a sword?

Hello,I don’t seem to even have the player gizmo in my list,also everytime I try to add code I get an error for
feature “local functions” not avail in C#

I have to say that this is one of the most confusing of your videos that I have seen. Gizmos themselves seem to be pretty straightforward but the code changes and refactoring that you do feels very rushed and difficult to follow, possibly because you copy in chunks of code ‘from one I prepared earlier’, although you do review the code it takes quite a while to understand exactly what you are doing. I mention this because it seems to be such a contrast to your usual style of carefully taking the student through the code and building up understanding step by step.

2 Likes

@MithrilMan thank you your post really helped with my concept for my game. I am using 1.5 for my melee attack radius. that comes out to about 5 feet. For my ranged I’m going to use 10.

thx man yo saved my day…I had a same issue now solved .thank you very much.

Hey would anyone be kind enough to share their code up to this point. I was trying to code a little in my own direction but I’m not quite skilled enough as a coder to do that yet >_< so I want to follow this project exactly but I don’t really want to rewatch the last 4 hours to get all the code

This is my gizmos for move and attack

Privacy & Terms