简体   繁体   English

球体重叠,甚至在我检查碰撞的情况下

[英]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 所以问题是我们没有在检查的球体上禁用对撞机: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). 这里的问题是您的starSize既用于局部比例(多因子)又用于球体碰撞器(平坦因子)。 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. 例如:您的星星的默认大小为2,而您的starSize等于2,那么您的球体的实际半径为4,但是对撞机检查的2 * 0.5 + 2 = 3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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