|
/* |
|
I assumed all trees have capsule colliders so you'll need one on tree or in children. |
|
Also tree prefab must be marked as Navmesh static |
|
Undo is not implemented here, so use it carefully |
|
*/ |
|
using System.Collections.Generic; |
|
using UnityEditor; |
|
using UnityEngine; |
|
|
|
namespace HostGame |
|
{ |
|
public class PrepareTerrainForNavmeshBake : MonoBehaviour |
|
{ |
|
private TreeInstance[] OriginalInstances; |
|
private TreePrototype[] Prototypes; |
|
|
|
public GameObject ColliderPlaceholder; |
|
public Terrain terrain; |
|
|
|
[ContextMenu("Transform Terrain")] |
|
public void TransformTerrain() |
|
{ |
|
var data = terrain.terrainData; |
|
|
|
OriginalInstances = data.treeInstances; |
|
Prototypes = data.treePrototypes; |
|
|
|
terrain.terrainData.SetTreeInstances(new TreeInstance[0], false); |
|
|
|
for (int i = 0; i < OriginalInstances.Length; i++) |
|
{ |
|
TreeInstance instance = OriginalInstances[i]; |
|
|
|
GameObject instancePrefab = Prototypes[instance.prototypeIndex].prefab; |
|
bool isNavigationStatic = GameObjectUtility.AreStaticEditorFlagsSet(instancePrefab, StaticEditorFlags.NavigationStatic); |
|
if (!isNavigationStatic) |
|
continue; |
|
|
|
CapsuleCollider treeCollider = instancePrefab.GetComponent<CapsuleCollider>(); |
|
if (!treeCollider) |
|
treeCollider = instancePrefab.GetComponentInChildren<CapsuleCollider>(); |
|
|
|
var placeholder = Instantiate(ColliderPlaceholder, transform); |
|
|
|
Vector3 terrainSize = terrain.terrainData.size; |
|
Vector3 worldSpacePos; |
|
worldSpacePos.x = terrainSize.x * instance.position.x; |
|
worldSpacePos.y = terrainSize.y * instance.position.y; |
|
worldSpacePos.z = terrainSize.z * instance.position.z; |
|
|
|
placeholder.transform.position = worldSpacePos + terrain.transform.position; |
|
float r = treeCollider.radius + instance.widthScale; |
|
placeholder.transform.localScale = new Vector3(r, treeCollider.height, r); |
|
|
|
|
|
GameObjectUtility.SetStaticEditorFlags(placeholder, StaticEditorFlags.NavigationStatic); |
|
} |
|
} |
|
|
|
[ContextMenu("Transform Back")] |
|
public void RestoreTerrain() |
|
{ |
|
List<Transform> children = new List<Transform>(); |
|
foreach (Transform child in transform) |
|
{ |
|
children.Add(child); |
|
} |
|
|
|
foreach (var child in children) |
|
DestroyImmediate(child.gameObject); |
|
|
|
terrain.terrainData.SetTreeInstances(OriginalInstances, true); |
|
} |
|
} |
|
} |