Spawning and destroying random platforms in unity - c#

I am trying to make a doodle jump game in unity for fun and I have a question.
How could I change my script to spawn other platforms on top and destroy any platform that is under main camera.I'll let down my code for spawning random platforms
public class GradinariuZAHAR : MonoBehaviour
{
public Transform Player;
public GameObject platformPrefab;
private float minimY = 0.2f;
private float maximY = 1.6f;
public int numberOfPlatforms = 200;
public float levelWidth = 3f;
// Use this for initialization
void Start()
{
GenerateChunk(.2f, 1.5f);
}
void GenerateChunk(float minY, float maxY)
{
Vector3 spawnPosition = new Vector3(0f, 0f, 0f);
for (int i = 0; i < numberOfPlatforms; i++)
{
spawnPosition.y += Random.Range(minY, maxY);
spawnPosition.x = Random.Range(-levelWidth, levelWidth);
Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
}
}
void Update()
{
if (Player.position.y > 160) {
Debug.Log("acum");
minimY = maximY;
maximY = maximY * 2;
GenerateChunk(minimY, maximY);
}
}
}

Just attach the following script to your platform. It'll destroy the platform once its entire sprite is completely below the camera, exactly how you want it.
using UnityEngine;
public class Platform : MonoBehaviour
{
SpriteRenderer sprite;
float bottomOfScreen;
private void Start()
{
sprite = GetComponent<SpriteRenderer>();
var cam = Camera.main;
var screen = new Vector2(Screen.width, Screen.height);
var camWorldPos = cam.ScreenToWorldPoint(screen);
bottomOfScreen = camWorldPos.y - cam.orthographicSize * 2;
}
private void Update()
{
var height = sprite.bounds.size.y;
var topOfPlatform = transform.position.y + height / 2;
if (topOfPlatform < bottomOfScreen)
Destroy(gameObject);
}
}

Related

How to make enemies not spawn on/too close to player. C#

I'm making a "player fish eats smaller fish and grows" game as practice. But I'm struggling with making the npc fish not spawn on or too close to the player.
This is the code for the spawner, atm fish can still spawn on the player.
public class Spawner : MonoBehaviour
{
public GameObject[] itemsToPickFrom;
public int numberToSpawn;
float placeX;
float placeY;
float minDistance;
void Start()
{
Spawn();
minDistance = 5f;
}
void Spawn()
{
for (int i = 0; i < numberToSpawn; i++)
{
int randomIndex = Random.Range(0, itemsToPickFrom.Length);
placeX = Random.Range(-10f, 9f);
placeY = Random.Range(-4f, 4f);
while (Vector2.Distance(GameObject.FindGameObjectWithTag("Player").transform.position, new Vector3(placeX, placeY, 0)) < minDistance)
{
placeX = Random.Range(-10f, 9f);
placeY = Random.Range(-4f, 4f);
}
Instantiate(itemsToPickFrom[randomIndex], new Vector3(placeX, placeY, 0), quaternion.identity);
}
}
I guess it's Unity, if so numberToSpawn is probably set on the editor interface, so it shouldn't be a problem.
The issue I can see is that you set minDistance after Spawn().
void Start()
{
Spawn();
minDistance = 5f;
}
If you set minDistance before Spawn(), it could be correct. The other logics seems correct at least.
float minDistance = 5f;
void Start()
{
Spawn();
}

Spawn image at random position in canvas

I have a canvas and inside it a panel. I want to spawn different image UI object at random position inside my panel (on screen). I took x and y min and max limits of the panel in order to generate a random position (withing these limts) but the problem is object are not instantiating at desired position. This is my code.
public class ImageSpawnerScreen : MonoBehaviour {
public float waitTime = 2;
public float cubeSpawnTotal = 10;
public List<GameObject> cubePrefabList;
float xPosMinLimit = -347;
float xPosMaxLimit = 340;
float yPosMinLimit = -458f;
float yPosMaxLimit = 450f;
public GameObject panel;
void Start()
{
StartCoroutine(SpawnCube());
}
IEnumerator SpawnCube()
{
for (int i = 0; i < cubeSpawnTotal; i++)
{
GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
//Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height))); //Random.Range(xPosMinLimit, xPosMaxLimit);
float xPos = Random.Range(xPosMinLimit, xPosMaxLimit);
float yPos = Random.Range(yPosMinLimit, yPosMaxLimit);
Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
spwanObj.transform.parent = panel.transform;
spwanObj.transform.position = spawnPosition;
yield return new WaitForSeconds(waitTime);
}
}
}
I checked instantiated object positions are far away from the given random range position. What I am doing wrong? I think it is Rect Transform so i have to set its position differently.
Indeed, you need to use RectTransform inside a Canvas.
You also don't need the -1 for you List.Count. Check the link in the comment below.
I think the following script will do what you are looking for:
public class ImageSpawnerScreen : MonoBehaviour
{
public float waitTime = 2;
public float cubeSpawnTotal = 10;
public List<GameObject> imagesList;
public RectTransform panel;
void Start()
{
StartCoroutine(SpawnImage());
}
IEnumerator SpawnImage()
{
for (int i = 0; i < cubeSpawnTotal; i++)
{
GameObject imageToSpawn = imagesList[Random.Range(0, imagesList.Count)]; // Remove -1 after count since is exclusive for int (https://docs.unity3d.com/ScriptReference/Random.Range.html)
Vector3 spawnPosition = GetBottomLeftCorner(panel) - new Vector3(Random.Range(0, panel.rect.x), Random.Range(0, panel.rect.y), 0);
print("Spawn image at position: " + spawnPosition);
GameObject spwanObj = Instantiate(imageToSpawn, spawnPosition, Quaternion.identity, panel);
yield return new WaitForSeconds(waitTime);
}
}
Vector3 GetBottomLeftCorner(RectTransform rt)
{
Vector3[] v = new Vector3[4];
rt.GetWorldCorners(v);
return v[0];
}
}
Let me know if you need more explanations.
To manage Canvas object's position you should definitely use RectTransform instead of regular transform. In your case you have to do something like :
m_RectTransform = GetComponent<RectTransform>();
As for setting position - coordinates you see on the object inside Canvas is not .position but RectTransform.anchoredPosition, so you should use it in your code. Here is an official documentation on anchoredPosition.
public class ImageSpawnerScreen : MonoBehaviour {
public float waitTime = 2;
public float cubeSpawnTotal = 10;
public List<GameObject> cubePrefabList;
public GameObject panel;
void Start()
{
StartCoroutine(SpawnCube());
}
IEnumerator SpawnCube()
{
for (int i = 0; i < cubeSpawnTotal; i++)
{
GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
//Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height))); //Random.Range(xPosMinLimit, xPosMaxLimit);
float xPos = Random.Range(0, Screen.width);
float yPos = Random.Range(0, Screen.height);
Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
spwanObj.transform.parent = panel.transform;
spwanObj.transform.position = spawnPosition;
yield return new WaitForSeconds(waitTime);
}
}
}
This should help u out.

How to do 2D Random Platform Spawner without colliding on top of each other?

I am creating a simple 2D platform game where the player will be jumping upwards in an infinite mode. Something like Doodle Jump! I am currently trying to make a breakable platform and a normal one but I have been having some problems spawning 2 different platforms at once. I did this code below and it seems to have 2 of the platforms colliding on top of each other
using UnityEngine;
using System.Collections;
public class PlatformSpawner : MonoBehaviour{
[SerializeField]
GameObject PlatformPrefab;
public float radius = 0f;
[SerializeField]
GameObject PlayerPrefab;
[SerializeField]
CameraFollow cameraScript;
[SerializeField]
GameManager gameManagerScript;
BoxCollider2D playerBoxCol2d;
public float topPlatformYPos = 0;
void Start(){
SpawnPlatformStart();
SpawnBreakPlatformStart();
}
/*This is the Platform Spawner when start */
void SpawnPlatformStart(){
float yPos = -4f;
float xPos = 0f;
GameObject playerGo = Instantiate (PlayerPrefab, Vector3.zero, Quaternion.identity) as GameObject;
playerBoxCol2d = playerGo.GetComponent<BoxCollider2D> ();
for (int i = 0; i < 6; i++) {
xPos = Random.Range (-2f, 2f);
GameObject platformGo = Instantiate (PlatformPrefab, new Vector3 (xPos, yPos, 0f), Quaternion.identity) as GameObject;
cameraScript.player = playerGo.transform;
if (i <= 0) {
playerGo.transform.position = new Vector3 (xPos, yPos + 1f, 0f);
}
Platform platformScript = platformGo.GetComponent<Platform> ();
GetComponentForPlatformScript (platformScript);
topPlatformYPos = yPos;
yPos += 2f;
}
}
/*This is the different Platform to spawn */
void SpawnBreakPlatformStart(){
float yPos = -20f;
float xPos = f;
for (int i = 0; i < 6; i++) {
xPos = Random.Range (6f, -3f);
GameObject platformGo = Instantiate (BreakPlatformPrefab, new Vector3 (xPos, yPos, 0f), Quaternion.identity) as GameObject;
Platform platformScript = platformGo.GetComponent<Platform> ();
GetComponentForPlatformScript (platformScript);
topPlatformYPos = yPos;
yPos += 4f;
}
}
void GetComponentForPlatformScript(Platform _platformScript){
_platformScript.playerBoxCollider2d = playerBoxCol2d;
_platformScript.PlatformSpawnerScript = this;
_platformScript.cameraTrans = cameraScript.gameObject.transform;
}
void GetComponentForPlayerScript(PlayerController _playerScript){
_playerScript.cameraTrans = cameraScript.gameObject.transform;
_playerScript.gameManagerScript = this.gameManagerScript;
}
}

How to spawn enemy at random intervals?

I am using EnemyScript to move the enemy towards the player and killing the player, but I'm unable to spawn it randomly in code. I am currently spawning it directly through screen by placing the prefab on the scene.
Here is my EnemyScript
using UnityEngine;
using System.Collections;
public class EnemyScript : MonoBehaviour {
public Transform target;
public float speed = 2f;
void Update ()
{
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
void OnTriggerEnter2D(Collider2D otherCollider)
{
PlayerControl shot = otherCollider.gameObject.GetComponent<PlayerControl>();
if (shot != null)
{
Destroy(shot.gameObject);
}
}
}
you could use something similar to this:
public GameObject myObj;
void Start ()
{
enemy = GameObject.Find("enemy");
InvokeRepeating("SpawnEnemy", 1.6F, 1F);
}
public void SpawnEnemy()
{
Vector3 position = new Vector3(Random.Range(35.0F, 40.0F), Random.Range(-4F, 2F), 0);
Instantiate(myObj, position, Quaternion.identity);
}
in the InvokeRepeating call you could possibly add the random range there also instead of a timed instantiate. This example is just a snippet of some prototype code i did a while ago, it may not suit your needs directly but hopefully will give you a general idea on what to do.
EDIT: to make sense, put this into a blank object somewhere in your scene, dont attach this to the actual enemy.
i programmed it like this.
public GameObject enemyPrefab;
public float numEnemies;
public float xMin = 20F;
public float xMax = 85F;
public float yMin = 3.5F;
public float yMax = -4.5F;
void Start () {
for (int i=0; i< numEnemies; i++) {
Vector3 newPos = new Vector3(Random.Range(xMin,xMax),Random.Range(yMin,yMax),0);
GameObject enemy = Instantiate(enemyPrefab,newPos,Quaternion.identity) as GameObject;
}
}
This will spawn a random number of enemies, at random locations, after random periods of time, all adjustable in the Inspector.
public float minTime = 1;
public float maxTime = 3;
public int minSpawn = 1;
public int maxSpawn = 4;
public Bounds spawnArea; //set these bounds in the inspector
public GameObject enemyPrefab;
private spawnTimer = 0;
Vector3 randomWithinBounds(Bounds r) {
return new Vector3(
Random.Range(r.min.x, r.max.x),
Random.Range(r.min.y, r.max.y),
Random.Range(r.min.z, r.max.z));
}
void Update() {
spawnTimer -= Time.deltaTime;
if(spawnTimer <= 0) {
spawnTimer += Random.Range(minTime, maxTime);
int randomSpawnCount = Random.Range(minSpawn, maxSpawn);
for(int i = 0; i < randomSpawnCount; i++) {
Instantiate(transform.transformPoint(enemyPrefab), randomWithinBounds(spawnArea), Quaternion.identity);
}
}
}
//bonus: this will show you the spawn area in the editor
void OnDrawGizmos() {
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.color = Color.yellow;
Gizmos.drawWireCube(spawnArea.center, spawnArea.size);
}
People on here seem to like using coroutines for time delays, but I personally prefer to track my own timers in Update() to maximize control and predictability.

Enemy Random Spawn

I am making my first Unity game and I decided to make a 5 level shooter for mobile. I have made a random spawn script for my enemies, but the spawn is too frequent and generates too many at once.
Here is the script:
using UnityEngine;
using System.Collections;
public class CreateRandomOctodeamons : MonoBehaviour {
public GameObject enemyPrefab;
public GameObject enemyPrefab1;
public float numEnemies;
public float xMin = 19F;
public float xMax = 85F;
public float yMin = 3.5F;
public float yMax = -4.5F;
void Start () {
GameObject newParent = GameObject.Find("1-background elements");
for (int i = 0; i < numEnemies; i++)
{
Vector3 newPos = new Vector3(Random.Range(xMin, xMax), Random.Range(yMin, yMax), 0);
GameObject octo = Instantiate(enemyPrefab, newPos, Quaternion.identity) as GameObject;
octo.transform.parent = newParent.transform;
Vector3 newPos1 = new Vector3(Random.Range(xMin, xMax), Random.Range(yMin, yMax), 0);
GameObject octo1 = Instantiate(enemyPrefab1, newPos, Quaternion.identity) as GameObject;
octo1.transform.parent = newParent.transform;
}
}
Please look over it and let me know if I should change anything or add anything. I am also looking for a generic health script where I could just add my play prefab to allow his health to show above his head.
This sounds like 3 or more questions in one. I'll try to answer the question about "too many."
Try something like this:
void Start () {
if (numEnemies < YourThreshholdForNumberOfEnemies)
{
GameObject newParent = GameObject.Find("1-background elements");
for (int i = 0; i < numEnemies; i++)
{
Vector3 newPos = new Vector3(Random.Range(xMin, xMax), Random.Range(yMin, yMax), 0);
GameObject octo = Instantiate(enemyPrefab, newPos, Quaternion.identity) as GameObject;
octo.transform.parent = newParent.transform;
Vector3 newPos1 = new Vector3(Random.Range(xMin, xMax), Random.Range(yMin, yMax), 0);
GameObject octo1 = Instantiate(enemyPrefab1, newPos, Quaternion.identity) as GameObject;
octo1.transform.parent = newParent.transform;
}
}
}
well if you want you can use this
public GameObject[] obj; // for your enemies, using array so you can put many kind of enemy prefabs
public float spawnMin = 1f; //your minimum time enemies spawn
public float spawnMax = 2f; //your maximum time enemies spawn
void Start ()
{
spawn();
}
void spawn()
{
Instantiate(obj[Random.Range(0, obj.GetLength(0))], //instantiate random prefabs
new Vector3(transform.position.x, transform.position.y, z),
Quaternion.identity)
//this is the one that control how many times spawn called
Invoke("Spawn", Random.Range(spawnMin, spawnMax));
}

Categories

Resources