TerrainRegions, :CopyRegion(), and :PasteRegion()

It appears (based on this post), not everyone knows about TerrainRegions, so I guess it is tutorial time for terrain regions.

[size=6]What is a TerrainRegion[/size]

A terrain region is described as a snapshot of a section of Terrain. It is an instance that looks like Terrain in the explorer.

Something to note is, unlike Terrain, a TerrainRegion is not a BasePart The properties that it contains are the normal instance properties (Name, Parent, ClassName, and Archivable), but also has the following properties:


Bool IsSmooth (Readable only)

Vector3 SizeInCells (Readable only)

As well as the following function:


Void :ConvertToSmooth() [PluginSecurity]

Another note is you can create it with Instance.new(“TerrainRegion”), but it will just be an empty region.

[size=6]Using CopyRegion and PasteRegion[/size]

With using Instance.new, no data is recorded for the region, but using CopyRegion and PasteRegion will read and write terrain data (even smooth terrain is still smooth).

[size=4]
Terrain:CopyRegion(Region3int16)[/size]

The function to create a TerrainRegion, you need to copy the existing terrain. The region you need is a special type of Region3int16, which is based on the voxel grid. To make a Region3int16 in this case, you need to do Region3int16.new(Vector3int16.new(MinCorner),Vector3int16.new(MaxCorner)), and it can’t be reversed (swamp the min and max corner) because it will cause unwanted results. See the image for what it looks like.

If you want to just copy the whole terrain (ex: Min corner to max corner), you can use the property game.Workspace.Terrain.MaxExtents. This function will return a TerrainRegion instance.

[size=4]Terrain:PasteRegion(TerrainRegion,Vector3int16,Bool)
[/size]
Once you have a TerrainRegion, you can now paste it wherever you want. The first argument for pasting the region is the TerrainRegion. The second argument is the min corner (see above) in the form of a Vector3int16. For the example above, to have it the same spot, it would be Vector3int16.new(-2,0,0). If copied the whole terrain and want to paste it in the current min corner of terrain, you can use game.Workspace.Terrain.MaxExtents.Min, which is a Vector3int16. The bool is for weather it would paste empty cells. If it is true, it will override any cell for an empty cell if there is one and the terrain region, and does not override any cells if the cell in the TerrainRegion is empty.

[size=6]Issues with using TerrainRegions
[/size]
1.You can’t store a TerrainRegion as a string, number, or any non-Userdata forms (ex: DataStores)
2.You can’t rotate TerrainRegions
3.You can’t create a TerrainRegion and have a property to set the data, you need to have terrain to copy
4.The IsSmooth property in TerrainRegions has to match the IsSmooth property in Terrain, or else it will error
5. Can’t generate via local scripts, FilteringEnabled or not. (See Crazyman32’s post below)

[size=6]
Alternatives[/size]

You can easily make a version that stores a table or JSON string. A while ago, I made this, which does work, but does not smoothly do Smooth Terrain.

For Smooth Terrain, there is two functions which is ReadVoxels and WriteVoxels, all though I am not 100% sure how to use them.

That is all for the tutorial. :wink:

[b][i]For whatever reason you want to share an image of this post, here is a picture I assembled together of this whole post: Imgur: The magic of the Internet

10 Likes

Another note is that you cannot use CopyRegion or PasteRegion client-side. So if you want to load in terrain maps for each local player, this will not work unfortunately.

1 Like

I would imagine this may be changed if local parts became supported. David Baszucki said it would happen… and that was last year…

I would imagine this may be changed if local parts became supported. David Baszucki said it would happen… and that was last year…[/quote]

Maybe. Check out my thread on this a while back and zeuxcg’s responses: http://developer.roblox.com/forum/client-features/15197-locally-rendered-terrain#163584

On my plugin to do list now: “TerrainAsBricks - generate invisible parts over terrain that you can select, resize, copy/paste, load into other places (that have the plugin), etc”

For storing via non-UserData formats, why not just use Terrain:ReadVoxels() and Terrain:WriteVoxels()?

Pretty much the only reason is you need SmoothTerrain for it to be usable, not to mention is has a maximum size it can read and write (I think it is 500,500,500, but I am not sure).

Didn’t think you were actually going to make a tutorial :o

Thanks, can I snapshot this post and send it to a friend of mine?

[quote] Didn’t think you were actually going to make a tutorial :o

Thanks, can I snapshot this post and send it to a friend of mine? [/quote]
Either I make a long post that gets lost or I make an easy to find tutorial. :stuck_out_tongue:

As for a screenshot, I will just go ahead and make one and upload it to imgur.
Edit: Added to original post