Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

05.12.2013, 18:58

Export von Unity Terrain für Collision Detection am Server

Servus zusammen,

nachdem ich lange Zeit vor dem Problem stand wie ich am sinnvollsten Themen wie Collision Detection und LoS u.Ä Server-Seitig implementieren könnte, habe ich schlussendlich eine Lösung gefunden, die wunderbar funktioniert und die ich euch gerne zeigen würde.

Ziel des ganzen ist es, das Terrain welches in Unity erstellt wird, am Server laden zu können und dort mit einer Physik Engine wie in meinem Fall der Bullet-Physics zu nutzen.


Zuerst brauchen wir eine Klasse welches unser Terrain als Objekt darstellt.

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TerrainData{
// 0 Punkt des Terrains
public Vector3 Center { get; set; }
// Breite
public int Width {get; set;}
// Länge
public int Length {get; set;}
// Höhendaten ( Heightmap im Endeffekt )

public float[] HData{get;set}
public float HeightScale{get;set;}
public Vector3 Scale{get;set}

public TerrainData(){
 Center = new Vector3();
 Scale = new Vector3();
}
}


Dann brauchen wir ein EditorScript in Unity.
Ich schreibe hier nicht das komplette Script sondern nur den Teil der wichtig ist für das Verständnis.

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
public static void ExportTerrainCollider(){ 
foreach(var tcoll in FindObjectsOfType(typeof(Collider)).Cast<Collider>())
{
                var terrain = tcoll as TerrainCollider;
                if (terrain != null)
                {
                    var terrainData = terrain.terrainData.GetHeights(0, 0, terrain.terrainData.heightmapWidth,
                                                               terrain.terrainData.heightmapHeight);
                    int width = terrain.terrainData.heightmapWidth;
                    int height = terrain.terrainData.heightmapHeight;
                    float[] heightData = new float[width * height];
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            heightData[y * width + x] = terrainData[y, x] * terrain.terrainData.size.y;
                        }
                    }
                    var center = (terrain.terrainData.size / 2f) + terrain.gameObject.transform.position;
                    TerrainData terrainCollider = new TerrainData()
                    {
                        Center = new Vector3(center.x, center.y, center.z),
                        Length = height,
                        Width = width,
                        HData = heightData,
                        HeightScale = terrain.terrainData.size.y,
                        Scale = new Vector3(terrain.terrainData.size.x / width, 1f, terrain.terrainData.size.z / height)
                    };
                }
}
}


Durch Anpassung der Foreach, ist es natürlich auch möglich, sich noch die Collider aller Objekte zu holen, das gehört aber nicht hier her.

Wichtig: Das ist kein Copy&Paste -> Win - Code.
Ihr müsst noch alles drum her rum selber bauen.

Die Nutzung in eurer Lieblings Physik-Engine ist nachdem ihr für jedes Terrain ein Objekt habt, ein Pappenstiel.

Ich hoffe ich konnte manchem dadurch auf die Sprünge helfen, da mir auch am Anfang der Ansatz gefehlt hat.

Viele Grüße
Chris

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »chrisss« (05.12.2013, 19:05)