'How to generate a random path between two start and end positions?
This create a grid of cubes with start and end cubes.
Then when calling the GeneratePath method it's coloring the closet cube to the start in green. The problem is that it's never continue to the end cube.
The goal is that it will generate a path randomly from start to end.
tried to add a while(true) in the GeneratePath method and then checking if closet is the end position cube then break but what it does is just taking memory and freeze the whole editor then i have to shut it the editor.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class GenerateGrid : MonoBehaviour
{
public GameObject gridPrefab;
public GameObject pathPrefab;
public List<Text> texts = new List<Text>();
private Transform[,] gridBlocks;
private List<List<Transform>> gridLists = new List<List<Transform>>();
private List<Vector3> gridBlocksPositions = new List<Vector3>();
private List<Vector3> gridOuterBlocks = new List<Vector3>();
private Transform startBlockPOs;
private Transform endBlockPos;
public int gridWidth = 10;
public int gridHeight = 10;
public int gap;
public float spawnSpeed = 0;
public bool gridGenerated = false;
private bool createPath = false;
private List<Transform> visited = new List<Transform>();
private List<Transform> notvisited = new List<Transform>();
Transform next;
void Start()
{
StartCoroutine(CreateGrid());
}
IEnumerator CreateGrid()
{
gridBlocks = new Transform[gridWidth, gridHeight];
for (int x = 0; x < gridWidth; x++)
{
yield return new WaitForSeconds(spawnSpeed);
for (int z = 0; z < gridHeight; z++)
{
yield return new WaitForSeconds(spawnSpeed);
GameObject block = Instantiate(gridPrefab, Vector3.zero, gridPrefab.transform.rotation) as GameObject;
block.transform.parent = transform;
block.transform.localPosition = new Vector3(x + x * gap, 0, z + z * gap);
block.tag = "Grid Block";
texts.Add(block.GetComponentInChildren<Text>());
gridBlocks[x, z] = block.transform;
gridBlocksPositions.Add(block.transform.position);
if ((x == 0) || (x == gridWidth - 1) || (z == 0) || (z == gridHeight - 1))
{
gridOuterBlocks.Add(block.transform.position);
var cubeRenderer = block.GetComponent<Renderer>();
cubeRenderer.material.SetColor("_Color", Color.red);
}
}
}
if (UnityEngine.Random.Range(0, 2) == 0)
{
var blockRenderer = gridBlocks[0, UnityEngine.Random.Range(0, gridHeight)].GetComponent<Renderer>();
blockRenderer.material.SetColor("_Color", Color.blue);
startBlockPOs = blockRenderer.transform;
blockRenderer = gridBlocks[gridWidth - 1, UnityEngine.Random.Range(0, gridHeight)].GetComponent<Renderer>();
blockRenderer.material.SetColor("_Color", Color.blue);
endBlockPos = blockRenderer.transform;
createPath = true;
}
else
{
var blockRenderer = gridBlocks[UnityEngine.Random.Range(0, gridWidth), 0].GetComponent<Renderer>();
blockRenderer.material.SetColor("_Color", Color.blue);
startBlockPOs = blockRenderer.transform;
blockRenderer = gridBlocks[UnityEngine.Random.Range(0, gridWidth), gridHeight - 1].GetComponent<Renderer>();
blockRenderer.material.SetColor("_Color", Color.blue);
endBlockPos = blockRenderer.transform;
createPath = true;
}
gridGenerated = true;
GeneratePath();
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.G))
{
if (createPath)
{
var blocks = GameObject.FindGameObjectsWithTag("Grid Block");
foreach(GameObject block in blocks)
{
Destroy(block);
}
StartCoroutine(CreateGrid());
}
}
}
private void GeneratePath()
{
while (true)
{
var closest = GetClosest();
var rend = closest.GetComponent<Renderer>();
rend.material.SetColor("_Color", Color.green);
if(closest == endBlockPos)
{
break;
}
}
}
Transform closestTarget = null;
float startPosDistanceFromTarget = 0;
float endPosDistanceFromTarget = 0;
private Transform GetClosest()
{
float closestDistance = Mathf.Infinity;
for (int x = 0; x < gridWidth; x++)
{
for (int z = 0; z < gridHeight; z++)
{
var block = gridBlocks[x, z];
startPosDistanceFromTarget = Vector3.Distance(startBlockPOs.position, block.position);
endPosDistanceFromTarget = Vector3.Distance(endBlockPos.position, block.position);
if (startPosDistanceFromTarget < closestDistance &&
block.position != startBlockPOs.position &&
block.GetComponent<Renderer>().material.color != Color.red)
{
closestTarget = block;
visited.Add(block);
closestDistance = startPosDistanceFromTarget;
}
}
}
return closestTarget;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
