• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by shivanDragon · Nov 21, 2012 at 11:40 AM · terrain

Programatically changing the tileSize of a SplatPrototype

I have a script to which I add a Terrain object (I drag and drop the terrain in the public Terrain field).

The Terrain is already setup in Unity to have 2 PaintTextures: 1 is a Square (set up with a tile size so that it forms a checkered pattern) and the 2nd one is a grass image:

alt text

Also the Target Strength of the first PaintTexture is lowered so that the checkered pattern also reveals some of the grass underneath.

Now I want, at run time, to change the Tile Size of the first PaintTexture, i.e. have more or less checkers depending on various run time conditions. I've looked through Unity's documentation and I've seen you have the Terrain.terrainData.SplatPrototype array which allows you to change this. Also there's a RefreshPrototypes() method on the terrainData object and a Flush() method on the Terrain object. So I made a script like this:

 public class AStarTerrain : MonoBehaviour {
 
     public int aStarCellColumns, aStarCellRows; 
 
     public GameObject aStarCellHighlightPrefab;
     public GameObject aStarPathMarkerPrefab;
     public GameObject utilityRobotPrefab;
     public Terrain aStarTerrain;
 
     void Start () {
             //I've also tried NOT drag and dropping the Terrain on the public field 
             //and instead just using the commented line below, but I get the same results
         //aStarTerrain = this.GetComponents<Terrain>()[0];
         Debug.Log ("Got terrain "+aStarTerrain.name);
 
         SplatPrototype[] splatPrototypes = aStarTerrain.terrainData.splatPrototypes;
         Debug.Log("Terrain has "+splatPrototypes.Length+" splat prototypes");
         SplatPrototype aStarCellSplat = splatPrototypes[0];
         Debug.Log("Re-tyling splat prototype "+aStarCellSplat.texture.name);
         aStarCellSplat.tileSize = new Vector2(2000,2000);
         Debug.Log("Tyling is now "+aStarCellSplat.tileSize.x+"/"+aStarCellSplat.tileSize.y);
         aStarTerrain.terrainData.RefreshPrototypes();
         aStarTerrain.Flush();
     }
 
 //...




Problem is, nothing gets changed, the checker map is not re-tiled. The console outputs correctly tell me that I've got the Terrain object with the right name, that it has the right number of splat prototypes and that I'm modifying the tileSize on the SplatPrototype object corresponding to the right texture. It also tells me the value has changed. But nothing gets updated in the actual graphical view.

So please, what am I missing?

1.jpg (124.9 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by ArnoC · Sep 13, 2014 at 12:38 AM

To change any property of any SplatPrototype of a terrain, duplicate the existing array of SplatPrototypes, ie create a new array with different instances inside, but with the same textures, tile offsets and size. Then you can change any property of the prototypes you need. Finally, assign that array back on the TerrainData.

No need to Flush() or RefreshPrototypes().

Caution: all changes made from code on a terrain while the game is running in the editor are persistent. So don't delete all your SplatPrototypes and don't mess them up by code, if you want to keep them after you stop the game in the editor.

Tested and works in Unity 4.5.4

 SplatPrototype[] oldProtos = terrain.terrainData.splatPrototypes;
 SplatPrototype[] newProtos = new SplatPrototype[oldProtos.Length];
 for(int i=0; i<oldProtos.Length; i++) {
     SplatPrototype oldProto = oldProtos[i];
     SplatPrototype newProto = new SplatPrototype();
     newProtos[i] = newProto;

     // Change what you need here
     newProto.texture = oldProto.texture;
     newProto.tileSize = oldProto.tileSize;
     newProto.tileOffset = oldProto.tileOffset;
     newProto.normalMap = oldProto.normalMap;
 
 }
 // Change what you need here
 terrain.terrainData.splatPrototypes = newProtos;


Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Owen-Reynolds · Jun 14, 2016 at 09:34 PM 0
Share

Still works in 5.2. To restate, you really do have to assign the entire splatPrototypes at once. Not even splatPrototypes[0]=abcwill work. In other words, reading splatPrototypes gives you a clone, similar to how the system clones materials.

The caution also applies: this still changes the terrain in your Assets/Project.

avatar image
0

Answer by gilley033 · Dec 29, 2012 at 09:27 AM

After working with terrains a bunch recently, I have found it's basically impossible to modify the member data of a splatPrototype directly.

What you should be able to do, however, is create a temporary splatprototype array that is basically the same as your original splat prototypes, but with different tileSize.

I've only used this method to set the terrainData of newly created terrain that hasn't had any splatPrototypes set. It may be that this doesn't work on terrain that already has has its splatPrototypes set. Sorry if that's the case, but I guess it's worth a try nonetheless.

 //After you've gotten your terrain and stored your terrains SplatPrototypes, use this code
 //Declare this first line however it needs to be in C: I'm not a C expert, 
 //so I only know the way of doing it in Unityscript
     tempSplat : SplatPrototype = new SplatPrototype();
                     
     tempSplat.texture = splatPrototypes[0].texture;
                         
     //Uncomment this line if using Unity 4.0 or greater. normal maps were only added in 4.0.                    
     //tempSplat.normalMap = splatPrototypes[0].normalMap;
                         
     tempSplat.tileSize.x = 2000;
     tempSpat.tileSize.y = 2000;
     
     tempSplat.tileOffset.x = splatPrototypes[0].tileOffset.x;
     tempSplat.tileOffset.y = splatPrototypes[0].tileOffset.y;
     
     splatPrototypes[0] = tempSplat;
     
     aStarTerrain.terrainData.RefreshPrototypes();
     aStarTerrain.Flush();
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Setting SplatPrototypes is very slow! (50 ms every Terrain), coroutines/threading? (I need suggestions) 0 Answers

Make a simple tree 1 Answer

How to assign texture position on the terrain by coding, not the GUI 3 Answers

Tree Creator Problems 1 Answer

terrain serialization detail grass 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges