I followed a tutorial on how to do grid based movement. It’s where a character would move forward a fixed number of steps, in order to snap to grid, or something like that.
The tutorial was very useful, only that I couldn’t find a way to adjust how far my character would travel.
I tried using a multiplier, multiplying a value to the horizontal input. Meaning that if it’s 1, I multiply it by the multiplier(which is let’s say 2), so it moves 2 steps instead of one. Yeah, I probably got that wrong. And it doesn’t work as intended ingame to, sometimes moving the move point too far, or moving the player too far.
Here’s the script, it still has the multiplier on it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerBattleController : MonoBehaviour
{
[Header("Components")]
[SerializeField] private Rigidbody2D rb; //what makes the player move
[SerializeField] private Transform movePoint;//where is our player moving next?
[Header("Movement")]
[SerializeField] private float moveSpeed;
[SerializeField] private float distanceMultiplier;
[Header("Collision")]
[SerializeField] private LayerMask whatisTile;
void Start()
{
rb = GetComponent<Rigidbody2D>();
movePoint.parent = null; //makes the movePoint it's own man!
}
void Update()
{
//goes to movepoint
transform.position = Vector3.MoveTowards(transform.position, movePoint.position, moveSpeed * Time.deltaTime);
//so player won't go haywire
if (Vector3.Distance(transform.position, movePoint.position) <= 0.05)
{
//basic movement
if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) == 1f)
{
if (Physics2D.OverlapCircle(movePoint.position + new Vector3(Input.GetAxisRaw("Horizontal") * distanceMultiplier, 0f, 0f), 0.2f, whatisTile))
{
movePoint.position += new Vector3(Input.GetAxisRaw("Horizontal") * distanceMultiplier, 0f, 0f);
}
}
if (Mathf.Abs(Input.GetAxisRaw("Vertical")) == 1f)
{
if (Physics2D.OverlapCircle(movePoint.position + new Vector3(0f, Input.GetAxisRaw("Vertical"), 0f) * distanceMultiplier, 0.2f, whatisTile))
{
movePoint.position += new Vector3(0f, Input.GetAxisRaw("Vertical") * distanceMultiplier, 0f);
}
}
}
}
}
It kinda depends on what you want to happen. Do you want the player to care about all the spots in between? If you just multiply it by 2x and do one move, it will skip right over it. See below for why.
Also, if things are in a grid, generally you don’t put a Rigidbody on them because physics operates in continuous space. On a grid you want to control exactly where they are: on grid centers.
“Yes, but I want them to move smoothly!” Great, but that doesn’t require a Rigidbody. That requires you to move them smoothly, a little bit each frame, until they arrive at their destination.
Smoothing movement between any two particular values:
You have currentQuantity and desiredQuantity.
only set desiredQuantity
the code always moves currentQuantity towards desiredQuantity
read currentQuantity for the smoothed value
Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.
Another approach would be to use a tweening package line LeanTween, DOTween or iTween.
Besides, physics is potentially being misused above in any case: with Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly as you are doing above, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.
Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.