- Home /
movement 2d in a grid
hey
I have a Question about 2D Movement. I can controll my player just fine and everything, but I want my Player to move in a kind of grid. So if i would put a grid as Backgound (just to make it clear) taht he would always stand in one of the squares after the movement. This is also seen in games like pokemon for example (the old ones).
Here is what I have so far:
if (Input.GetKey (KeyCode.D)) {
toRight = true;
toLeft = false;
toUp = false;
toDown = false;
walk = true;
transform.position = new Vector3
(transform.position.x + walkDistance,
transform.position.y,
transform.position.z);
}
(This might not be the best way to go, but i am rather new to unity)
(also I am using c#)
The Booleans are just for the animation.
So to sum up my Question:
I know how to move the Player, but he should only move in a "grid".
I hope I made it clear
Hope someone will help
Tanks :)
Answer by robertbu · Jan 07, 2014 at 09:57 PM
While you didn't ask for it specifically, most folks looking for this type of script want the character to move over time rather than just appear at the new location. In working with grids, it is easiest if you use 1 unit squares and adjust other factors (like Camera.orthographicSize) for your game. Here is a simple, starter script using the ASDF keys for a grid-like movement on the XY plane:
#pragma strict
private var speed = 2.0;
private var pos : Vector3;
private var tr : Transform;
function Start() {
pos = transform.position;
tr = transform;
}
function Update() {
if (Input.GetKeyDown(KeyCode.D) && tr.position == pos) {
pos += Vector3.right;
}
else if (Input.GetKeyDown(KeyCode.A) && tr.position == pos) {
pos += Vector3.left;
}
else if (Input.GetKeyDown(KeyCode.W) && tr.position == pos) {
pos += Vector3.up;
}
else if (Input.GetKeyDown(KeyCode.S) && tr.position == pos) {
pos += Vector3.down;
}
transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * speed);
}
really cool.
now what about if I wanted to prevent the player from going outside my grid?
What would be the best way to implement this?
Raycasting sounds a bit overkill but checking the player's position against a series of coordiantes also sounds a bit crazy.
Any idea? Cheers
@OliveU$$anonymous$$ - Please open this as a new question rather than ask it as a 'solution' on an existing, excepted question. Thanks.
Answer by gianticristian · Feb 03, 2015 at 01:23 AM
Thanks robertbu, this work great! I change it to work in C#:
Vector3 pos; // For movement
float speed = 2.0f; // Speed of movement
void Start () {
pos = transform.position; // Take the initial position
}
void FixedUpdate () {
if(Input.GetKey(KeyCode.A) && transform.position == pos) { // Left
pos += Vector3.left;
}
if(Input.GetKey(KeyCode.D) && transform.position == pos) { // Right
pos += Vector3.right;
}
if(Input.GetKey(KeyCode.W) && transform.position == pos) { // Up
pos += Vector3.up;
}
if(Input.GetKey(KeyCode.S) && transform.position == pos) { // Down
pos += Vector3.down;
}
transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * speed); // Move there
}
In this tutorial he uses FixedUpdate ins$$anonymous$$d of normal Update, and he mentions that you don't need to use deltaTime to move the object. Is this just a different way to skin the cat or is there a specific use case between using deltaTime and rigidbody2D.velocity?
Is there a way for this code to define the distance moved so that it fits to the grid tile? I'm trying to get something to move 0.7.
Answer by HDmodsXD3000 · Jul 17, 2017 at 10:40 PM
BlockySteve
Grid movement with RayCast2D collision. Do not attach a collider2D to your player,only on your object dat you want to collide on.
Vector3 pos;
public float speed = 2.0f;
void Start()
{
pos = transform.position; // Take the current position
}
void FixedUpdate()
{
//====RayCasts====//
RaycastHit2D hitup = Physics2D.Raycast(transform.position, Vector2.up, 16);
RaycastHit2D hitdown = Physics2D.Raycast(transform.position, Vector2.down, 16);
RaycastHit2D hitright = Physics2D.Raycast(transform.position, Vector2.right, 16);
RaycastHit2D hitleft = Physics2D.Raycast(transform.position, Vector2.left, 16);
//==Inputs==//
if (Input.GetKey(KeyCode.A) && transform.position == pos && hitleft.collider == null)
{ //(-1,0)
pos += Vector3.left * 16;// Add -1 to pos.x
}
if (Input.GetKey(KeyCode.D) && transform.position == pos && hitright.collider == null)
{ //(1,0)
pos += Vector3.right * 16;// Add 1 to pos.x
}
if (Input.GetKey(KeyCode.W) && transform.position == pos && hitup.collider == null)
{ //(0,1)
pos += Vector3.up * 16; // Add 1 to pos.y
}
if (Input.GetKey(KeyCode.S) && transform.position == pos && hitdown.collider == null)
{ //(0,-1)
pos += Vector3.down * 16;// Add -1 to pos.y
}
//The Current Position = Move To (the current position to the new position by the speed * Time.DeltaTime)
transform.position = Vector3.MoveTowards(transform.position, pos, speed); // Move there
}
}
I know this is old, but wouldn't you want to do the raycast only when you press a direction key and want to move that way? Testing every direction every frame seems like overkill. Also, I think you could have a player collider still and on your hit test you can just test if hit != gameobject.tag="Player" or some such.
I was thinking the same thing. Push W key, check for collision, then do the move. I wonder if you could also use this to check whether or not you're "facing" an NPC or chest or whatever such that you could press a button to talk or open or something like that?
I mean... I wouldn't know how to DO any of that...
Your're right. I was 12 when i wrote this code so i did not have to much experience at it. Sorry for the super late response. I will edit the code later.
Your answer
Follow this Question
Related Questions
Making a bubble level (not a game but work tool) 1 Answer
Distribute terrain in zones 3 Answers
Extend simple movement script (C#) 1 Answer
Player movement issue... 1 Answer
3d grid of game objects - C# errors 1 Answer