I just purchased Unity Pro last night and I wanted to start on my game… but before I dive in I wanted to know, how do I go about making my scene stream in large terrains little at a time.
One suggestion is to separate the terrains into multiple smaller ones then enable them as you move along the world, I’m also trying to figure this out because I need to do this too so I’m not saying this is the right way to do it but it is an idea see if that works or you could do what they did with AssetBundleAPI and call it from your script as you move around by determining the position of your character or object,
if (Transform.position == Vector3(position))
{
//Load Terrain code
}
Also try asking eric or angry ant they’ll know the best answer.
Please do not tell people to pm me (or anyone else) like that. The forums are the appropriate venue for discussion of this nature. I haven’t done any terrain streaming so I don’t really know the answer.
There’s a mesh serialization example. I’m not sure if Unity supports consuming web services yet, but in C# you can do an async SOAP request to get terrain data, and serialize it to add it to your scene. That way it’ll work like MMORPG by streaming terrain and other content as you move about.
1 Dynamicly loading extra world “pieces”. (you can use Application.LoadAdditiveLevel(NUMBER/NAME))
2 Dynamicly downloading these pieces BEFORE using (streaming)
The way to code it is 2 → 1. But for you to get used to it: Try 1 first. Just create two scenes, and have a script in the first scene with loadadditivelevel(1). The contents of both scenes will be mixed together.
When you master that easy bit, stream the other scene via an assetbundle or so.
…now you have a streaming world. All what’s left is cleaning up old pieces of the world, etc.
Kool beans!! it’s starting to make much more sense.
So as for making the aligning the edges of my terrains for each scene … is that something I’ll have to do in code… or will SetNeighbor() work just fine?
I’m pretty comfortable with the loading part … my major concern is how will the engine know where to place this newly loaded scene.
As bloodtiger hinted at, if you don’t want to change scenes because you want the next terrain segment to be visible from the one you are on, you would in fact instantiate the next terrain tile when you are near the edge. Unity 2.1 does allow for multiple terrain objects in the same scene, and also allows positioning them randomly (2.0 didn’t allow either). This feature was added specifically for MMO/large seamless world support.
You would of course want to destroy the old terrain tile when you get far enough into the new one.
The niceties of whether the terrains are instantiated from prefabs, loaded from the Resources file, or streamed from an AssetBundle are a separate issue that depends on your deployment, memory footprint of the game, etc.
Like I said: try the loadadditivelevel and you’ll get it all right away.
It just adds the second scenes content in your current scene. So if that scenes terrain starts at x=200, and your first scenes terrain ends at 200, you’ll have a seamless(?) terrain of double the size.
I was working on this object right now myself. However, do note that tree colliders won’t properly work if you move a terrain from 0,0,0. The tree collision will keep its old spot. This bug has been submitted already.
don’t forget to link the terrains together through script (SetNeightbor), if you have several ones in your scene so the border handling works correctly.
if you have 2 terrains with different edge heights then you did something wrong because you would design the terrain as 1 large terrain.
not as multiple ones that just get “forced together”
Yes, I’ve seen your posts regarding using setNeighbor, but you neglected to realize that people actually want to stitch terrains together, not just adjust the normals.
private static void stitchEdge(int resolution, Terrain ter, Terrain left, Terrain top, Terrain right, Terrain bottom)
{ //modified this src: https://answers.unity.com/questions/26923/yet-another-terrain-seams-question.html
//this only needs to be called once and will change the terrain of current to match on edge the one to right and bottom.
//created another method to feather the edge if the difference is to much… or if the difference is greater along entire edge then lower every height in that terrain by the average difference.
float[,] newHeights = new float[resolution, resolution];
float[,] rightHeights = new float[resolution, resolution], bottomHeights = new float[resolution, resolution],
leftHeights = new float[resolution, resolution], topHeights= new float[resolution, resolution];
if (right != null)
rightHeights = right.terrainData.GetHeights(0, 0, resolution, resolution);
if (bottom != null)
bottomHeights = bottom.terrainData.GetHeights(0, 0, resolution, resolution);
if (left != null)
leftHeights = left.terrainData.GetHeights(0, 0, resolution, resolution);
if (top != null)
topHeights = top.terrainData.GetHeights(0, 0, resolution, resolution);
if (right != null || bottom != null || left!=null || top!=null)
{
//STITCH HEIGHTS TO RIGHT AND BOTTOM TERRAINS, also left and top now (which may be flat to return mountains to zero instead of hole on edge of terrain at the end of the world.
newHeights = ter.terrainData.GetHeights(0, 0, resolution, resolution);
for (int i = 0; i < resolution; i++)
{
if (right != null)
newHeights[i, resolution - 1] = rightHeights[i, 0];
if (bottom != null)
newHeights[0, i] = bottomHeights[resolution - 1, i];
if (left != null)
newHeights[i, 0] = leftHeights[i, resolution -1];
if (top!=null)
newHeights[resolution - 1, i] = topHeights[0,i];
}
ter.terrainData.SetHeights(0, 0, newHeights);
}
}
Threads for Unity 2.x should all get locked. If people need to discuss the contents of the old thread they should just create a new one and throw in a link to the old one.