For something like shown in the picture, you should create tileable meshes in a 3D editor. As the player moves, randomly select the next mesh and replace the older one as a child of the planet object. The trees and other details could also be randomly selected and childed to the meshes.
You could have segments corresponding to spherical wedges of about 90 degrees, for instance, like below:
[14002-wedges.png*_|14002]
Each new wedge could be a game object containing the mesh and with the details childed to it. The hierarchy could be as follows:
Planet
Wedge1
Tree1
Tree2
Rock1
Bush1
Wedge2
// wedge2 details
Wedge3
// wedge3 details
Wedge4
// wedge4 details
EDITED: If you want to use a simple sphere as the planet, things are easier. Paint a sphere with the path and the grass (you must create a suitable texture in an image editor), then rotate it when the player walks. Items like trees, rocks etc. may be created at Start and populate the planet near to the player. As the planet rotates and items pass the player, they may be “transplanted” to a new location ahead enough of the player.
The script below is an example on how to do this. The path region is delimited by the angle (-pathAngle…pathAngle) from the vertical, and the grass and items populate the region from (-grassAngle…grassAngle) from the vertical (path region excluded). When the up key is pressed, the planet rotates about X to simulate that the player is walking; as the planet rotates, items that pass the angle killAngle from the forward direction are moved to a new random position at bornAngle from the horizontal plane.
[14141-randomplanet.png*_|14141]
In order to use this script you must attach it to the player, then drag the planet object to planet, set radius to the radius of your planet and fill the prefabs array with the prefabs.
var planet: Transform; // drag the planet here
var radius: float = 20; // planet radius
var vel: float = 6; // player speed - degrees per second
var prefabs: Transform[]; // drag the item prefabs here
var qntItems = 30; // how many items populate the scene
var bornAngle: float = 0; // items born at this X angle
var killAngle: float = 90; // items disappear after this angle
var pathAngle: float = 10; // path angle from vertical
var grassAngle: float = 45; // end of grass angle from vertical
private var items: Transform[];
function Start () {
items = new Transform[qntItems];
// populate planet
for (var i=0; i<qntItems; i++){
// create a random item
var item = Instantiate(prefabs[Random.Range(0, prefabs.Length)]);
MoveItem(item, Random.Range(bornAngle, killAngle)); // move it to a random position
item.parent = planet; // child item to the planet
items *= item;*
function Update () {
- // rotate planet according to up/down arrow keys*
- var vAxis: float = Input.GetAxis(“Vertical”);*
_ planet.Rotate(-vAxisvelTime.deltaTime, 0, 0);_
- if (vAxis > 0.1){ // if moving…*
-
animation.CrossFade("walk"); // play "walk" animation*
- } else {*
-
animation.CrossFade("idle"); // else play "idle"*
- }*
- for (var i = 0; i < qntItems; i++){*
-
// if item passed the kill angle from Z axis...*
_ if (Vector3.Angle(items*.up, Vector3.forward) > killAngle){_
_ // replant it at the born angle, at random position*_
_ MoveItem(items*, bornAngle);
}
}
}*_
// Move item to a random position in the grass, at elevation angleX
function MoveItem(item: Transform, angleX: float) {
* var angleY: float;*
* if (Random.value < 0.5){ // randomly select left or right sides*
* angleY = Random.Range(-grassAngle, -pathAngle);*
* } else {*
* angleY = Random.Range(pathAngle, grassAngle);*
* }*
* // calculate new item up direction*
_ var dir = Quaternion.Euler(0, angleY, 0) * Vector3.forward;
dir = Quaternion.Euler(-angleX, 0, 0) * dir;
* // set item position and rotation*
item.position = planet.position + radius * dir;
* item.rotation = Quaternion.FromToRotation(Vector3.up, dir);
}*
EDITED2: This version includes random size, rotation and color for the world assets, and continuous pickup items generation. The pickups are generated at a 0 born angle, and with a separation of pickupAngle degrees: when the planet rotates pickupAngle from the born angle, a new pickup is generated. The pickups must be collected by the player, since the code doesn’t takes care of them after creation - if not collected and destroyed, they will crowd the path after a few turns:
var planet: Transform; // drag the planet here
var radius: float = 20; // planet radius
var vel: float = 6; // player speed - degrees per second
var prefabs: Transform[]; // drag the item prefabs here
var qntItems = 30; // how many items populate the scene
var bornAngle: float = 0; // items born at this X angle
var killAngle: float = 90; // items disappear after this angle
var pathAngle: float = 10; // path angle from vertical
var grassAngle: float = 45; // end of grass angle from vertical
var pickupPrefabs: Transform[]; // drag the pickup prefabs here
var pickupAngle: float = 7; // degrees between pickups
var pickupHeight: float = 1; // pickup height above ground_
private var items: Transform[];
private var lastPickup: Transform; // last pickup created
function Start () {
items = new Transform[qntItems];
// populate planet
for (var i=0; i<qntItems; i++){
// create a random item
var item = Instantiate(prefabs[Random.Range(0, prefabs.Length)]);
MoveItem(item, Random.Range(bornAngle, killAngle)); // move it to a random position
item.parent = planet; // child item to the planet
items = item;
}
lastPickup = CreatePickup();
}
function Update () {
// rotate planet according to up/down arrow keys
var vAxis: float = Input.GetAxis(“Vertical”);
if (vAxis > 0.1){ // if moving forward…
planet.Rotate(-vAxisvelTime.deltaTime, 0, 0); // rotate planet
animation.CrossFade(“walk”); // play “walk” animation
} else {
animation.CrossFade(“idle”); // else play “idle”
}
for (var i = 0; i < qntItems; i++){
// if item passed the kill angle from Z axis…
if (Vector3.Angle(items*.up, Vector3.forward) > killAngle){*
// replant it at the born angle, at random position
MoveItem(items*, bornAngle);*
}
}
if (Vector3.Angle(lastPickup.up, Vector3.forward) > pickupAngle){
lastPickup = CreatePickup();
}
}
// Move item to a random position in the grass, at elevation angleX
function MoveItem(item: Transform, angleX: float) {
var angleY: float;
if (Random.value < 0.5){ // randomly select left or right sides
angleY = Random.Range(-grassAngle, -pathAngle);
} else {
angleY = Random.Range(pathAngle, grassAngle);
}
// calculate new item up direction
var dir = Quaternion.Euler(0, angleY, 0) * Vector3.forward;
dir = Quaternion.Euler(-angleX, 0, 0) * dir;
// set item position and rotation
item.position = planet.position + radius * dir;
item.rotation = Quaternion.FromToRotation(Vector3.up, dir);
// set random size and rotation about Y
item.Rotate(0, Random.Range(0, 360), 0);
item.localScale = Random.Range(0.4, 1.5)*Vector3.one;
// set a random color
var rndColor: Vector4 = Random.insideUnitSphere;
var rndr = item.GetComponentInChildren(Renderer);
rndr.material.color = rndColor;
}
function CreatePickup(){ // create pickup in front of the planet
var pickup = Instantiate(pickupPrefabs[Random.Range(0, pickupPrefabs.Length)]);
pickup.parent = planet;
pickup.up = Vector3.forward;
pickup.position = planet.position + Vector3.forward * (radius + pickupHeight);
return pickup;
}
If some pickups may not be collected by the player, all pickups should have a script attached that would suicide them after passing back the player - something like this:
function Update(){ // destroy pickup when at more than 90 degrees from born angle:
if (Vector3.Angle(transform.up, Vector3.forward) > 90) Destroy(gameObject);
}
If one wants irregular spacing between pickups, a possible solution is to include a number of “empty pickups” in the pickupPrefabs array - empty objects with the suicide script above: they would do nothing but occupy the space of real pickups.
*
*