I have two problems.
First I’m cloning objects inside the terrain area only. The problem is when i change the objects size for example to 50 some of them if they are near the terrain edge half of them inside the terrain half outside. And i want to make sure that all the objects in this case cubes will be inside the terrain area. How can i fix it ?
Second problem, How can i make a new variable to set the minimum space between each cubes ? Since i spawn them in random position the space between them is also random but i want to be able to change and set the minimum space that should be between them. For example if the minimum space is 10 then the random space between the cubes should be 10 and above. Random of course since i spawn them in random positions but the spaces between each cubes should be minimum 10 or what ever i will set.
This is the script i’m using:
using System;
using UnityEngine;
using Random = UnityEngine.Random;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class CloneObjects : MonoBehaviour {
public GameObject objectToClone;
public int objectsStartingHeight = 20;
[HideInInspector]
public GameObject[] objects;
// for tracking properties change
private Vector3 _extents;
private int _objectCount;
private float _objectSize;
/// <summary>
/// How far to place spheres randomly.
/// </summary>
public Vector3 Extents;
/// <summary>
/// How many spheres wanted.
/// </summary>
public int ObjectCount;
public float ObjectSize;
// Use this for initialization
void Start () {
Clone();
objects = GameObject.FindGameObjectsWithTag("objectToClone");
}
private void OnValidate()
{
// prevent wrong values to be entered
Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
ObjectCount = Mathf.Max(0, ObjectCount);
ObjectSize = Mathf.Max(0.0f, ObjectSize);
}
private void Reset()
{
Extents = new Vector3(250.0f, 20.0f, 250.0f);
ObjectCount = 100;
ObjectSize = 20.0f;
}
// Update is called once per frame
void Update () {
}
private void Clone()
{
if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
return;
// cleanup
var ObjectToDestroy = GameObject.FindGameObjectsWithTag("ClonedObject");
foreach (var t in ObjectToDestroy)
{
if (Application.isEditor)
{
DestroyImmediate(t);
}
else
{
Destroy(t);
}
}
var withTag = GameObject.FindWithTag("Terrain");
if (withTag == null)
throw new InvalidOperationException("Terrain not found");
for (var i = 0; i < ObjectCount; i++)
{
var o = Instantiate(objectToClone);
o.tag = "ClonedObject";
o.transform.SetParent(base.gameObject.transform);
o.transform.localScale = new Vector3(ObjectSize, ObjectSize, ObjectSize);
// get random position
var x = Random.Range(-Extents.x, Extents.x);
var y = Extents.y; // sphere altitude relative to terrain below
var z = Random.Range(-Extents.z, Extents.z);
// now send a ray down terrain to adjust Y according terrain below
var height = 10000.0f; // should be higher than highest terrain altitude
var origin = new Vector3(x, height, z);
var ray = new Ray(origin, Vector3.down);
RaycastHit hit;
var maxDistance = 20000.0f;
var nameToLayer = LayerMask.NameToLayer("Terrain");
var layerMask = 1 << nameToLayer;
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
{
var distance = hit.distance;
y = height - distance + y; // adjust
}
else
{
Debug.LogWarning("Terrain not hit, using default height !");
}
//o.transform.Rotate(0.0f,randomNumbers*,0.0f);*
// place !
-
o.transform.position = new Vector3(x, y+objectsStartingHeight, z);*
}
_extents = Extents;
_objectCount = ObjectCount;
_objectSize = ObjectSize;
}
}
And this is when i set the size to 50 in some places the cubes half in half out the terrain:
[90923-ss94.jpg|90923]*
And this is a screenshot show the script settings in the inspector: Y is set to 0.5 and creating 10 objects and the size of each object is 50. All the objects have the same size.
[90924-ss95.jpg|90924]*
*
*
And last the terrain position is X = -250 Y = 0 and Z = -250
The terrain size is Width = 500 Length = 500 Height = 600