- Home /
How to generate random borders with collider?
(I attached a photo) In a 2D game, How to generate this kind of random curved borders with polygon collider on it? Please guide me. Provide any helpful links to follow. What are the programming concepts and procedures that is required create this random generation? I am a beginner
Answer by Aeleck · Aug 09, 2017 at 08:33 PM
Using the Polygon collider will be fairly easy for you. You will need access to the points in a script and dynamically update them. There are two approaches I see that could be beneficial. One is where you move the player to the right, adding a point between the outside corner of the border and the actual farthest right point of the border that is on the inside of the border, effectively replacing the farthest to the right point on the screen and removing the point that is the farthest left closest to the player (which for your sake you can make it index 0 in the point list) and simply remove it.Now as far as editing the list and putting these in the right places can be kind of unpleasant so what I would do is not rearrange or insert any new vertices. Simple put two points for the side away from the inside border as just two corners, then load the edge towards the player with however many vertices you want (the amount depends on how smooth/sharp you want the border to be). Once you have the points, your script can be much more simple and you can adjust the one vertice that is at the far end of the inner border, change it based on algorithm, or otherwise, and simply pass the data back through the other points like below
// only need to adjust y (or whatever vector is up and down for you)
points[points.length - 1].y = calculateNewBorderPosition(); // function you make to generate more border
// Then shift all the positions back
for (int p = 0; p < points.length - 1; p++)
points[p] = points[p + 1];
And this will fake that the player is moving forward, note though, that you will need to create a timer that after a certain amount of time has passed, generate a new point, and shift all back, that way it's not every frame.
Since this may be hard to visualize, I did my best.
Here is what script I came up with:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BorderGenerator : MonoBehaviour
{
PolygonCollider2D _polCol;
// we use a distance value instead of time in order to make it easier to sync other objects that may be moving "with" the border
public float moveSpeed = 1f;
// amount to simulate over time (faux distance)
// The local Y of each point, used as a center value (existing polygon collider created so center is 0 local space (see image)
public float borderLocalHeight = 0f;
// The amount of distance the border will vary from its center
public float borderDeltaDistance = 0.1f;
// keep track of our distance so that we generate appropiatley
float currDistance = 0f;
void Awake ()
{
_polCol = GetComponent <PolygonCollider2D> ();
}
// Update is called once per frame
void Update ()
{
// get the distance between the last two points (closest to the generation edge) to know how far we need to go before making a new point
// Note: the distance is gotten in local space, if the border were to be scaled from the transform, these values will not change
float targetDistance = _polCol.points [_polCol.points.Length - 1].x - _polCol.points [_polCol.points.Length - 2].x;
// "move" how far we should move this frame
currDistance += moveSpeed * Time.deltaTime;
// we are far enough long in time to "make" a new point
if (currDistance >= targetDistance)
{
// first get all the points of the path
Vector2[] points = _polCol.GetPath (0);
// pass all existing y values back (starting at 2, to ignore the two top corners of the border away from the player
for (int v = 2; v < points.Length - 1; v++)
points [v].y = points [v + 1].y;
// Then create the new height of the new border
points [points.Length - 1].y = borderLocalHeight + Mathf.Sin (Time.time) * borderDeltaDistance;
// and reassign the positions
_polCol.SetPath (0, points);
// and lastly subtract our distance from our current distance as to keep the scaling correct
currDistance -= targetDistance;
}
}
}
This creates this effect with the PolygonCollider:
As you can see the bottom points are being moved up and down, but this can be used to create a movement too. Position another one with the same script, scale its y to be -1 and boom you have yourself a tunnel. The Mathf.Sin line is where you would write your algorithm for what kind of border you wanted it to generate (smooth rolling, jagged, etc) which you would need to decide what you wanted on. Sin and Cos functions are great for smooth effects like this.
And lastly here is my PolygonCollider settings so you can see how I set it up. The first two points on the list are the top left and top right corners so that I didn't have to worry about them being in the way when I cycled through and adjusted the heights. I hope this helped!