Skip to content

Instantly share code, notes, and snippets.

@SanielX
Created June 1, 2020 18:54
Show Gist options
  • Save SanielX/e6dff5a0b0f14e11b45b184399b49a7a to your computer and use it in GitHub Desktop.
Save SanielX/e6dff5a0b0f14e11b45b184399b49a7a to your computer and use it in GitHub Desktop.
Small script I made to raplace all trees on terrain with something better for navmesh.
/*
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);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment