- Home /
 
Seasonal Terrain Trees From Script
I'd like to add a bit of seasonal flare to my trees which are not placed gameObjects in the hierachy, they are trees added via the Terrain paint widget. I created a gameObject test tree that pingpongs between red and green via script, added that tree into the terrain tree painter and put a few down but at runtime they don't change. I had a feeling it wouldn't be that easy ;-)
Is there a method to access a TERRAIN tree and modify it via script/C#?
Answer by getyour411 · Aug 22, 2013 at 05:30 AM
Putting together parts I found on UA, forums, general Google search etc I have came up with the following. I'm not sure if I should post it given the warnings associated with changing TerrainData but it does what I wanted and could be extended to do much more. On the other hand, if a moderator thinks it should be deleted that's ok.
 using UnityEngine;
 using System.Collections;
 
 // WARNING WARNING WARNING: The sources I found to assist with this indicate these were/might still be undocumented APIs,
 // and there's no undoing the changes made to your tree and terrain - it WILL NOT SNAP BACK when you click Stop in the Editor.
 // There could be other complications as well. Use at your risk.
 
 // Step 1. Create a tree/prefab and put it into the Terrain Tree Painter
 // Step 2. Create the same tree/model/etc but change the color to simulate a Fall color scheme and add it to Terrain Tree Painter
 // Step 3. Attach this to something
 
 public class QM_TreeSeasons : MonoBehaviour
 {
 
     public TerrainData terrain;             // drag the Terrain Data in Editor
     public int treeCount;
     public int treeTypes;
     public TreeInstance[] currentTreeList;
     private bool season;
     
     // These values are the prefab/prototype index value spat out by Start()
     
     public int springTreeIndex;
     public int fallTreeIndex;
     
     void Awake ()
     {
         treeCount = 0;    
         treeTypes = 0;
         springTreeIndex = -1;
         fallTreeIndex = -1;
     }
     
     void Start ()
     {
         
         //Set active terrain
         terrain = Terrain.activeTerrain.terrainData;        
         
         // Setup a holding array
         currentTreeList = new TreeInstance[terrain.treeInstances.Length];
         
         // Get some numbers
         treeTypes = terrain.treePrototypes.Length;
         treeCount = terrain.treeInstances.Length;
         
         // Displays some numbers
         Debug.Log ("Tree types (i.e # of prefabs in Terrain tree painter: " + treeTypes);
         Debug.Log ("They are: ");
 
         // Search the trees and print the name and index
         for (int cnt=0; cnt < terrain.treePrototypes.Length; cnt++) {
             Debug.Log ("name: " + terrain.treePrototypes [cnt].prefab.name + " @ prototype index " + cnt);
             
         }
         
     }
     
     // STOP STOP STOP: 
     // ChangeSeasons() changes your TerrainData and there's no going back.
     // If you run this next block you will be changing, permanently,
     // your TerrainData trees. Don't press "X" unless you are sure.
         
     
     void ChangeSeasons ()
     {
         
         // Copy existing TreeInstances array contents into holding array
         System.Array.Copy (terrain.treeInstances, currentTreeList, terrain.treeInstances.Length);
                 
         if (terrain.treeInstances.Length == currentTreeList.Length) {
             
             for (int tcnt=0; tcnt < currentTreeList.Length; tcnt++) {
                     
                 if (season) {
                     if (currentTreeList [tcnt].prototypeIndex == springTreeIndex) {
                         currentTreeList [tcnt].prototypeIndex = fallTreeIndex;
                     }
                 }
                 if (!season) {
                     if (currentTreeList [tcnt].prototypeIndex == fallTreeIndex) {
                         currentTreeList [tcnt].prototypeIndex = springTreeIndex;
                     }
                 }
             }
             terrain.treeInstances = currentTreeList;
             season = !season;
         }
         
     }
     
     // Having giving all the warnings above, if you want to toggle your trees, press X again
     // I don't know if other stuff in your terrain data might be affected. Use at your own risk.
 
     void Update ()
     {
         if (Input.GetKeyUp (KeyCode.X)) {
             if (springTreeIndex == -1 || fallTreeIndex == -1) {
                 Debug.Log ("You have to set these values matching the desired models");
                 Debug.Log ("prefab index values shown in Debug.Log");
             } else {
                 ChangeSeasons ();
             }
         }
     }
 }
 
              Your answer
 
             Follow this Question
Related Questions
Importing custom tree into terrain editor - how do I do it? 1 Answer
Wierd Material Behaviour 0 Answers
How to change leave color at runtime? 1 Answer
My grass looks really weird. 0 Answers
Tree brush making very tiny trees 0 Answers