Polan31
Polan31

Reputation: 11

Why my minimum distance in Unity not working?

UNITY 2D C#

I have a "Gear" object that spawns.

I have determined the minimum and max distance that can be between objects.

However, objects still spawn on other objects, covering (overlapping) them.

How to change it?

My script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GearsSpawner : MonoBehaviour
{

    public GameObject theGear;
    public Transform generationPoint;

    public float distanceBetween;
    public float distanceBetweenMin;
    public float distanceBetweenMax;

    private int gearSelector;
    public GameObject[] theGears;

    private float minWidth;
    public Transform maxWidthPoint;

    private float maxWidth;
    public float maxWidthChange;
    private float widthChange;

    void Start()
    {
        minWidth = transform.position.x;
        maxWidth = maxWidthPoint.position.x;
    }


    void Update()
    {
        if (transform.position.y < generationPoint.position.y)
        {
            distanceBetween = Random.Range(distanceBetweenMin, distanceBetweenMax);
            gearSelector = Random.Range(0, theGears.Length);
            widthChange = transform.position.x + Random.Range(maxWidthChange, -maxWidthChange);
            if (widthChange > maxWidth)
            {
                widthChange = maxWidth;
            }
            else if (widthChange < minWidth)
            {
                widthChange = minWidth;
            }
            transform.position = new Vector3(widthChange, transform.position.y + distanceBetween, transform.position.z);
            Instantiate(theGears[gearSelector], transform.position, transform.rotation);
        }
    }
}

enter image description here

Upvotes: 0

Views: 464

Answers (4)

Polan31
Polan31

Reputation: 11

Solved

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GearsSpawner : MonoBehaviour {


public GameObject theGear;
public Transform generationPoint;
public float distanceBetween;

public float distanceBetweenMin;
public float distanceBetweenMax;

private int gearSelector;

public GameObject[] theGears;

private float minWidth;
public Transform maxWidthPoint;
private float maxWidth;
public float maxWidthChange;

private float widthChange;

void Start (){

    minWidth = transform.position.x;
    maxWidth = maxWidthPoint.position.x;
}



public void Update (){

    if (transform.position.y < generationPoint.position.y)
    {
        distanceBetween = Random.Range (distanceBetweenMin, distanceBetweenMax) + 0.5f;

        gearSelector = Random.Range (0, theGears.Length);

        widthChange = transform.position.x + Random.Range (maxWidthChange, -maxWidthChange);

        if (widthChange > maxWidth) {
            widthChange = maxWidth;
        } else if (widthChange < minWidth)
        {
            widthChange = minWidth;
        }

        transform.position = new Vector3 (widthChange , transform.position.y + distanceBetween, transform.position.z);

        Instantiate (theGears[gearSelector], transform.position, transform.rotation);
    }

} }

Upvotes: 0

Grant Shotwell
Grant Shotwell

Reputation: 339

Hopefully I understand your code right: you're trying to create a chain of gears from bottom to top by moving a random amount upwards, then a random amount left/right. If that's correct, then you might be overthinking it.

Rect boundaries;

void Start()
{
    boundaries = new Rect(
        transform.position, //corner 1
        maxWidthPoint.position - transform.position //size: corner 2 - corner 1
    );
}

void Update()
{
    if (transform.position.y < generationPoint.position.y)
    {
        float deltaY = Random.Range(distanceBetweenMin, distanceBetweenMax);
        float deltaX = Random.Range(minWidthChange, maxWidthChange);
        transform.position += new Vector3(deltaX, deltaY, 0);

        if(transform.position.y < boundaries.yMin)
            transform.position.y = boundaries.yMin
        if(transform.position.y > boundaries.yMax)
            transform.position.y = boundaries.yMax

        if(transform.position.x < boundaries.xMin)
            transform.position.x = boundaries.xMin
        if(transform.position.x > boundaries.xMax)
            transform.position.x = boundaries.xMax

        int index = Random.Range(0, theGears.Length);
        Instantiate(theGears[index], transform.position, transform.rotation);
    }
}

Upvotes: 0

Thomas Hilbert
Thomas Hilbert

Reputation: 3629

Well I'm not sure if I totally understand what your code is supposed to do. However there are a few spots that look fishy and I have changed them according to my understanding of its intended purpose (marked with FIX):

void Update()
{
    if (transform.position.y < generationPoint.position.y)
    {
        distanceBetween = Random.Range(distanceBetweenMin, distanceBetweenMax);
        gearSelector = Random.Range(0, theGears.Length);
        widthChange = transform.position.x + Random.Range(-maxWidthChange, maxWidthChange); // FIX: the first argument of Random.Range must be the lower limit, the second one that upper limit
        if (widthChange > maxWidth)
        {
            widthChange = maxWidth;
        }
        else if (widthChange < minWidth)
        {
            widthChange = minWidth;
        }
        Vector3 newPosition = new Vector3(widthChange, transform.position.y + distanceBetween, transform.position.z); // FIX: instead of overwriting the spawner's position, store the newPosition in a local and use that
        Instantiate(theGears[gearSelector], newPosition, transform.rotation);
    }
}

Upvotes: 0

Technivorous
Technivorous

Reputation: 1712

im guessing your objects are not exactly one unit in size, check the scale of the objects in question and adjust you minimum distance accordingly

Upvotes: 1

Related Questions