Hello All,
I am currently working on a procedural generated mobile game using unity2ds Sprite Shape Controller. There isn’t much as it regards to the API on explaining these classes.
I used some code I found online in a tutorial and edited it to work with closed sprite shapes(see below).
The goal is to have curved sprite shapes randomly generated as the level(of which I can do with some manipulation of values). However when in game view the sprite shape does not spawn/render ahead of time like it is suppose to. However if I zoom out in scene view while the game is running the sprite will spawn.
Is this an issue with unity rendering the sprite shape? Or am I missing something? I am not sure what BakeMesh() does is that the issue?
public class LevelSpawner : MonoBehaviour
{
public GameObject cell;
private GameObject[] cells;
private GameObject player;
private Vector3 rightSideOfContinousPlatform;
private GameObject currentPlatform;
private GameObject nextPlatform;
private Spline currentPlatformSpline;
private Spline nextPlatformSpline;
private EdgeCollider2D currentPlatformEdgeCollider;
private EdgeCollider2D nextPlatformEdgeCollider;
private int platNumber = 1;
public float rotation;
void Awake()
{
//Find the pre-existing spawn platform, and initialize current platform variables with respect to it.
player = GameObject.FindGameObjectWithTag("Player");
currentPlatform = GameObject.Find("Platform");
currentPlatformSpline = currentPlatform.GetComponent<SpriteShapeController>().spline;
currentPlatformEdgeCollider = currentPlatform.GetComponent<EdgeCollider2D>();
rightSideOfContinousPlatform = currentPlatform.transform.TransformPoint(currentPlatformSpline.GetPosition(currentPlatformSpline.GetPointCount() - 2));
}
void Update()
{
//Debug.Log(currentPlatformSpline.GetPointCount());
// Debug.Log(currentPlatformSpline.GetPosition(currentPlatformSpline.GetPointCount() - 1));
cells = GameObject.FindGameObjectsWithTag("Platform Clone");
foreach(GameObject c in cells)
{
c.transform.position = new Vector3(c.transform.position.x, c.transform.position.y, 10);
}
//If the player is approaching the right end of the level, spawn a new platform.
if (rightSideOfContinousPlatform.x - player.transform.position.x < 200f)
{
spawnRightPlatform();
}
foreach(GameObject c in cells)
{
if(c.transform.position.x + 50 < player.transform.position.x)
{
Destroy(c);
}
}
//TODO: If the player is approaching the left end of the level, spawn a new platform.
}
void spawnRightPlatform()
{
//Decide what platform template to use randomly.
//int randomCell = Random.Range(0, cells.Length);
//Pick point far to the right to place the platform, this will be adjusted in the same frame.
Vector3 placeLocation = rightSideOfContinousPlatform + new Vector3(0f, 0, 0);
//Spawn the platform at placeLocation
nextPlatform = Instantiate(cell, placeLocation, Quaternion.identity);
//Setup the GameObjects & Components needed for this function, based off the spawned platform
GameObject nextPlatformSS = nextPlatform;
SpriteShapeController nextPlatformSSC = nextPlatformSS.GetComponent<SpriteShapeController>();
nextPlatformEdgeCollider = nextPlatformSS.GetComponent<EdgeCollider2D>();
nextPlatformSpline = nextPlatformSSC.spline;
nextPlatformSSC.RefreshSpriteShape();
//Retrieve the width of the new platform, and adjust the positioning accordingly. 10 is added to the x spacing to prevent sharp turns. (adjustable)
float platWidth = nextPlatformSS.GetComponent<SpriteShapeRenderer>().bounds.size.x;
Vector3 correctLocation = rightSideOfContinousPlatform + new Vector3((platWidth / 2) + 10, 0, 0);
nextPlatform.transform.position = correctLocation;
//Find the ends of the platforms. Vector 3rightSideOfCurrentPlatform is already specified from previous iteration.
Vector3 leftSideOfNextPlatform = nextPlatformSpline.GetPosition(0);
Vector3 left = nextPlatform.transform.TransformPoint(leftSideOfNextPlatform);
Vector3 right = currentPlatform.transform.TransformPoint(currentPlatformSpline.GetPosition(currentPlatformSpline.GetPointCount() - 1));
//Find the midpoint between the two ends.
Vector3 midpoint = new Vector3((left.x + right.x) / 2f,
((left.y + right.y) / 2), 0);
//Brings the two end points on the colliders to the midpoint.
Vector2[] currentColliderPoints = currentPlatformEdgeCollider.points;
currentColliderPoints[currentColliderPoints.Length - 1] = currentPlatform.transform.InverseTransformPoint(midpoint);
currentPlatformEdgeCollider.points = currentColliderPoints;
Vector2[] nextColliderPoints = nextPlatformEdgeCollider.points;
nextColliderPoints[0] = nextPlatform.transform.InverseTransformPoint(midpoint);
nextPlatformEdgeCollider.points = nextColliderPoints;
currentPlatformSpline.SetPosition(currentPlatformSpline.GetPointCount() - 2,
currentPlatform.transform.InverseTransformPoint(midpoint + new Vector3(0, 10, 0)));
//Brings the two end points of the spline together. Either side is visually adjusted to overlap .25, to avoid gaps. (adjustable)
currentPlatformSpline.SetPosition(currentPlatformSpline.GetPointCount() - 1, currentPlatform.transform.InverseTransformPoint(midpoint + new Vector3(0, 5, 0)));
nextPlatformSpline.SetPosition(0, nextPlatform.transform.InverseTransformPoint(midpoint + new Vector3(2f, 5, 0)));
//adding 10 to the top
nextPlatformSpline.SetPosition(1, nextPlatform.transform.InverseTransformPoint(midpoint + new Vector3(0f, 10, 0)));
//nextPlatformSpline.SetPosition(nextPlatformSpline.GetPointCount() - 2,
//nextPlatform.transform.InverseTransformPoint(nextPlatformSpline.GetPosition(nextPlatformSpline.GetPointCount() - 1) + new Vector3(0, 5, 0)));
//add middle splint point
Vector3 leftPoint = nextPlatformSpline.GetPosition(1);
Vector3 rightPoint = nextPlatformSpline.GetPosition(nextPlatformSpline.GetPointCount() - 2);
Vector3 middlePoint = new Vector3((leftPoint.x + rightPoint.x) / 2, (leftPoint.y + rightPoint.y)/2, 0);
//insert middle spline point
nextPlatformSpline.InsertPointAt(2, middlePoint);
nextPlatformSpline.SetTangentMode(2, ShapeTangentMode.Continuous);
nextPlatformSpline.SetLeftTangent(2, new Vector3(1,1,0) * rotation);
nextPlatformSpline.SetRightTangent(2, new Vector3(-1,-1,0) * (rotation * -1));
//Renames the new platform, and moves the newly generated platform into the 'Current Platform' variables
nextPlatform.name = "Plat" + platNumber;
nextPlatform.tag = "Platform Clone";
rightSideOfContinousPlatform = nextPlatform.transform.TransformPoint(nextPlatformSpline.GetPosition(nextPlatformSpline.GetPointCount() - 1));
currentPlatformEdgeCollider = nextPlatformEdgeCollider;
currentPlatformSpline = nextPlatformSpline;
currentPlatform = nextPlatform;
platNumber++;
nextPlatform = null;
}
}