Ok, Working in Unity here and trying to get out this core game dynamic. Basically I have all these 3D platforms that have certain weights to them (weight meaning how often they appear in the array from which game can select next platform) -
right now each platform has a set of the 4 cardinal directions (plus up/down but all have those) where it can spawn the next platform for player to walk onto, else they fall. This is an enum and I set this manually.
Before player first steps on a platform, it is halfway alpha, so it just looks like a marker. After they step, it turns 1 alpha and thus doesn't look like a "marker", see here:
As the player walks via joystick, I want the platforms to spawn in square "tiers" - say of length 10 platforms - and I'll do something when tier is full. My problem is I've tried a bunch of different systems but do not know how to implement this. Model picture where there are different configurations but ultimately a 10x10 limit/bounds:
Here's my method of spawning based on direction - problem is direction is subjective, based on player object's point of view:
foreach(Direction d in directionsAvailable)
{
Vector3 pos = transform.position;
float dist = container.GetComponent<Renderer> ().bounds.size.x;
switch (d) {
case Direction.Backward:
pos = new Vector3 (pos.x, pos.y, pos.z-dist);
break;
case Direction.Forward:
pos = new Vector3 (pos.x, pos.y, pos.z+dist);
break;
case Direction.Left:
pos = new Vector3 (pos.x-dist, pos.y, pos.z);
break;
case Direction.Right:
pos = new Vector3 (pos.x+dist, pos.y, pos.z);
break;
case Direction.Down:
pos = new Vector3 (pos.x, pos.y-(2*dist), pos.z);
break;
case Direction.Up:
pos = new Vector3 (pos.x, pos.y+(2*dist), pos.z); //hits itself, might have to do more dist
break;
default:
break;
}
Here is how I test if a platform is at a position or position is open:
public Platform PlatAtPos(Vector3 pos)
{
platformsSpawned = GameObject.FindObjectsOfType<Platform>();
foreach(Platform p in platformsSpawned)
{
if(p.originPos == pos || p.transform.position == pos) //or just delete one of them
{
return p;
}
}
return null;
}
public void checkForPlatsAround()
{
gameController = GameObject.FindObjectOfType<GameController> ();
float dist = container.GetComponent<Renderer> ().bounds.size.x;
foreach (Platform.Direction dir in Enum.GetValues(typeof(Platform.Direction))) {
Vector3 pos = transform.position;
switch (dir) {
case Direction.Backward:
pos = new Vector3 (pos.x, pos.y, pos.z-dist);
break;
case Direction.Forward:
pos = new Vector3 (pos.x, pos.y, pos.z+dist);
break;
case Direction.Left:
pos = new Vector3 (pos.x-dist, pos.y, pos.z);
break;
case Direction.Right:
pos = new Vector3 (pos.x+dist, pos.y, pos.z);
break;
case Direction.Down:
pos = new Vector3 (pos.x, pos.y-(2*dist), pos.z);
break;
case Direction.Up:
pos = new Vector3 (pos.x, pos.y+(2*dist), pos.z); //hits itself, might have to do more dist
break;
default:
break;
}
if(gameController.PlatAtPos(pos) != null)
{
gameController.PlatAtPos (pos).showAsMarker ();
}
}
}
Is there a better/clearer way to go about this? How can I do this procedurally?