- Home /
Why the player is keep moving sometimes out of the grid area ?
I have a grid in this case size 10x10 I did that when i'm starting the game the player will be randomly position on one of the 4 walls on random block(Cube).
Then the player is start moving on the grid. I added spaces between the blocks(Cubes) the space is 1.5 between each cube. The player should move each time in distance of 1.5 so he will move from cube to cube.
The player will move to randomly direction each time. I'm checking first what directions the player can move and then select one random direction facing the player to this direction and make him move.
The problem is that the player in many times is leaving the grid area. I tried so many things but i can't force him to stay inside the grid area.
The problem happen on all directions: Left Right Forward Backward that sometimes the player is moving out of the grid area.
The first script is the script that create the grid:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GridGenerator : MonoBehaviour
{
public GameObject gridBlock;
public int gridWidth = 10;
public int gridHeight = 10;
public float spaceBetweenBlocks = 1.5f;
public Vector3 blocksScale = new Vector3(1, 0.01f, 1);
public Color blocksColor;
private GameObject[] wallsParents = new GameObject[4];
public GameObject[] allBlocks;
void Start()
{
wallsParents[0] = GameObject.Find("Top Wall");
wallsParents[1] = GameObject.Find("Left Wall");
wallsParents[2] = GameObject.Find("Right Wall");
wallsParents[3] = GameObject.Find("Bottom Wall");
GenerateGrid();
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
var findpath = GetComponent<PathFinder>();
findpath.FindPath();
}
public void AutoGenerateGrid()
{
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
for (int i = 0; i < allBlocks.Length; i++)
{
DestroyImmediate(allBlocks[i]);
}
var end = GameObject.FindGameObjectWithTag("End");
DestroyImmediate(end);
GenerateGrid();
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
var findpath = GetComponent<PathFinder>();
findpath.FindPath();
}
public void GenerateGrid()
{
for (int x = 0; x < gridWidth; x++)
{
for (int z = 0; z < gridHeight; z++)
{
GameObject block = Instantiate(gridBlock, Vector3.zero, gridBlock.transform.rotation) as GameObject;
block.transform.parent = transform;
block.transform.name = "Block";
block.transform.tag = "Blocks";
block.transform.localPosition = new Vector3(x * spaceBetweenBlocks, 0, z * spaceBetweenBlocks);
block.transform.localScale = blocksScale;
block.GetComponent<Renderer>().material.color = blocksColor;
if (x == 0)//TOP
{
block.transform.parent = wallsParents[0].transform;
block.transform.name = "TopWall";
block.transform.tag = "Blocks";
}
else if (z == 0)//LEFT
{
block.transform.parent = wallsParents[1].transform;
block.transform.name = "LeftWall";
block.transform.tag = "Blocks";
}
else if (z == gridHeight - 1)//RIGHT
{
block.transform.parent = wallsParents[2].transform;
block.transform.name = "RightWall";
block.transform.tag = "Blocks";
}
else if (x == gridWidth - 1)//BOTTOM
{
block.transform.parent = wallsParents[3].transform;
block.transform.name = "BottomWall";
block.transform.tag = "Blocks";
}
}
}
}
}
The second grid is Path Finder that move the player around the grid randomly but from block to block not just randomly around.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.IO;
public class PathFinder : MonoBehaviour
{
public Transform player;
public float playerMoveSpeed = 1f;
public float playerRotationSpeed = 0.5f;
public float distanceToTravel = 1.5f;
public bool randomPath = true;
public List<Vector3> possibleDirections = new List<Vector3>();
public Vector3 selectedDirection;
private Transform start;
private Transform end;
private GridGenerator gridgenerator;
private float m_distanceTraveled = 0f;
private List<Vector3> visitedList = new List<Vector3>();
private List<Vector3> toBeVisitedList = new List<Vector3>();
private Vector3 playerPosition;
private const float margin = 0.001f;
public void FindPath()
{
gridgenerator = GetComponent<GridGenerator>();
GenerateStartEnd();
FindDirections();
m_distanceTraveled = 0;
}
private void FindDirections()
{
possibleDirections = new List<Vector3>();
playerPosition = player.localPosition;
m_distanceTraveled = 0;
if (playerPosition.x > 0)
{
// can go left
possibleDirections.Add(Vector3.left);
}
if (playerPosition.x + gridgenerator.spaceBetweenBlocks < gridgenerator.gridWidth * gridgenerator.spaceBetweenBlocks)
{
// can go right
possibleDirections.Add(Vector3.right);
}
if (playerPosition.z > 0)
{
// can go backward
possibleDirections.Add(Vector3.back);
}
if (playerPosition.z + gridgenerator.spaceBetweenBlocks < gridgenerator.gridHeight * gridgenerator.spaceBetweenBlocks)
{
// can go forward
possibleDirections.Add(Vector3.forward);
}
if (randomPath == true)
{
selectedDirection = possibleDirections[Random.Range(0, possibleDirections.Count)];
}
player.forward = selectedDirection;
}
private void Update()
{
if (m_distanceTraveled < distanceToTravel)
{
Vector3 oldPosition = player.localPosition;
player.localPosition += selectedDirection * Time.deltaTime * playerMoveSpeed;
m_distanceTraveled += Vector3.Distance(oldPosition, player.localPosition);
}
if (m_distanceTraveled > distanceToTravel)
{
FindDirections();
}
}
private List<Vector3> GenerateStartEnd()
{
GameObject walls = GameObject.Find("Walls");
List<Transform> wallsParents = new List<Transform>();
List<Vector3> startEndPos = new List<Vector3>();
foreach (Transform child in walls.transform)
{
wallsParents.Add(child);
}
for (int i = 0; i < 2; i++)
{
wallsParents.Remove(wallsParents[Random.Range(0, wallsParents.Count)]);
}
var childsWall0 = wallsParents[0].GetComponentsInChildren<Transform>().ToList();
var childsWall1 = wallsParents[1].GetComponentsInChildren<Transform>().ToList();
childsWall0.RemoveAt(0);
childsWall1.RemoveAt(0);
start = childsWall0[Random.Range(0, childsWall0.Count)];
player.position = start.position;
end = childsWall1[Random.Range(0, childsWall1.Count)];
end.tag = "End";
startEndPos.Add(start.position);
startEndPos.Add(end.position);
start.GetComponent<Renderer>().material.color = Color.red;
end.GetComponent<Renderer>().material.color = Color.blue;
return startEndPos;
}
}
What i tried so far ? Changed this line:
if (playerPosition.x > 0)
To
if (playerPosition.x > 0.1f) or even to 1 or to 1.5f or to 2 Same changes i did on the line:
if (playerPosition.z > 0)
But it didn't fix the problem the player is keep moving in some times out of the grid area.
This line:
if (playerPosition.x + gridgenerator.spaceBetweenBlocks < gridgenerator.gridWidth * gridgenerator.spaceBetweenBlocks)
The spaceBetweenBlocks is 1.5
Maybe the problem is in the Update ? Here i'm moving the player according to the direction he is facing and then calling FindDirections again to get new random direction to move.
private void Update()
{
if (m_distanceTraveled < distanceToTravel)
{
Vector3 oldPosition = player.localPosition;
player.localPosition += selectedDirection * Time.deltaTime * playerMoveSpeed;
m_distanceTraveled += Vector3.Distance(oldPosition, player.localPosition);
}
if (m_distanceTraveled > distanceToTravel)
{
FindDirections();
}
}
I don't want to use raycast or rigidbody just using IF's states. But it's not working. Here is a small video i recorded that show the problem:
And this is a screenshot showing the player out of the grid area: You can see the player is on the left side out of the grid area.
Your answer
Follow this Question
Related Questions
How can I instantiate a prefab/s in all loaded scenes or in selected scenes from list ? 1 Answer
How do i use a public sealed class to create objects and destroy them ? 0 Answers
Help with deselection please 1 Answer
How can I make that the interactable raycast shoot will not pass through some objects like doors ? 1 Answer