Alright, so I’ve been having a bit of fun trying to recreate the Populous 3 ‘Volcano’ spell on a Unity terrain. Here’s a video of what those look like: Populous the Beginning - Volcanoes (HD) - YouTube. In comparison, here’s a video of what I’ve got so far: - YouTube.
Anyway, my current method has 2 major problems:
- I use a texture offset to give the idea that the lava is flowing, but that only goes in 1 direction. It looks really silly when you look at the back of the volcano and the lava appears to be flowing upwards.
- Updating the splatmap prototypes on a terrain is way too expensive. Terrain I’m using here only has 3 textures on it, adding more makes it even slower, and it already drops to like 12 fps.
There are also a few minor problems - I don’t make a ‘hole’ in the top, but I can do that easily enough (just didn’t feel like coding it in yet), - I cover my entire volcano in lava, instead of having a few ‘trenches’ (I haven’t really looked at doing that, yet, though) - and I’m not happy with how the lava-to-rock conversion goes, but that’s mostly because I haven’t really looked at what that should look like yet.
Here is my method for doing the lava flow as it looks now:
void LavaFlow(){
float percentageTimePassed = timePassed/flowTime;
for(int ix = 0; ix < texDiffX; ix++){
for(int iy = 0; iy < texDiffY; iy++){
float currentRadiusSqr = (textureCenter-new Vector2(ix, iy)).sqrMagnitude;
float radiusPercentage = currentRadiusSqr/radiusSqr;
if(radiusPercentage < percentageTimePassed*flowSpeed){
splatMap[iy,ix,lavaID] = 1f;
splatMap[iy,ix,groundID] = 1-splatMap[iy,ix,lavaID];
}
}
}
tData.SetAlphamaps(minTX,minTY, splatMap);
}
Method that turns te lava flow to rock is almost the same (actually, I should probably turn those into a single method and pass some parameters), it just changes different textures and starts later.
Oh, and the texture offset script for my lava is just this:
Terrain terrain;
SplatPrototype[] splats;
public Vector2 offsetSpeed;
// Use this for initialization
void Start () {
terrain = GetComponent<Terrain>();
splats = terrain.terrainData.splatPrototypes;
}
// Update is called once per frame
void Update () {
splats[1].tileOffset = splats[1].tileOffset + offsetSpeed * Time.deltaTime;
terrain.terrainData.splatPrototypes = splats;
}
But I should probably use something completely different instead.
Anyone have any suggestions on how to deal with the major problems I outlined?