Advertisement
Staggart

Unity - Convert terrain trees to GameObject's

Mar 10th, 2023
1,159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.73 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using Object = UnityEngine.Object;
  6. #if UNITY_EDITOR
  7. using UnityEditor;
  8. #endif
  9.    
  10. [RequireComponent(typeof(Terrain))]
  11. public class ConvertTreesToGameObject : MonoBehaviour
  12. {
  13.     [SerializeField]
  14.     private Terrain terrain;
  15.  
  16.     private void Reset()
  17.     {
  18.         terrain = GetComponent<Terrain>();
  19.     }
  20.    
  21.     [ContextMenu("Extract")]
  22.     public void Extract()
  23.     {
  24.         List<GameObject> children = new List<GameObject>();
  25.         foreach (Transform child in transform)
  26.         {
  27.             //Skip the first, since its the terrain itself
  28.             if(child == transform) continue;
  29.            
  30.             children.Add(child.gameObject);
  31.         }
  32.  
  33.         foreach (GameObject child in children)
  34.         {
  35.             //Remove all previously created objects first
  36.             DestroyImmediate(child);
  37.         }
  38.  
  39.         for (int i = 0; i < terrain.terrainData.treePrototypes.Length; i++)
  40.         {
  41.             TreePrototype tree = terrain.terrainData.treePrototypes[i];
  42.      
  43.             //Get all instances matching the prefab index
  44.             TreeInstance[] instances = terrain.terrainData.treeInstances.Where(x => x.prototypeIndex == i).ToArray();
  45.      
  46.             for (int j = 0; j < instances.Length; j++)
  47.             {
  48.                 //Un-normalize positions so they're in world-space
  49.                 instances[j].position = Vector3.Scale(instances[j].position, terrain.terrainData.size);
  50.                 instances[j].position += terrain.GetPosition();
  51.  
  52.                 #if UNITY_EDITOR
  53.                 GameObject instance = PrefabUtility.InstantiatePrefab(tree.prefab, this.transform) as GameObject;
  54.                 #else
  55.                 GameObject instance = Object.Instantiate(tree.prefab.gameObject, this.transform);
  56.                 #endif
  57.                
  58.                 instance.name = tree.prefab.name + j;
  59.                 instance.transform.position = instances[j].position;
  60.                 instance.transform.rotation = Quaternion.Euler(0f, Mathf.Rad2Deg * instances[j].rotation, 0f);
  61.                 instance.transform.localScale = new Vector3(instances[j].widthScale, instances[j].heightScale, instances[j].widthScale);
  62.             }
  63.         }
  64.     }
  65. }
  66.  
  67. #if UNITY_EDITOR
  68. [CustomEditor(typeof(ConvertTreesToGameObject))]
  69. class ConvertTreesToPrefabInspector : Editor
  70. {
  71.     private ConvertTreesToGameObject script;
  72.     private void OnEnable()
  73.     {
  74.         script = (ConvertTreesToGameObject)target;
  75.     }
  76.  
  77.     public override void OnInspectorGUI()
  78.     {
  79.         base.OnInspectorGUI();
  80.  
  81.         if (GUILayout.Button("Extract trees"))
  82.         {
  83.             script.Extract();
  84.         }
  85.     }
  86. }
  87. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement