Random.Range isn't returning whole numbers
I'm attempting to make a simple simulation of grass growing, but for the life of me I cannot get it to work! My latest problem is that I cannot get the grass to spawn in a random location relative to the spawned parent in a whole number. So it will spawn a tuft (cube, really) of grass near the parent, but I want it to be within a whole number's distance away e.g. 1,2,3 instead of 1.1, 1.2, 1.3 Here's the code:
using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random;
public class GrassScript : MonoBehaviour { public GameObject Grass; public GameObject GrassCore; public Transform GrassPosition;
// Update is called once per frame
void Update () {
if (Input.GetKeyDown("d"))
{
GameObject GrassPrefab = Instantiate(Grass) as GameObject;
GrassPrefab.name = "Grass";
GrassPrefab.transform.position = new Vector3(Random.Range((GrassPosition.position.x)-2, (GrassPosition.position.x)+3), GrassPosition.position.y, Random.Range((GrassPosition.position.z) - 2, (GrassPosition.position.z) + 3));
}
}
}
Answer by Hellium · Oct 23, 2018 at 05:28 PM
Random.Range does not return a whole number if you don't provide integers. Thus, you will have to provide the function to get an integer from the floating position. Either round, floor or ceil the values:
Vector3 position = GrassPosition.position ;
position.x = Random.Range(
Mathf.CeilToInt(GrassPosition.position.x) - 2, // You can also use Mathf.RoundToInt or another function
Mathf.FloorToInt(GrassPosition.position.x) + 3
) ;
position.z = Random.Range(
Mathf.CeilToInt(GrassPosition.position.z) - 2,
Mathf.FloorToInt(GrassPosition.position.z) + 3)
) ;
GrassPrefab.transform.position = position ;
Having another unforseen issue though: Now the grass spawns awesomely (again, thanks!) but I want it to run a check to see if grass is already at those coordinates and if it is, to delete the grass already there and replace it, so that there is only ever one 'tuft' in any given location. I'm thinking to use some kind of boolean checker, but I don't really know since I'm so new to this.
I haven't tested the following code, but you can give a try:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrassScript : $$anonymous$$onoBehaviour
{
public GameObject Grass;
public GameObject GrassCore;
public Transform GrassPosition;
private List<GameObject> grassInstances;
void Start ()
{
grassInstances = new List<GameObject>(128);
}
void Update ()
{
if ( Input.Get$$anonymous$$eyDown("d") )
AddGrassInstance( InstantiateGrass() ) ;
}
private GameObject InstantiateGrass()
{
GameObject grassInstance = Instantiate(Grass) as GameObject;
grassInstance.name = "Grass";
Vector3 position = GrassPosition.position ;
position.x = Random.Range(
$$anonymous$$athf.CeilToInt( GrassPosition.position.x ) - 2,
$$anonymous$$athf.FloorToInt( GrassPosition.position.x ) + 3
) ;
position.z = Random.Range(
$$anonymous$$athf.CeilToInt( GrassPosition.position.z ) - 2,
$$anonymous$$athf.FloorToInt( GrassPosition.position.z ) + 3
) ;
grassInstance.transform.position = position ;
return grassInstance;
}
private void AddGrassInstance( GameObject grassInstance )
{
int grassIndex = GetGrassIndexAtPosition( grassInstance.transform.position ) ;
if( grassIndex >= 0 )
grassInstances[i] = grassInstance ;
else
grassInstances.Add( grassInstance );
}
private int GetGrassIndexAtPosition( Vector3 position )
{
int grassCount = grassInstances.Count;
for( int i = 0 ; i < grassCount ; ++i )
if( (grassInstances[i].transform.position - position ).sqrDistance < 0.2f )
return i ;
return -1 ;
}
}
Your answer