Come appiattire il terreno sotto un oggetto di gioco?


10

Ho una sceneggiatura che crea un oggetto terreno e lo dipinge con trame, ma sto riscontrando un problema. Quando provo a posizionare oggetti di gioco (come il semplice oggetto d'acqua fornito dall'unità), utilizzo un Raycast per determinare l'altezza corretta per posizionare l'oggetto di gioco, ma ciò assicura che sia posizionato correttamente in quel particolare punto.

Come potrei fare per appiattire il terreno sotto l'oggetto di gioco in modo che non vada nel terreno o bazzichi nel nulla in caso di colline?


3
Trova tutti i vertici che formano i triangoli del terreno sotto l'oggetto di gioco. Rendi le coordinate y di tutti quei vertici uguali.
MichaelHouse

Risposte:


6

Come ho detto nel mio commento, vorrai trovare tutti i vertici che compongono i triangoli sotto il tuo oggetto di gioco e impostare il loro valore y sullo stesso valore.

Espanderò il mio commento con passaggi più dettagliati. Non ho familiarità con Unity, quindi non conosco gli strumenti migliori da utilizzare per il lavoro, ma credo di poterti iniziare sulla strada giusta.

Metodo della forza bruta:

  1. Lancia una griglia di raggi direttamente dal tuo oggetto di gioco. La griglia dovrebbe essere abbastanza stretta da garantire che non mancheranno triangoli sulla superficie del terreno.
  2. Per ogni raggio che colpisce qualcosa, puoi ottenere il triangolo nella mesh del terreno con il seguente:

    RaycastHit hit;
    if (!Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))
        return;
    
    MeshCollider meshCollider = hit.collider as MeshCollider;
    if (meshCollider == null || meshCollider.sharedMesh == null)
        return;
    
    Mesh mesh = meshCollider.sharedMesh;
    Vector3[] vertices = mesh.vertices;
    int[] triangles = mesh.triangles;
    Vector3 p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
    Vector3 p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
    Vector3 p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];
  3. p0, p1 e p2 sono tutte le posizioni dei tre vertici che compongono il triangolo che è stato colpito. Volete regolare ciascuna di queste posizioni dei vertici per avere lo stesso yvalore. Puoi raccogliere tutti i vertici, quindi impostarli tutti su un yvalore medio oppure puoi utilizzare il yvalore iniziale raccolto che hai trovato quando hai posizionato l'oggetto di gioco.

ottimizzazioni:

  • Invece di lanciare una griglia di raggi, puoi spazzare giù un collettore dall'oggetto di gioco e raccogliere i punti di contatto delle collisioni tra il collettore di oggetti di gioco e la maglia di collisione del terreno. Quindi, per ciascuno di quei punti di contatto, eseguire i passaggi sopra per ottenere i vertici che si desidera spostare.

  • Crea il tuo terreno in modo tale che i vertici xe i zvalori siano allineati a una griglia e varia solo nel suo yvalore. Ora puoi facilmente ottenere i limiti dell'oggetto di gioco e modificare tutti i valori y dei vertici all'interno di tali limiti.

Quest'ultima ottimizzazione è davvero un metodo alternativo che sarebbe probabilmente facile da implementare e abbastanza efficace.


Da quello che posso dire l'oggetto Terrain ( docs.unity3d.com/Documentation/ScriptReference/Terrain.html ) ha un TerrainCollider ( docs.unity3d.com/Documentation/ScriptReference/… ) non un MeshCollider ( docs.unity3d.com/Documentation / ScriptReference / ... ), quindi manca una proprietà sharedMesh che si tenta di utilizzare nel passaggio 2. Ho assunto che avrei bisogno di una sorta di logica per modificare la mappa di altezza memorizzata dalla proprietà terrainData.
Rapida,

Puoi controllare qui: forum.unity3d.com/threads/… Inoltre, sembra che l'oggetto del terreno abbia una mesh regolare, quindi la seconda optimaization potrebbe essere la soluzione migliore.
MichaelHouse

1

In genere vuole che il terreno sotto l'oggetto sia piano e che il terreno immediatamente circostante sia levigato.

Se il terreno è costituito da una griglia e l'edificio è allineato agli assi, questo è molto più semplice.

Nel caso generale, si suddividono i triangoli su cui si trova l'edificio, quindi si imposta la y di tutti i vertici sui triangoli su cui l'edificio si trova sullo stesso y , quindi si esegue un livellamento dello spostamento del punto medio per tutti i vertici entro una certa distanza che sono non se stessi sotto un edificio.

Ho usato questo approccio per mettere le strade su un terreno 3D.

In genere si desidera imporre una separazione minima tra gli edifici per avere abbastanza terra da lisciare. Oppure potresti eseguire l'algoritmo in via provvisoria prima del posizionamento e vedere se viene superata una certa soglia di ripidezza e quindi controllare dove l'utente può posizionare gli edifici.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.