I have this script here that generates the map on startup:
using UnityEngine;
using UnityEngine.AI;
public class Map_Generator : MonoBehaviour
{
//EDIT VARIABLES
private Vector3 _centre = new Vector3(0, 0, 0);
private int _width = 1000;
private int _length = 1000;
private int _numberOfTrees = 7500;
private int _numberOfBushes = 10000;
private int _numberOfObstacles = 150;
private int _numberOfLockboxes = 50;
//VARIABLES
public bool _buildMap = true;
[SerializeField] private GameObject _entity;
[SerializeField] private GameObject _treePrefab;
[SerializeField] private GameObject _logPrefab;
[SerializeField] private GameObject _lockboxPrefab;
[SerializeField] private GameObject _bandagePrefab;
[SerializeField] private GameObject _bushPrefab;
private int _objectNumber = 0;
private bool _space;
private Vector3 _randomPosition;
private Collider[] _colliders;
[SerializeField] private GameObject _trees;
[SerializeField] private GameObject _bushes;
[SerializeField] private GameObject _obstacles;
[SerializeField] private GameObject _lockboxes;
//START
private void Start()
{
if (_buildMap)
{
_mapBuild(); //Build map
_buildMap = false;
}
}
//VOIDS AND COROUTINES
private void _mapBuild()
{
//Lockboxes
_objectNumber = 0;
while (_objectNumber < _numberOfLockboxes)
{
GameObject _object = Instantiate(_lockboxPrefab);
_object.transform.position = new Vector3(0, 0, 0);
_object.GetComponent<BoxCollider>().enabled = false;
_space = false;
while (!_space)
{
_space = true;
_randomPosition = _centre + new Vector3(Random.Range(-_width / 2, (_width / 2) + 1), 0, Random.Range(-_length / 2, (_length / 2) + 1));
_object.transform.position = _randomPosition;
_object.transform.eulerAngles = new Vector3(_object.transform.eulerAngles.x, Random.Range(0, 361), _object.transform.eulerAngles.z);
_colliders = Physics.OverlapBox(_randomPosition + new Vector3(0, 21, -0.2f), new Vector3(1, 25, 1), _object.transform.rotation);
foreach (Collider _collider in _colliders)
{
if (_collider.transform.tag == "Object" || _collider.transform.tag == "Map Edge")
{
_space = false;
}
}
}
while (Physics.CheckBox(_object.transform.position + new Vector3(0, 21, -0.2f), new Vector3(1, 25, 1), _object.transform.rotation))
{
_object.transform.position += new Vector3(0, 0.1f, 0);
}
_object.transform.position += new Vector3(0, -1, 0);
_object.GetComponent<BoxCollider>().enabled = true;
_object.transform.SetParent(_lockboxes.transform);
_object.name = "Lockbox";
_objectNumber += 1;
if (Random.Range(1, 6) >= 3) //Item spawning
{
GameObject _item = Instantiate(_bandagePrefab);
_item.transform.position = _object.transform.position + _object.transform.TransformDirection(new Vector3(0, 0, -0.2f));
_item.transform.eulerAngles = new Vector3(_item.transform.eulerAngles.x, Random.Range(0, 361), _item.transform.eulerAngles.z);
_item.transform.SetParent(_object.transform);
_item.name = "Bandages";
}
}
//Obstacles
_objectNumber = 0;
while (_objectNumber < _numberOfObstacles)
{
GameObject _object = Instantiate(_logPrefab);
_object.transform.position = new Vector3(0, 0, 0);
_object.GetComponent<BoxCollider>().enabled = false;
_space = false;
while (!_space)
{
_space = true;
_randomPosition = _centre + new Vector3(Random.Range(-_width / 2, (_width / 2) + 1), 0, Random.Range(-_length / 2, (_length / 2) + 1));
_object.transform.position = _randomPosition;
_object.transform.eulerAngles = new Vector3(_object.transform.eulerAngles.x, Random.Range(0, 361), _object.transform.eulerAngles.z);
_colliders = Physics.OverlapBox(_randomPosition + new Vector3(0, 24, 0), new Vector3(1, 25, 7.75f), _object.transform.rotation);
foreach (Collider _collider in _colliders)
{
if (_collider.transform.tag == "Object" || _collider.transform.tag == "Map Edge")
{
_space = false;
}
}
}
while (Physics.CheckBox(_object.transform.position + new Vector3(0, 24, 0), new Vector3(1, 25, 7.75f), _object.transform.rotation))
{
_object.transform.position += new Vector3(0, 0.1f, 0);
}
_object.transform.position += new Vector3(0, -1, 0);
_object.GetComponent<BoxCollider>().enabled = true;
_object.transform.SetParent(_obstacles.transform);
_object.name = "Obstacle";
_objectNumber += 1;
}
//Trees
_objectNumber = 0;
while (_objectNumber < _numberOfTrees)
{
GameObject _object = Instantiate(_treePrefab);
_object.transform.position = new Vector3(0, 0, 0);
_object.GetComponent<CapsuleCollider>().enabled = false;
_space = false;
while (!_space)
{
_space = true;
_randomPosition = _centre + new Vector3(Random.Range(-_width / 2, (_width / 2) + 1), 0, Random.Range(-_length / 2, (_length / 2) + 1));
_object.transform.position = _randomPosition;
_object.transform.eulerAngles = new Vector3(_object.transform.eulerAngles.x, Random.Range(0, 361), _object.transform.eulerAngles.z);
_colliders = Physics.OverlapCapsule(_randomPosition, _randomPosition + new Vector3(0, 24.5f, 0), 0.6f);
foreach (Collider _collider in _colliders)
{
if (_collider.transform.tag == "Object" || _collider.transform.tag == "Map Edge")
{
_space = false;
}
}
}
while (Physics.CheckCapsule(_object.transform.position, _object.transform.position + new Vector3(0, 24.5f, 0), 0.6f))
{
_object.transform.position += new Vector3(0, 0.1f, 0);
}
_object.transform.position += new Vector3(0, -1, 0);
_object.GetComponent<CapsuleCollider>().enabled = true;
_object.transform.SetParent(_trees.transform);
_object.name = "Tree";
_objectNumber += 1;
}
//Bushes
_objectNumber = 0;
while (_objectNumber < _numberOfBushes)
{
GameObject _object = Instantiate(_bushPrefab);
_object.transform.position = new Vector3(0, 0, 0);
_space = false;
while (!_space)
{
_space = true;
_randomPosition = _centre + new Vector3(Random.Range(-_width / 2, (_width / 2) + 1), 0, Random.Range(-_length / 2, (_length / 2) + 1));
_object.transform.position = _randomPosition;
_object.transform.eulerAngles = new Vector3(_object.transform.eulerAngles.x, Random.Range(0, 361), _object.transform.eulerAngles.z);
_colliders = Physics.OverlapSphere(_randomPosition, 2);
foreach (Collider _collider in _colliders)
{
if (_collider.transform.tag == "Object" || _collider.transform.tag == "Map Edge")
{
_space = false;
}
}
}
while (Physics.CheckSphere(_object.transform.position, 2))
{
_object.transform.position += new Vector3(0, 0.1f, 0);
}
_object.transform.position += new Vector3(0, -1, 0);
_object.transform.SetParent(_bushes.transform);
_object.name = "Bush";
_objectNumber += 1;
}
//Entity
_entity.GetComponent<NavMeshAgent>().enabled = false;
_entity.transform.position = new Vector3(0, 0, 0);
_entity.GetComponent<CapsuleCollider>().enabled = false;
_space = false;
while (!_space)
{
_space = true;
_randomPosition = _centre + new Vector3(Random.Range(-_width / 2, (_width / 2) + 1), 0, Random.Range(-_length / 2, (_length / 2) + 1));
_entity.transform.position = _randomPosition;
_entity.transform.eulerAngles = new Vector3(_entity.transform.eulerAngles.x, Random.Range(0, 361), _entity.transform.eulerAngles.z);
_colliders = Physics.OverlapCapsule(_randomPosition + new Vector3(0, -5, 0), _randomPosition + new Vector3(0, 5, 0), 2.5f);
foreach (Collider _collider in _colliders)
{
if (_collider.transform.tag == "Object" || _collider.transform.tag == "Map Edge")
{
_space = false;
}
}
if (_randomPosition.sqrMagnitude < 40000)
{
_space = false;
}
}
while (Physics.CheckCapsule(_entity.transform.position + new Vector3(0, -5, 0), _entity.transform.position + new Vector3(0, 5, 0), 2.5f))
{
_entity.transform.position += new Vector3(0, 0.1f, 0);
}
_entity.GetComponent<CapsuleCollider>().enabled = true;
_entity.GetComponent<NavMeshAgent>().enabled = true;
}
}
this works fine, and everything looks fine, and i didnt notice anything wrong until the “entity” object (which has a navmesh agent) started saying it wasnt properly placed on a navmesh. i took a further look, and it was randomly floating way above the map. this happens with all generated items, as shows in the video:
note that this only happens to some of the items randomly, and the item type is random as the entity is not always placed in the sky, only sometimes.
i have no idea why it is doing this, though i suspect it is to do with this snippet:
//For all the item types, not just the entity
while (Physics.CheckCapsule(_entity.transform.position + new Vector3(0, -5, 0), _entity.transform.position + new Vector3(0, 5, 0), 2.5f))
{
_entity.transform.position += new Vector3(0, 0.1f, 0);
}
which repeatedly moves the object up until it is not inside a collider (the terrain collider)
i really need to get this answer as quickly as possible, so id really appreciate any help
thankyou in advance ![]()