Autor Beitrag
Garzec
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29



BeitragVerfasst: Mi 07.12.16 14:23 
Hallo,
in Unity habe ich einen Planeten(Kugel) mit Gravitation. Durch eine Spawnroutine werden Objekte um die Kugel erstellt und durch die Gravitation an den Planeten gezogen.

Nun möchte ich vor dem Spawnen prüfen, ob dort ein Objekt platziert werden kann, ohne das es dann beim Fallen auf die Kugel auf einem anderen Objekt landen würde.

In Kurzform: Prüfung, ob ein neu gespawntes Objekt an der Position x,y,z mit einer "Größe" nicht auf einem bereits auf der Kugeloberfläche befindlichen Objekt fallen würde.

An den Planetenmittelpunkt, den Radius, die Positionen der Objekte und die Größen der Objekte würde ich rankommen, mir fehlt leider der mathematische Teil. Ich habe mal begonnen:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
public class WorldGenerator : MonoBehaviour
{
    CalcCoordinates calculator; // Hilfsklasse

    GameObject planet; // Der Planet
    public GameObject[] planetPrefabs; // Objekte auf dem Planeten
    public GameObject[] skyPrefabs; // Objekte in der Luft
    public GameObject[] spacePrefabs; // Objekte im All

    void Start()
    {
        calculator = GameObject.FindGameObjectWithTag("Calculator").GetComponent<CalcCoordinates>();
        planet = GameObject.FindGameObjectWithTag("Planet");

        SpawnObjects(planet, planetPrefabs, PlayerPrefs.GetInt("planetObjectsCount"), 50); // SpawnRoutine
        SpawnObjects(planet, skyPrefabs, PlayerPrefs.GetInt("skyObjectsCount"), 150);
        SpawnObjects(planet, spacePrefabs, PlayerPrefs.GetInt("spaceObjectsCount"), 200);
    }

    private void SpawnObjects(GameObject planet, GameObject[] prefabs, float objectCount, float distanceToPlanet)
    {
        List<gameObject> spawnObjectsList = new List<gameObject>(); // speichere alle bereits erstellten Objekte
        for (int i = 0; i < objectCount; i++)
        {
            gameObject spawnObject = prefabs[Random.Range(0, prefabs.Length)]; // Welches Objekt soll gespawnt werden?
            Vector3 spawnPos = calculator.CalcPointOnSphere(distanceToPlanet); // Wo soll das Objekt gespawnt werden?
            if(CheckSpawnPoint(spawnObjectsList, spawnObject, spawnPos)) // Kollisionsprüfung
            {
                    gameObject objectToSpawn = (gameObject)Instantiate(spawnObject, spawnPos, Quaternion.identity); // neues Objekt
                    spawnObjectsList.Add(objectToSpawn); // das neue Objekt der Liste hinzufügen
            }
        }
    }

    private bool CheckSpawnPoint(List<gameObject> spawnObjectsList, GameObject objectToSpawn, Vector3 spawnPos)
    {
        foreach(gameObject listObject in spawnObjectsList) // alle bereits gespawnten Objekte
        {
            if(..) // wenn das zu spawnende objekt mit einem bereits vorhandenen Objekt kollidieren würde ...
            {
                return false;
            }
        }
        return true;
    }
}


Wäre cool, wenn jemand zum unteren Teil eine Idee hätte :)


Moderiert von user profile iconTh69: Topic aus C# - Die Sprache verschoben am Mi 07.12.2016 um 13:26
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 07.12.16 14:30 
Hallo,

bitte Crosspost immer angeben: myCSharp.de - Unity Spawnalgorithmus auf einem Planeten mit Kollisionsabfrage
Hat denn das dort erwähnte Physics.OverlapSphere nicht geholfen?
Du erhältst damit ja eine Liste der überlappenden Objekte, und wenn diese nicht leer ist, dann einfach das Objekt neu platzieren...
Garzec Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29



BeitragVerfasst: Mi 07.12.16 16:18 
Also ich habe den Code mal runtergekürzt:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
    CalcCoordinates calculator;

    GameObject planet;
    public GameObject[] planetPrefabs;
    public GameObject[] skyPrefabs;
    public GameObject[] spacePrefabs;

    void Start()
    {
        calculator = GameObject.FindGameObjectWithTag("Calculator").GetComponent<CalcCoordinates>();

        planet = GameObject.FindGameObjectWithTag("Planet");

        SpawnObjects(planet, planetPrefabs, PlayerPrefs.GetInt("planetObjectsCount"), 50);
        SpawnObjects(planet, skyPrefabs, PlayerPrefs.GetInt("skyObjectsCount"), 150);
        SpawnObjects(planet, spacePrefabs, PlayerPrefs.GetInt("spaceObjectsCount"), 200);
    }

    private void SpawnObjects(GameObject planet, GameObject[] prefabs, float objectCount, float distanceToPlanet)
    {
        for (int i = 0; i < objectCount; i++)
        {
            Instantiate(prefabs[Random.Range(0, prefabs.Length)], calculator.CalcPointOnSphere(distanceToPlanet), Quaternion.identity);
        }
    }


Wenn ich innerhalb der Schleife eine do-while Schleife einbaue, fliegt mir das Programm um die Ohren.

In Pseudo-Code hatte ich

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Collider[] colliders = ...
do
{
Instantiate...
}
while
{
colliders != null;
}