Hey guys, I am new to unity and trying to do a 2D Endless Runner Game. I wrote a spawner but it spawns obstacles in the same spot. Spawner(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public Transform[ ] spawnPoint;
public GameObject[ ] enemyPrefabs;
// Start is called before the first frame update
void Start()
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randEnemy], spawnPoint[0].position, transform.rotation);
}
// Update is called once per frame
void Update()
{
}
}
)
I have a obstacle movement code too but when i add it to spawner it changes spawn position but i need to do spawn and than obstackle slide left Obstacle move(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Double : MonoBehaviour
{
public float speed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
}
)
Can you guys help me 
Can you edit your post and copy/paste the code using code tags? It will make it much easier for others to view and in turn, help you.
1 Like
I could only find edit title so i reply with code tags. Thank you 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public Transform[] spawnPoint;
public GameObject[] enemyPrefabs;
// Start is called before the first frame update
void Start()
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randEnemy], spawnPoint[0].position, transform.rotation);
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Double : MonoBehaviour
{
public float speed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
}
So you are instantiating the enemies all at spawnPoint[0].position. Which means the first index of the array. You need to do a random.range for that number inbetween the to make it vary. Do it the same way as the randEnemy but for the spawnPosition.
I think i did it wrong. I want them to spawn at the same point(outside of the screen) and slide to the player to jump over them like dino game in browser.
Ah gotcha, then that makes sense. Spawn them in one spot and then have them move towards the player. Is that not working now?
Yep. Spawn point is moving not the obstacles.
I did it with this code finally.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OSpawner : MonoBehaviour
{
public Transform[] spawnPoint;
public GameObject[] enemyPrefabs;
public float speed;
public float maxTime = 1;
private float timer = 0;
// Start is called before the first frame update
void Start()
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randEnemy], spawnPoint[0].position, transform.rotation);
}
// Update is called once per frame
void Update()
{
if (timer > maxTime) {
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randEnemy], spawnPoint[0].position, transform.rotation);
transform.position += Vector3.left * speed * Time.deltaTime;
timer = 0;
}
timer += Time.deltaTime;
}
}
And i add Move script to the Obstacles prefabs.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
}
But i have a new problem :)))
I have a 3 obstacles. Obstacle 1 is cactus and a cloud you need to jump between them. Obstacle2 and 3 is just cactus. When i select spawn point y=0 first image happens(Obstacle1 spawns underground)
and when i move spawn point y=1.85 image2 happens(Obstacle2 and 3 fly)
I understand i need to do 2 spawn points and if Obstacle1 spawns spawn point needs to be in y = 1.85 location and Obstacle 2,3 spawn point needs to be in y=0 location but i dont know how can i do that
Well since you have objects in the air and on the ground, i would just duplicate the code and have one for instantiating ground objects and one for air. That way the objects will spawn at their proper Y locations, regardless of being on the ground or air. Then you can have the functions alternate via spawn time so they dont spawn at the same time.
Yeah makes sense. I will do it but i am gonna try to do it in 1 code and keep looking here for answers until i finish the game. It doesnt feel right when you can do something it in 1 code but do it in 2. If i cant find how to do it i will complete it like you said. Thank you for your answers 
I think i understand your thought process, but just know you dont need to use 2 scripts. You just need 2 functions within the same script. Of course you can do it in one function but it may get a bit hairy to debug. That way if there is an issue with the ground spawning, you dont have to mess up the air spawning.
Something like this:
void Start()
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randEnemy], spawnPoint[0].position, transform.rotation);
}
// Update is called once per frame
void Update()
{
SpawnGround();
SpawnAir();
}
void SpawnGround()
{
if (timer > maxTime)
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[groundEnemy], spawnPoint[0].position, transform.rotation);
transform.position += Vector3.left * speed * Time.deltaTime;
timer = 0;
}
timer += Time.deltaTime;
}
void SpawnAir()
{
if (airTimer > maxTime)
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[airEnemy], airSpawnPoint[0].position, transform.rotation);
transform.position += Vector3.left * speed * Time.deltaTime;
timer = 0;
}
airTimer += Time.deltaTime;
}
Note, this code was just briefly created, you will have to make some tweaks and changes, but the point hopefully sticks out.
I get the idea of your code. I will work on this to adapt my project. Thanks 
1 Like
Hi, me again
I did it. Its spawning correctly with this code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObSpawner : MonoBehaviour
{
public Transform[] spawnPoints;
public GameObject[] enemyPrefabs;
public float speed;
public float maxTime = 1;
private float timer = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
SpawnGround();
SpawnAir();
}
void SpawnGround()
{
if (timer > maxTime)
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[0], spawnPoints[0].position, transform.rotation);
transform.position += Vector3.left * speed * Time.deltaTime;
timer = 0;
}
timer += Time.deltaTime;
}
void SpawnAir()
{
if (timer > maxTime)
{
int randEnemy = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[1], spawnPoints[1].position, transform.rotation);
transform.position += Vector3.left * speed * Time.deltaTime;
timer = 0;
}
timer += Time.deltaTime;
}
}
Btw do you know how can i destroy past obstacles? When i try to do like [Destroy(enemyPrefabs,10);] i get this error.
Assuming you’re trying to destroy the GameObject at index 10 of the array “enemyPrefabs,” try Destroy(enemyPrefabs[10]);
I recommend learning about Object Pooling for this. It is a great tool to have in your belt and will help with performance in the long run. It is something indies to AAA studios use. Just destroying gameobjects doesn’t help if the game/scene is running for a while.
For an immediate answer, i would just have them disappear as soon as they are out of range of the camera or after a certain amount of time. But this isnt as performant as the object pool approach i mentioned.
Thank you very much i asked a lot sorry 
