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