Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • 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
5
Question by lzt120 · Apr 13, 2010 at 08:54 AM · textureterraintriggersplat

How can I perform some action based on the terrain texture currently under my player?

I want trigger with texture on terrian, some area make player hurts, some area player can not pass throught, how this can be handled in Unity. Thanks.

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

4 Replies

· Add your reply
  • Sort: 
avatar image
12
Best Answer

Answer by duck · Apr 13, 2010 at 10:30 AM

(see new edit below for link to example script)

You can read values from the "Mix Map" (a.k.a. Splat Map, Alpha Map, Control Texture - these are often used to refer to the same thing) using some undocumented terrain functions. The Mix Map controls the blending of each of your textures across the terrain, and is a 2D grid of values. The size of this grid is determine by the "Control Texture Resolution" setting in the terrain dialog box.

So, you'll need to convert the player's world coordinates to coordinates which represent the grid cell of the "control texture" which the player is currently within. A similar technique is described in this question, but in this case it converts it to the 2d heightmap grid:

How to translate WORLD coordinates to TERRAIN coordinates?

However instead of the heightmap size, you'll need to use the Mix Map size which can be read using the undocumented command, terrain.alphamapResolution.

So, to convert, you need to subtrack the terrain's position, divide by the terrain size, and multiply by that Mix Map Size:

var terrainData = terrain.terrainData;
var terrainPos = terrain.transform.position;
var mapX = ((player.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth;
var mapZ = ((player.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight;

Next you need to use those coordinates to sample the values which control the mix of textures at that position, using the undocumented function GetAlphamaps, like this:

var splatmapData = terrain.GetAlphamaps(x, y, width, height); 

Because the alphamap data is a 2d grid, the x & y values here are integers, as are the width & height values (which let you sample an area of the grid of any size). Because you're only interested in sampling the cell under the player, the width and height should be 1.

Now you're left with a variable (splatmapData) which contains a 3d array. To read the mix levels of each texture layer, you need something like this:

var texture1Level = splatmapData[0,0,0];  // texture layer 1
var texture2Level = splatmapData[0,0,1];  // texture layer 2
var texture3Level = splatmapData[0,0,2];  // texture layer 3
var texture4Level = splatmapData[0,0,3];  // texture layer 4

(the reason you have 0,0 at the start is because "splatmapData" could have contained a sampled area larger than 1x1 in size, so this specifies the location within the sampled area. Because our width & height was 1,1 - the sampled area is only one cell in size).

The number of lines above should match the number of texture layers you're using in your terrain. If an area is 100% covered in one texture, you should find that texture level has a value of 1.0, and the rest have a value of 0.0. If there is a blend of textures at that location, you'll find that more than one layer has a value larger than 0.0, and that they all add up to a total of 1.0.

For more detail about maniupulating the terrain textures via scripting, see these answers:
How can I automatically place grass and other details on my terrain to correspond with the splatmap?
How to automatically apply different textures on terrain based on height?

Note:
*Some of these functions are undocumented. These have now been officially added to the Unity API! Check the Terrain and TerrainData documentation.

In addition, I have written a helper script to easily detect the type of texture on a terrain at a given location, in answer to another question.

Comment
Add comment · Show 9 · 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 alexnode · Apr 13, 2010 at 10:37 AM 0
Share

wow! thanks ...

avatar image duck ♦♦ · Apr 13, 2010 at 10:41 AM 0
Share

this doesn't solve the problem of not being able to pass through certain areas though...!

avatar image alexnode · Apr 13, 2010 at 10:53 AM 0
Share

I think that using textures for collision doesn't really make sense . But for sound and changes in movement is ace ! You can do loads !!

avatar image duck ♦♦ · Apr 13, 2010 at 03:46 PM 0
Share

Yes I think for collisions, unless it has to be procedurally deter$$anonymous$$ed, your best option would be to manually build invisible colliders in the correct place - either using collider primitives, or by importing a mesh built in a 3D app which contains the "walls" in the correct positions.

avatar image Zeroth · Jun 28, 2010 at 08:12 PM 0
Share

By "texture layer" do you mean all the different terrain textures that can be painted, or something else? How can we tell how many texture layers we have?

Show more comments
avatar image
0

Answer by KvanteTore · Apr 13, 2010 at 09:51 AM

Having a texture on the terrain in an area can be handled independently of taking an action when the player enters that area.

The texture can be applied as normal using the terrain editor.

To detect when the player enters these areas, you could create objects without renderers, but with colliders that you scale and place around the landscape. To make the areas impassable you simply add the colliders, which will turn the invisible. To make them passable but taking some when the player enters you can mark the colliders as Trigger and use the OnTriggerEnter, OnTriggerLeave and OnTriggerStay to take the appropriate action.

Comment
Add comment · Show 2 · 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 alexnode · Apr 13, 2010 at 10:17 AM 0
Share

Yes but is there any way to raycast on the terrain and get the current texture you are sitting on ? You could do some nice staff if you could find the name of each splat map. Like changing the footstep sound or the jump height etc. And it would be seriously quicker than adding colliders.

avatar image alexnode · Apr 13, 2010 at 10:33 AM 0
Share

I mean yes you should add colliders and triggers for some functions but there are some nice things you could do with knowing the texture.

avatar image
0

Answer by alexnode · Apr 13, 2010 at 10:34 AM

There is a discussion here about that topic. It is interesting http://forum.unity3d.com/viewtopic.php?t=6429&highlight=ray+terrain+texture

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
avatar image
0

Answer by TheKusabi · Nov 07, 2012 at 08:06 PM

After looking into it for a few hours.,I am pretty happy with this function I made.

 public Texture getTerrainTextureAt( Vector3 position )
     {
         // Set up:
         Texture retval    =    new Texture();
         Vector3 TS; // terrain size
         Vector2 AS; // control texture size
 
         TS = Terrain.activeTerrain.terrainData.size;
         AS.x = Terrain.activeTerrain.terrainData.alphamapWidth;
         AS.y = Terrain.activeTerrain.terrainData.alphamapHeight;
 
 
         // Lookup texture we are standing on:
         int AX = (int)( ( position.x/TS.x )*AS.x + 0.5f );
         int AY = (int)( ( position.z/TS.z )*AS.y + 0.5f );
         float[,,] TerrCntrl = Terrain.activeTerrain.terrainData.GetAlphamaps(AX, AY,1 ,1);
         
         TerrainData TD = Terrain.activeTerrain.terrainData;
         
         for( int i = 0; i < TD.splatPrototypes.Length; i++ )
         {
             if( TerrCntrl[0,0,i] > .5f )
             {
                 retval    =    TD.splatPrototypes[i].texture;
             }
             
         }
         
         
         return retval;
     }

Just use it like this.

 Texture floorTexture = getTerrainTextureAt( transform.position );


Feel free to use this.

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.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Modifying Terrain Splat Texture at Runtime 2 Answers

How can I automatically place grass and other details on my terrain to correspond with the splatmap? 5 Answers

Terrain Splatting 1 Answer

Positioning textures on terrain 0 Answers

Can i change the Texture of terrain 3 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