@TerraUnity Does TerraLand 2.2 work with Unity 2017’s .NET 4.6 scripting runtime?
First of all thanks for the kind words and sorry for the delay in reply. Runtime Terrain Deformation & Modification whether caused by explosions or player/vehicle interactions with the surface has been already implemented in our development, but these features will be available in our upcoming product which is under development and will be released soon. TerraLand will stay with its core features for GIS terrain generation and also be included in the new product.
So stay tuned to get the latest announcements on the new product.
The main issue with terrain manipulation in Unity which causes runtime modifications laggy and impractical is the SetHeights function in terraindata as already stated which will freeze the app on main thread for some time and is not thread-safe. Wish Unity team consider this factor so that we can all experience smooth terrain modifications at runtime.
In this case, just drop us an email so that we can book you in our list as a Terra +3 user in order to make a free transition. Once you have this new product you already have updated TerraLand, TerraTrees & TerraCity included in that package plus many other new components and yes, the TerraCity will bring geo-referenced buildings into the game.
I do not own this package, but please note that the upcoming product will include TerraEnhancer and many other shading/rendering assets for realistic rendering of terrain and environment elements in itself so what you are after as distance blending and detail textures are already there as a small part of the many features in our custom shaders. Some old screenshots has been already leaked here in this thread but more info will be there while we are close to the initial version or maybe a Beta release.
It’s weird because Texture2D.LoadImage is an internal function in Unity API and I thought maybe your Unity installation is corrupt until I find these similar issues:
https://discussions.unity.com/t/662213
So this post suggests reimporting the dll plugins and let the Unity API Updater does its job:
https://forum.unity.com/threads/unityengine-texture2d-loadimage-is-missing.467202/#post-3054402
Also as the LoadImage raised up here, just wanted to make another wish similar to SetHeights that it would be awesome to have these functions asynchronous and thread-safe:
https://feedback.unity3d.com/suggestions/async-texture2d-dot-loadimage-and-other-texture-operations
We use LoadImage in TerraLand Runtime to texture generated terrains at runtime and resolutions higher than 1024 will make huge spikes in our tests. Also would be great to access the LoadImage function source so that we can manually set queues in there through coroutines.
Theoretically yes, why wouldn’t it work if it is compatible with older versions!
But there are some code snippets in all scripts in TerraLand including the TerraLandSettings.cs script as the project launcher which revert the runtime API version to 2.0 in OnEnable function so whenever you change it in editor’s Player settings, they will revert it back to 2.0 and this causes a loop in re-setting.
Also we have found a weird bug/change in 4.6 which does not delete temp satellite images when needed and causes an unwanted loop of errors.
So we will remove the code snippets from all scripts so that the scripting runtime version will be set from only one place by users and also will investigate the previously mentioned issue to finally release a bug-free version of TerraLand in .NET 4.6.
How could I modify the code to cut of ocean areas? Since the downloaded data doesn’t feature bathymetry which I have to add it manualy after generating it separatedly using global mapper and unity terrain generation. Don’t know if Terraland feature a terrain blend tool, which - I guess - would fix my workflow.
Right now I’m using Autodesk Infraworks, but Terraland seems to provide a more straightforward approach.
TerraLand generate terrains on top of Unity’s built-in terrain shader system and does not touch the stock shader code. In order to cut holes in the terrain, we need to modify terrain shader to whether accept transparency or move vertices to somewhere else (self-invented
) or go the CPU way and modify terrain heights through its heightmap. However in both shader techniques the problem is that terrain collision is still there on modified areas as we only changed rendering through the GPU and this leads to another factor to be cared of (Switching terrain collider on/off whenever we are on transparent areas or not) if necessary; while changing the heightmap removes this limitation and collision follows generated surface.
As the topic is in a high demand so searching for such implementation on the 1st method will bring many results such as the following ones:
http://wiki.unity3d.com/index.php/TerrainTransparency
https://assetstore.unity.com/packages/tools/terrain/terrain-hole-system-8277
https://answers.unity.com/questions/730380/how-can-i-make-a-hole-in-the-terrain.html
https://answers.unity.com/questions/704763/does-anyone-know-how-to-implement-these-depth-mask.html
http://www.blog.radiator.debacle.us/2012/08/how-to-dig-holes-in-unity3d-terrains.html
If you are interested on how to move terrain vertices way down below so that bathy terrain is on top on those areas, let me know and I’ll share the shader code snippet to get going. But note that this is a quick hack of terrain rendering and is more limited than doing the transparency painting on desired areas.
Regarding modifying heightmap to suit your needs, it would be an easy process too, so first choose which method is enough for you and then give it a try.
P.S. never heard of Infraworks before, although it’s cool but at the end of the day you are not in a game engine and that’s what matters.
Also forgot to mention that in order to adjust terrain heights for your needs, there is already a similar scenario here with the solution:
Question: TerraLand 2 – High Quality Photo-Realistic Terrains from Real-World GIS Data page-7#post-3230526
Answer: http://wiki.unity3d.com/index.php/RaiseHeightmap
We are about to release the Offline Streaming feature in TerraLand and the development is mostly done so I think the release will be made in a few days from now.
Please note that this feature is the last one for now regarding TerraLand; this is due to focusing on our upcoming product which TerraLand is a part of it and secondly marketing failure in comparison to other assets while TerraLand offers way more features but we feel the community is not loyal to all this.
Following is just a heads up for the latest feature:
The steps to create a geo-server in TerraLand Downloader is so simple. This server is used for later streaming by Runtime API.
As before, you define an area in TerraLand Downloader but this time the area can cover a very large region such as a city or a country or possibly the whole Earth, because all needed tiles of obtaining elevation & imagery will be downloaded and saved on your hard drive with desired resolution.
A section is added to the Downloader component which is specialized for Local Server generating which defines number of total tiles for specified region and each elevation/image tile’s resolution.
The generated geo-server has a very simple structure which contains a “Elevation” folder including heightmap tiles and a folder titled “Imagery” including image tiles.
The Offline Runtime API connects to this local server and loads and applies needed data on terrains around the player in the scene dynamically as he travels. So users experience a seamless streaming of data and terrain generation just as our previous demo of WorldExplorer but this time without needing an internet connection and in a more managed system.
Regarding streaming of geo-referenced buildings and vegetation, these features will be a part of our upcoming product which is under development.
Hey @TerraUnity , has the offline streaming been released?
Hey @tgaldi we are about to release it in the following days. The implementation runs pretty smooth and optimized in our tests as the system has a lot of improvements and bug fixes now.
A sample demo build will be available today in a few hours and will be announced here.
This time it was a big delay in what I said, but hopefully we are there.
Download the first demo of our TerraLand Offline Streaming feature from here:
terraunity.com/freedownload/TerraLand_OfflineStreaming.zip

Controls:
Navigation: Arrow Keys/WASD
Move Up: “E”/Mouse Left Click
Move Down: “Q”/Mouse Right Click
Shift: Increase Speed
Alt: Decrease Speed
All movements are 3D Mouse simulated.
Ok for the ones who want to try the Offline Streaming demo with their own provided data tiles, it is needed to give some insights about how to set it up and how it works.
Setup
Simply put the generated geo-server containing elevation & imagery tiles in the root folder of the build. In order to detect the server path, the local server’s folder name always has to be exactly the same as defined in the “RuntimeOffline” script in the scene and “Project Root Path” checkbox must be selected so that TerraLand can detect the data source.
You can have as many folders as servers in the build’s root directory but TerraLand picks up the one with the name defined in the “RuntimeOffline” script in the scene.
Sever Structure
The structure of the local server is so simple. It contains 3 main folders of Elevation, Imagery & Info. These sub-folders also need to have the same name as original and any attempts to rename these folders will break the operation.
Obviously the Elevation folder contains downloaded and generated heightmap tiles and the Imagery folder contains downloaded satellite images as terrain textures.
As all the information for setting up the server is exposed here and it’s configurable from outside TerraLand, you can simply generate your own datasets and geo-servers from your own custom elevation/imagery data files created in any external GIS programs. Currently the heightmap format is limited to .raw files and image format is limited to .jpg.
How It Works
TerraLand’s Offline Streaming feature is a real-time dynamic system which streams elevation/imagery data on demand. So as the player travels around the world, the system updates surrounding terrains and feed needed tiles from the assigned server and converts them to Unity terrain assets.
In the provided demo from the previous post, the whole world area which is downloaded and cached is 40km x40km spread into a grid of 32x32 which is total of 1024 data tiles. The active see-able area around player is set to be a grid of 8x8 (64 tiles) which are updating whenever needed. So imagine the active area as a small square which is in another bigger square as the world which the smaller square updates its position in world’s bounds.
As the whole world size is 40km x 40km so the active area will be 10km x 10km (32 / 8 = 4 ===> 40 / 4 = 10).
Each heightmap tile resolution is 129 and each satellite image tile resolution is 1024. Full resolution coverage is 4096 pixels for the heightmap and 32768 pixels for the aerial imagery.
Sample Datasets
UPDATE: There are now sample scenes available in the TerraLand 3 package
Here are 2 other downloadable datasets usable in the demo entirely generated, cropped & converted in TerraLand:
Monument Valley (40km x 40km) terraunity.com/freedownload/MonumentValley.zip
Zion National Park (40km x 40km) terraunity.com/freedownload/Zion.zip
Just unzip them in the root folder of the build (TerraLand Offline Streaming_Data) and run the demo. Keep in mind that you have to backup other servers with the same folder name if exist before rewriting its contents.
Please note that the provided demo is just a technical overview of how the streaming system operates in the action and no artistic considerations are involved and generated environment is only a base for the world generation. Also the system will evolve in the coming versions and becomes more flexible and detailed in the future.
The TerraLand’s latest version is configured and updated to easily generate local servers for the area of interest usable in TerraLand’s Runtime Offline Streaming system and will be available in your terraunity.com/AssetStore accounts in the following days. More info and changes will be announced here upon release.
Hello,
Is there a way to drop a geo-referenced object into a terraland runtime scene? Previously you provided an example with a downloaded scene but I’m trying to do this within terraland runtime. I understand that the initial lat/lon is used as the 0,0,0 for the scene and I should just need an offset to apply to my latitude and longitude.
Thanks!
Good question, as already received several emails regarding the same scenario, here are some information and source code to get exact Lat/Lon coordinates in runtime.
TerraLand’s Runtime system is able to travel in possibly unlimited world sizes and this behavior needs floating point inaccuracies to be handled. For this we use a script on camera which offsets everything in the scene whenever camera gets to a certain distance from the scene origin at 0,0,0. Calculating the current Latitude/Longitude coordinates regardless of the occasional offsets is handled by a Vector3 in the following script.
Here is the full source code of the “FloatingOriginAdvanced” script in TerraLand Runtime which handles floating origin offsets on camera and contains a Vector3 var called “staticPosition” which returns a static seamless position of the player/camera regardless of any occurred offsets in the world.
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
[RequireComponent(typeof(Camera))]
public class FloatingOriginAdvanced : MonoBehaviour
{
public float distance = 100.0f;
public bool collectObjectsOnce = true;
public bool checkPhysics = true;
public float physicsDistance = 1000.0f;
public float defaultSleepThreshold = 0.14f;
private Transform cameraTransform;
private float distanceSqr;
private float physicsDistanceSqr;
private Object[] objects;
private static List<Object> gameObjects;
private static List<Object> physicsObjects;
public static Vector3 staticPosition;
public Vector3 worldOffset;
public bool originChanged = false;
void Start ()
{
cameraTransform = transform;
distanceSqr = Mathf.Pow(distance, 2f);
physicsDistanceSqr = Mathf.Pow(physicsDistance, 2f);
if(collectObjectsOnce)
CollectObjectsOnce();
staticPosition = transform.position;
}
void LateUpdate ()
{
ManageFloatingOrigin();
}
public void CollectObjectsOnce ()
{
gameObjects = new List<Object>();
gameObjects = FindObjectsOfType(typeof(Transform)).ToList();
if(checkPhysics)
{
physicsObjects = new List<Object>();
physicsObjects = FindObjectsOfType(typeof(Rigidbody)).ToList();
}
}
private void ManageFloatingOrigin ()
{
try
{
originChanged = false;
Vector3 cameraPosition = cameraTransform.position;
staticPosition = cameraTransform.position + worldOffset;
if(cameraPosition.sqrMagnitude > distanceSqr)
{
worldOffset += cameraTransform.position;
originChanged = true;
if(collectObjectsOnce)
{
foreach(UnityEngine.Object o in gameObjects)
{
Transform t = (Transform)o;
if (t.parent == null)
t.position -= cameraPosition;
}
}
else
{
objects = FindObjectsOfType(typeof(Transform));
foreach(UnityEngine.Object o in objects)
{
Transform t = (Transform)o;
if (t.parent == null)
t.position -= cameraPosition;
}
}
if(checkPhysics && physicsDistance > 0f)
{
if(collectObjectsOnce)
{
foreach (UnityEngine.Object o in physicsObjects)
{
Rigidbody r = (Rigidbody)o;
if (r.gameObject.transform.position.sqrMagnitude > physicsDistanceSqr)
r.sleepThreshold = float.MaxValue;
else
r.sleepThreshold = defaultSleepThreshold;
}
}
else
{
objects = FindObjectsOfType(typeof(Rigidbody));
foreach (UnityEngine.Object o in objects)
{
Rigidbody r = (Rigidbody)o;
if (r.gameObject.transform.position.sqrMagnitude > physicsDistanceSqr)
r.sleepThreshold = float.MaxValue;
else
r.sleepThreshold = defaultSleepThreshold;
}
}
}
}
}
catch{}
}
}
By having the static position from the origin, we can now calculate the current geo-coordinates of the camera position. Following is the class derived from the GameManager script in the WorldExplorer demo which I removed the unnecessary parts which returns current player Lat Lon position in the world.
// As requested here: https://discussions.unity.com/t/611457 page-8#post-3391209
// Here is the script to get Lat/Lon coordinates from camera position in runtime.
// All calculations are based on the assumption that each unit in Unity is euqual to 1 meter in real world space.
using UnityEngine;
using System;
public class RuntimeLatLon : MonoBehaviour
{
public GameObject worldGenerator;
private static Runtime runTime;
private static double earthRadius = 6378137;
private Vector3 realWorldPosition;
private double initialLat;
private double initialLon;
private double playerLat;
private double playerLon;
private Vector3 worldPosFromCoords;
public double destinationLat;
public double destinationLon;
public float destinationHeight = 3000f;
void Awake()
{
runTime = worldGenerator.GetComponent<Runtime>();
SetPlayer();
}
void Update()
{
GetLatLon();
GetWorldPosition();
}
public void SetPlayer()
{
if (MainMenu.latitude.Equals(""))
{
initialLat = double.Parse(runTime.latitudeUser);
initialLon = double.Parse(runTime.longitudeUser);
}
else
{
initialLat = double.Parse(Runtime.latitudeMenu);
initialLon = double.Parse(Runtime.longitudeMenu);
}
}
private void GetLatLon()
{
realWorldPosition = FloatingOriginAdvanced.staticPosition;
double offsetLat = (realWorldPosition.z / earthRadius) * 180 / Math.PI;
playerLat = initialLat + offsetLat; // Moving NORTH/SOUTH
double offsetLon = (realWorldPosition.x / (earthRadius * Math.Cos(Math.PI * playerLat / 180))) * 180 / Math.PI;
playerLon = initialLon + offsetLon; // Moving EAST/WEST
}
private void GetWorldPosition()
{
double destinationOffsetLat = destinationLat - initialLat;
double destinationOffsetLon = destinationLon - initialLon;
double worldPosZ = destinationOffsetLat * (Math.PI / 180) * earthRadius;
double worldPosX = (destinationOffsetLon * (earthRadius * Math.Cos(Math.PI * destinationLat / 180))) * Math.PI / 180;
worldPosFromCoords = new Vector3((float)worldPosX, destinationHeight, (float)worldPosZ);
}
void OnGUI()
{
GUI.backgroundColor = new UnityEngine.Color(0.3f, 0.3f, 0.3f, 0.3f);
GUI.Box(new Rect(10, Screen.height - 35, 220, 22), "Lat: " + playerLat.ToString("0.000000") + " Lon: " + playerLon.ToString("0.000000"));
GUI.Box(new Rect(250, Screen.height - 35, 420, 22), "Destination Point X: " + worldPosFromCoords.x.ToString("0.000") + " Y: " + worldPosFromCoords.y.ToString("0.000") + " Z: " + worldPosFromCoords.z.ToString("0.000"));
}
}
Hope it helps ![]()
I have updated the above script “RuntimeLatLon” to also have the reverse engineering of the GetLatLon function where we need to set a destination geo-point (Lat/Lon) to get the returned world position in Unity in order to do desired stuff like moving the player to that certain point.
Here’s the code snippet of the mentioned function:
private void GetWorldPosition()
{
double destinationOffsetLat = destinationLat - initialLat;
double destinationOffsetLon = destinationLon - initialLon;
double worldPosZ = destinationOffsetLat * (Math.PI / 180) * earthRadius;
double worldPosX = (destinationOffsetLon * (earthRadius * Math.Cos(Math.PI * destinationLat / 180))) * Math.PI / 180;
worldPosFromCoords = new Vector3((float)worldPosX, destinationHeight, (float)worldPosZ);
}
In order to show the flexibility, performance & customization of the Offline Streaming system plus utilizing TerraLand’s built-in tools, here is the rendering demo of high resolution 1 meter Lidar data from Alaska.
Download ALASKA Demo
http://terraunity.com/freedownload/TerraLandOfflineStreaming_1MeterLidar_Alaska.zip
Click on each image to see the animation
Demo Details
Controls:
Navigation: Arrow Keys/WASD
Move Up: “E”/Mouse Left Click
Move Down: “Q”/Mouse Right Click
Shift: Increase Speed
Alt: Decrease Speed
All movements are 3D Mouse simulated.
Total terrain surface in the demo is around 7x7 kilometers spread and resampled in a 8192 pixel resolution heightmap tiled into a 32x32 grid as 1024 heightmap tiles using “TerraLand Terrain” component. Each elevation tile is 257x257 pixels.
Active area around the player is a grid of 8x8 as 64 tiles covering approx. 1.7 km2 which is streamed dynamically while traveling.
No Satellite Images are used in the demo and the colors on terrain surface is procedurally generated using a custom terrain shader which involves a simple hack for texturing.
The original 1 meter Lidar TIN data is obtained from OpenTopography.
The purpose of this demo is to show the possibilities of TerraLand tools without even leaving Unity and to show the rendering power and the performance of the high resolution terrain surfaces in huge open world environments created by the Offline Streaming system in Unity.
The Lidar data is used as raw capturing of the point cloud data on the surface to contain all 3D features such as trees. The existing 3D features on the surface will give players a sense of scale and visual fidelity.
The existence of raw 3D features on the surface in the demo is similar to a basic version of Google Earth’s 3D Imagery technique.
TerraLand is not on Asset Store anymore, for buying?
You can buy TerraLand as before from our website here: http://terraunity.com/product/terraland/
TerraLand is deprecated in AssetStore in a temporary situation but may be back in the following days. However, this was intended as we are moving to TerraLand 3 with streaming features in place. More info will be revealed here soon.






