Spawning a prefab at a specific point in a procedurally generated map
So I am new to Unity and I was working through the tutorial on procedural cave generation (this one) and I've made it to the end. I would like to expand this into a small game where the player goes through an infinite series of levels but to do that I need to add a script that will make the player spawn inside of an open area. I wrote this method to do that and it is called when the map is generated.
void SpawnPlayer()
{
for (int x = 0; x < width; x++)
{
spawnLocationX = x;
for (int y = 0; y < height; y++)
{
spawnLocationY = y;
if (map[x, y] == 0)
{
if (playerCount == 0)
{
playerClone = Instantiate(player, new Vector4(spawnLocationX, -4, spawnLocationY, 0), Quaternion.identity);
playerCount = 1;
Debug.Log("Spawn Player");
return;
}
if (playerCount == 1)
{
player.position = new Vector4(spawnLocationX, 50, spawnLocationY, 0);
Debug.Log("Moveplayer");
return;
}
}
}
}
}
From my understanding this code should check every tile of the map, get the first x, y coordinates of the first open point and spawn the player there. Then the next time its called it should just move the already existing player prefab to the new open point.
However what is happening is the first time the map is generated the player spawns at (0, -4, 0) and every other time its called the player doesnt move at all. The debug that says moveplayer does get called when the player should be moved and I have run debugs that show the for loops are checking and returning the x,y values of open spaces.
I was wondering if anyone could explain how to get this to spawn the player in an appropriate location or if I'm going about this the completely wrong way.
Thanks!
Answer by LazyElephant · Dec 16, 2015 at 12:15 AM
The position of a game object is stored as a Vector3. You're trying to assign a Vector4 to it, which the compiler will do by just dropping the w value of the Vector4. It looks like you're confusing your arguments because of this. As it is, you're assigning the x position of your player correctly. The y value is being assigned to either -4 on the first instance or 50 if you're just moving an already existing one. Then the z position is being set to your spawnLocationY.
player.position = new Vector3(spawnLocationX, spawnLocationY, WhateverYourZValueIS);
Should be what you're looking for. I don't know what the -4 and 50 are supposed to represent in your Vector4s, so I wasn't able to take those into account.
Ok thank you so much! I was getting my vector arguments confused (I have no idea why I had 50 in there lol) This worked and it now moves the player everytime the map generates, however it doesnt always move the player to an open square about 10% of the time.. Is that an issue with my loop logic or should I look elsewhere in my code?
I don't see anything wrong with the loop code as long as map[width, height] == 0
means the space is empty. Could you post the new code so I can see what you changed?
The vectors are supposed to be arranged that way because the map is top down and -4 is the y value of the ground plane in the scene. I added the debugs for the x/y spawn positions to make confirm it was the player moving and not the map just changing and yes if the map == 0 it is empty.
//SPAWN PLAYER
void SpawnPlayer()
{
for (int x = 0; x < width; x++)
{
spawnLocationX = x;
for (int y = 0; y < height; y++)
{
spawnLocationY = y;
if (map[x, y] == 0)
{
if (playerCount == 0)
{
playerClone = Instantiate(player, new Vector3(spawnLocationX, -4, spawnLocationY), Quaternion.identity);
playerCount = 1;
Debug.Log("Spawn Player");
Debug.Log(spawnLocationX);
Debug.Log(spawnLocationY);
return;
}
if (playerCount == 1)
{
player.position = new Vector3(spawnLocationX, -4, spawnLocationY);
Debug.Log("$$anonymous$$ove player");
Debug.Log(spawnLocationX);
Debug.Log(spawnLocationY);
return;
}
}
}
}
}
I don't see anything in that code which would be causing the problem you described. I think the problem must be somewhere else. Are you sure the $$anonymous$$ap is always completely filled in before trying to spawn your player?
I changed the map generate method so it calls SpawnPlayer() last and that helped a lot. (I ran the generator script ~200 times and its down to about 5% spawning in walls. What I realized after that change is that it always spawns right on the wall which means its just spawning too close to the edge. I'm pretty confident I can rewrite part of the code that assigns wall outlines to fix it now! Thank you so much for all your help.
Your answer
Follow this Question
Related Questions
Spawning the player in a procedurally generated map 0 Answers
Instantiate And move the GameObject to the click position from another position. 1 Answer
FPS , Getting invalid AABB(I used animated machine gun that is available in unity asset) 0 Answers
Variable Becoming null only inside functions 2 Answers
Instantiate GameOBject with changing size in relation to another GameObject in the scene C# 0 Answers