I’m using a 2d array grid for my level with each grid assigned a value of either 0 (walkable grid) or 1 (unwalkable grid/wall). Every time an input button is pressed, it initiates a continuous movement in that respective direction, until it is supposed to turn to its’ right. This is pretty reminescent of Snake or Pacman.
I have managed to get the gist of the movement to work, however it is not optimized. The straight direction that it moves in, happens very fast. The object stops when it comes against an unwalkable grid instead of turning. Only when the input key is pressed then, that it detects the unwalkable grid and takes a turn.
If possible, it would be great if someone could take a look at my project [33238-gridmovement.zip|33238]
or if you wish to check my code, here it is
using UnityEngine;
using System.Collections;
using DG.Tweening;
using System.Collections.Generic;
public class Player : MonoBehaviour {
const float TweenWpDuration = 0.2f;
public GameObject levelCreator_;
levelCreator temp;
Vector3 playerPos;
int[,] mapArray = new int[13,17];
public bool inhibitPlayerInput;
void Start () {
DOTween.Init(true, true, LogBehaviour.Verbose).SetCapacity(6000, 6000);
levelCreator_ = GameObject.Find ("LevelCreatorGameObject");
temp = levelCreator_.gameObject.GetComponent<levelCreator>();
mapArray = temp.mapArray;
for(int i = 1; i<12; i++)
{
for(int ii = 1; ii < 16; ii++)
{
if( mapArray[i,ii] == 2)
{
playerPos = new Vector3(i,ii,0);
}
}
}
Debug.Log (GhostManager.ghostTweens.Count);
transform.position = new Vector3(playerPos.x,playerPos.y,0);
}
void Update () {
if (inhibitPlayerInput) return;
getInput();
}
void getInput()
{
bool inputPressed = false;
if(Input.GetKey(KeyCode.W) && inhibitPlayerInput == false)
{
inputPressed = true;
walkup();
}
else if (Input.GetKey(KeyCode.S))
{
inputPressed = true;
walkdown();
}
else if(Input.GetKey(KeyCode.A))
{
inputPressed = true;
walkleft();
}
else if(Input.GetKey(KeyCode.D))
{
inputPressed = true;
walkright();
}
}
void walkup ()
{
Vector3 newPlayerPos = playerPos;
newPlayerPos += new Vector3(-1,0,0);
if (mapArray[(int)newPlayerPos.x,(int)newPlayerPos.y] == 1)
{
if (mapArray[(int)playerPos.x,(int)playerPos.y + 1] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y + 1] >= 2)
walkright();
else
walkleft();
return;
}
playerPos = newPlayerPos;
if(mapArray[(int)playerPos.x,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y] >= 2)
{
inhibitPlayerInput = true;
transform.DOMove(playerPos, TweenWpDuration).OnComplete(() => inhibitPlayerInput = false).SetEase(Ease.Linear);
}
if (mapArray[(int)playerPos.x - 1,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x - 1,(int)playerPos.y] >= 2)
{
playerPos = newPlayerPos;
walkup();
}
return;
}
void walkright ()
{
Vector3 newPlayerPos = playerPos;
newPlayerPos += new Vector3(0,1,0);
if (mapArray[(int)newPlayerPos.x,(int)newPlayerPos.y] == 1)
{
if (mapArray[(int)playerPos.x + 1,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x + 1,(int)playerPos.y] >= 2)
walkdown();
else
walkup();
return;
}
playerPos = newPlayerPos;
if(mapArray[(int)playerPos.x,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y] >= 2)
{
inhibitPlayerInput = true;
transform.DOMove(playerPos, TweenWpDuration).OnComplete(() => inhibitPlayerInput = false).SetEase(Ease.Linear);
}
if (mapArray[(int)playerPos.x,(int)playerPos.y + 1] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y + 1] >= 2)
{
playerPos = newPlayerPos;
walkright();
}
return;
}
void walkleft ()
{
Vector3 newPlayerPos = playerPos;
newPlayerPos += new Vector3(0,-1,0);
if (mapArray[(int)newPlayerPos.x,(int)newPlayerPos.y] == 1)
{
if (mapArray[(int)playerPos.x + 1,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x + 1,(int)playerPos.y] >= 2)
walkdown();
else
walkup();
return;
}
playerPos = newPlayerPos;
if(mapArray[(int)playerPos.x,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y] >= 2)
{
inhibitPlayerInput = true;
transform.DOMove(playerPos, TweenWpDuration).OnComplete(() => inhibitPlayerInput = false).SetEase(Ease.Linear);
}
if (mapArray[(int)playerPos.x,(int)playerPos.y - 1] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y - 1] >= 2)
{
playerPos = newPlayerPos;
walkleft();
}
return;
}
void walkdown ()
{
Vector3 newPlayerPos = playerPos;
newPlayerPos += new Vector3(1,0,0);
if (mapArray[(int)newPlayerPos.x,(int)newPlayerPos.y] == 1)
{
if (mapArray[(int)playerPos.x,(int)playerPos.y + 1] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y + 1] >= 2)
walkright();
else
walkleft();
return;
}
playerPos = newPlayerPos;
if(mapArray[(int)playerPos.x,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x,(int)playerPos.y] >= 2)
{
inhibitPlayerInput = true;
transform.DOMove(playerPos, TweenWpDuration).OnComplete(() => inhibitPlayerInput = false).SetEase(Ease.Linear);
}
if (mapArray[(int)playerPos.x + 1,(int)playerPos.y] == 0 || mapArray[(int)playerPos.x + 1,(int)playerPos.y] >= 2)
{
playerPos = newPlayerPos;
walkdown();
}
return;
}
}
A hint for your code: replace walkup/down/right/left with a walk-method, that takes a Vector3, and use that Vector3 to give directions. Now you have four methods that are identical with the exception of some coordinates. That means that whenever you want to change your walk-methods, you have to change all of them, and make sure that you change exactly the same thing every time. I can guarantee that you will mess up doing that, trust me. If you do that and repost your code, it will be much easier for us (and you) to find the problems.
– BasteDRY code is worth aiming for. Could certainly reduce this long post to a short one.
– Kiwasi