- Home /
How to move object grid base continuously?
I want to move object continously when I press button just once grid to grid. When I press button to make object move to another direction, it should wait until object is right on the grid and starts to move another direction. Those are my codes. It moves continously when I press once but doesn't move grid to grid
void GridMove()
{
Debug.Log("ye");
if(Input.GetKeyDown(KeyCode.W))
{
forward = true;
back = false;
left = false;
right = false;
}
if (forward)
{
StartCoroutine(MoveCharacter(Vector3.forward * Time.deltaTime));
}
if (Input.GetKeyDown(KeyCode.S))
{
back = true;
forward = false;
left = false;
right = false;
}
if (back)
{
StartCoroutine(MoveCharacter(Vector3.back * Time.deltaTime));
}
if (Input.GetKeyDown(KeyCode.A))
{
left = true;
back = false;
forward = false;
right = false;
}
if (left)
{
StartCoroutine(MoveCharacter(Vector3.left * Time.deltaTime));
}
if (Input.GetKeyDown(KeyCode.D))
{
right = true;
back = false;
forward = false;
left = false;
}
if (right)
{
StartCoroutine(MoveCharacter(Vector3.right * Time.deltaTime));
}
}
private IEnumerator MoveCharacter(Vector3 direction)
{
float elapsedTime = 0f;
originPos = transform.position;
targetPos = originPos + direction;
while (elapsedTime < timeToMove)
{
transform.position = Vector3.Lerp(originPos, targetPos, (elapsedTime / timeToMove));
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = targetPos;
}
Answer by DenisIsDenis · Jun 22, 2021 at 11:50 AM
In general, after looking at your code, I thought that a different approach is needed here. In the following script, I did something like what you need. Comments in the script can help to understand.
using UnityEngine;
public class CubeMovingOnGrid : MonoBehaviour
{
//It is much easier to use a direction vector
//than four bool variables and four conditions.
Vector3 movingDirection = Vector3.forward;
//We use end position to snap to grid.
Vector3 targetPosition;
float timeToMove = 5f;
float elapsedTime;
//Grid cell size
public float lengthCellGrid = 1;
public float speed = 1;
void Start()
{
targetPosition = transform.position;
}
void Update()
{
GridMove();
}
void GridMove()
{
elapsedTime += Time.deltaTime;
if (Input.GetKeyDown(KeyCode.W))
{
movingDirection = Vector3.forward * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.S))
{
movingDirection = Vector3.back * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.A))
{
movingDirection = Vector3.left * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.D))
{
movingDirection = Vector3.right * lengthCellGrid;
}
// Shift targetPosition if we got to it
if (targetPosition == transform.position && elapsedTime < timeToMove)
{
targetPosition += movingDirection;
}
// Moving to targetPosition
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
}
Thanks for answer. But this is not actually what I want. But ıt's not working as I want
For example when object tries to turn right when its going forward, ıt should wait until grid ends. But not according to time. I used time for it but its not logical. I want object to know wheter its in grid or not. Should I use layer mask or something like that ?
I probably figured out what you need. If I'm not mistaken, you need the following:
1) The player controls the character, and when he stops, the cube stops at a certain cell exactly in the middle.
2) You can turn the cube only when it is exactly in the middle of the cell, in order to avoid walking between cells.
If so, then by modifying my first script a little, you can get the desired result:
using UnityEngine;
public class CubeMovingOnGrid : MonoBehaviour
{
//It is much easier to use a direction vector
//than four bool variables and four conditions.
Vector3 movingDirection = Vector3.forward;
//We use end position to snap to grid.
Vector3 targetPosition;
//Grid cell size
public float lengthCellGrid = 1;
public float speed = 1;
void Start()
{
targetPosition = transform.position;
}
void Update()
{
GridMove();
}
void GridMove()
{
if (Input.GetKeyDown(KeyCode.W))
{
movingDirection = Vector3.forward * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.S))
{
movingDirection = Vector3.back * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.A))
{
movingDirection = Vector3.left * lengthCellGrid;
}
if (Input.GetKeyDown(KeyCode.D))
{
movingDirection = Vector3.right * lengthCellGrid;
}
// Shift targetPosition if we got to it
bool isGoing = Input.GetButton("Horizontal") || Input.GetButton("Vertical");
if (targetPosition == transform.position && isGoing)
{
Ray ray = new Ray(transform.position + Vector3.up + movingDirection, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 2))
{
if (hit.collider.CompareTag("Floor"))
{
targetPosition += movingDirection;
}
}
}
// Moving to targetPosition
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
}
(Note: cells of the floor must be marked with the tag "Floor" and added to them some kind of collider (you can use one collider for all cells at once))
Thanks really. This is exactly what I want I think. I'm gonna try implement this
Your answer
Follow this Question
Related Questions
Having trouble with grid movement 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
3D Grid Movement 1 Answer
Making a bubble level (not a game but work tool) 1 Answer
Grid-based movement with auto-move 1 Answer