So, Populous 3. Great game, but I really have no idea how to go about reproducing some of the spells in that game in Unity.
For people unfamiliar with the game, Populous 3 takes place on spherical worlds, and has a number of spells that can alter the terrain rather significantly. Here is a short video that exhibits all spells in the game.
So my main interest here is how you would achieve those spells that alter the terrain - Land Bridge, Flatten, Erode, Earthquake and Volcano (the names are rather descriptive).
I’ve looked around a bit, and I’ve found information on how to do a spherical world, and on how to alter a Terrain in realtime, but…Terrains aren’t spherical so… how would I go about doing something like this?
Well, I made a thing. It’s far from finished, but it gives me a pretty good starting point.
Using an icosphere (since I deform it, UV-sphere is a bad idea) ( I just use one I made in blender, don’t need to procedurally make it in Unity), I now have some code that can raise/lower the “terrain” around a point. It’s not much, but making it has given me enough insight that I think I can do the effects I want without too much problems from this point on. (Well, at least until I start trying to give it a texture. No idea how I am gonna do that…)
I’ll post the code I have and mark this as answered.
using UnityEngine;
using System.Collections;
//This script should be attached to the "world" icosphere.
public class AlterTerrain : MonoBehaviour {
//This should be an icosphere, no way to enforce it afaik though
public Mesh mesh;
public MeshCollider mcollider;
// Use this for initialization
void Start () {
mesh = GetComponent<MeshFilter>().mesh;
mcollider = GetComponent<MeshCollider>();
//just for testing, picking a random point that's close
//enough on the sphere
Raise(new Vector3(0,1,0), 0.2f, -0.1f);
}
//Lower or raise a point and the area around it
public void Raise(Vector3 point, float radius, float amount){
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
float radiusSqr = radius * radius;
for(int i = 0; i < vertices.Length; i++){
//vertex positions are in local space
Vector3 wpos = transform.TransformPoint(vertices*);*
float distanceSqr = (wpos - point).sqrMagnitude;*
//if it is in raiseterrain radius (is a sphere, this will give strange effect when radius is too large*
//for now a sphere is fine but should probably be changed to be in a circle*