简体   繁体   中英

Sphere are overlapping even tho I check for collisions

I am using this code to generate a number of sphere around a center point, with different size and position.

There is a conditional check to prevent sphere from overlapping.

The problem I face is, in the scene some sphere are always overlapping.

=>

[Header("Galaxy")]
public int numberOfStars = 300;
public int maximumRadius = 100;
public float minDistBetweenStars = 2f;
[Header("Star")]
public float minimumSize = 1f;
public float maximumSize = 2f;

void Start()
{
    for(int i = 0; i < numberOfStars; i++)
    {
        float distance = Random.Range(0, maximumRadius);
        float angle = Random.Range(0, 2 * Mathf.PI);

        float starSize = Random.Range(minimumSize, maximumSize);
        Vector3 starPosition = new Vector3(distance * Mathf.Cos(angle), 0, distance * Mathf.Sin(angle));

        Collider[] starCollider = Physics.OverlapSphere(starPosition, (starSize * 0.5f) + minDistBetweenStars);
        if (starCollider.Length == 0)
        {
            GameObject star = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            star.transform.position = starPosition;
            star.transform.localScale = new Vector3(starSize, starSize, starSize);
        }
        else
        {
            i--;
        }
    }
}

I do pass in the remove, so some sphere are being removed,m but I still see a lot of overlapping.

So the problem was we were not disabling the collider on the sphere we was checking :P

public class StarGenSO : MonoBehaviour
{
    [Header("Galaxy")]
    public int numberOfStars = 300;
    public int maximumRadius = 100;
    public float minDistBetweenStars = 2f;
    [Header("Star")]
    public float minimumSize = 1f;
    public float maximumSize = 2f;

    void Awake()
    {
        for (int i = 0; i < numberOfStars; i++)
        {
            GameObject star = GameObject.CreatePrimitive(PrimitiveType.Sphere);

            float distance = Random.Range(0, maximumRadius);
            float angle = Random.Range(0, 2 * Mathf.PI);

            float starSize = Random.Range(minimumSize, maximumSize);
            Vector3 starPosition = new Vector3(distance * Mathf.Cos(angle), 0, distance * Mathf.Sin(angle));

            var currentCol = star.GetComponent<Collider>();
            currentCol.enabled = false;

            Collider[] starCollider = Physics.OverlapSphere(starPosition, (starSize * 0.5f) + minDistBetweenStars);
            if (starCollider.Length == 0)
            {
                star.transform.position = starPosition;
                star.transform.localScale = new Vector3(starSize, starSize, starSize);
                currentCol.enabled = true;
            }
            else
            {
                Debug.Log("remove");
                Destroy(star);
                i--;
            }
        }
    }
}

A preferred solution

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

public class StarGenSo : MonoBehaviour
{
    [Header("Galaxy")]
    public int numberOfStars = 300;
    public int maximumRadius = 100;
    public float minDistBetweenStars = 2f;
    [Header("Star")]
    public float minimumSize = 1f;
    public float maximumSize = 2f;
    [Header("Star Object")]
    public GameObject obj;

    IEnumerator Start()
    {
        for (int i = 0; i < numberOfStars; i++)
        {
            float distance = Random.Range(0, maximumRadius);
            float angle = Random.Range(0, 2 * Mathf.PI);

            float starSize = Random.Range(minimumSize, maximumSize);
            Vector3 starPosition = new Vector3(distance * Mathf.Cos(angle), 0, distance * Mathf.Sin(angle));

            Collider[] starCollider = Physics.OverlapSphere(starPosition, (starSize * 0.5f) + minDistBetweenStars);
            if (starCollider.Length == 0)
            {
                GameObject star = Instantiate(obj);
                star.transform.position = starPosition;
                star.transform.localScale = new Vector3(starSize, starSize, starSize);
                star.AddComponent<SphereCollider>();
            }
            else
            {
                i--;
            }
        }
        yield return null;
    }
}

Result: 在此处输入图片说明

The problem here is your starSize use both for local scale (multiple factor) and sphere collider (flat factor). Eg: your star have default size of 2 and your starSize equal 2, then your actual radius of your sphere is 4, but your collider check for 2*0.5 + 2 = 3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM