Generating sprite objects and destroying them after they are out of bounds

I have a fixed orthographic camera for my 2D game with a scrolling background and I want to spawn my sprites randomly outside the camera bounds and have them move inside and out of the camera and get destroyed. Currently I’m using the script below but its generating a lot of sprites within the camera bounds and not working as intended. I cant point out where i’m going wrong?

[33778-screenshot+2014-10-17+01.03.22.jpg|33778]

Random Sprite Generation Code:

	public Vector2 speed = new Vector2(10,10);

	//Moving direction
	public Vector2 direction = new Vector2(-1,0);

	private Vector2 movement;

	public int numToSpawn;

	private Vector3 position;

	float CameraHeight;

	float CameraWidth;

	int spawned = 0;

	public bool spawn;

	void Start () 
	{

		CameraHeight = Camera.main.camera.orthographicSize;

		CameraWidth = CameraHeight * Screen.width/Screen.height;

	}

	void Update () 
	{
 
		movement = new Vector2(speed.x * direction.x, speed.y * direction.y);

		if(spawn)
		{
			position = new Vector3(Random.Range(-0.5f,0), Random.Range(0f,CameraHeight),0f);
			Instantiate(gameObject,position,transform.rotation);
			spawned++;
		}	
	}

	void FixedUpdate()
	{
		rigidbody2D.velocity = movement;

	}


	//Checking Collision property
	void OnTriggerEnter2D(Collider2D col)
	{
		EffectsScript effects =  gameObject.GetComponent<EffectsScript>();
		if(effects.IsColorise)
		{
			effects.RandomColorise();
			
		}
		if(effects.IsMelody)
		{
			effects.Melody();
		}
	}

I take it this script is attached to the camera? What is the position of the camera? Is the idea for the sprites to appear just on the left side of the camera boundaries? Also, is there a particular reason why the x-coordinate of the sprites is randomized instead of just being placed at a fixed distance outside the camera view?

1 Answer

1

@sweptica

I think the reason you are getting a bunch of object created is because your instantiating your game objects in the Update() method. Consider making a spawn function and then Invoking it in your start method. Something like:

void Spawn()
{
    if(spawn)
    {
    Instantiate(gameObject,spawnPosition,transform.rotation);
    spawned++;
    }
    Invoke("Spawn", Random.Range(1, 5);
}

Then in your start method call your spawn function.

void Start()
{
//Other stuff you want to do in your start method.

Spawn();
}

As far as a workable solution for spawning the stuff off the screen, I would use some of the functions of the Camera class. Personally I would use ViewportToWorldPoint(). I made some helper functions for a game that found the four corners of the screen, like this:

Vector3 lowerLeftCorner;
Vector3 lowerRightCornter;
Vector3 upperLeftCorner;
Vector3 upperRightCorner;

lowerLeftCorner = mainCam.ViewportToWorldPoint(new Vector3(0f, 0f, 0f));
lowerRightCorner = mainCam.ViewportToWorldPoint(new Vector3(1f, 0f, 0f));
upperLeftCorner = mainCam.ViewportToWorldPoint(new Vector3(0f,1f,0f));
upperLeftCorner = mainCam.ViewportToWorldPoint(new Vector3(1f,1f,0f));

Then to instantiate the gameObject off the screen I did this (I only instantiated gameObjects on the left and bottom of the screen):

//Gets half of the gameObject's width and height so that it can be used to control spawning
    float objWidthOffset = gameObject.renderer.bounds.extents.x;
    float objHeightOffset = gameObject.renderer.bounds.extents.y;

//Spawn object right below bottom of screen.
    Vector3 spawnPosition = new Vector3 (Random.Range(lowerLeftCorner.x + objWidthOffset, lowerRightCorner.x - objWidthOffset), lowerLeftCorner.y - objHeightOffset, 0.0f);

Then you just use the spawnPosition variable in your Instantiate function. Hopefully this helps some. If not, feel free to ask questions :slight_smile:

Oh, and I wouldn't attach this to the camera. I'd attach it to the Prefabs you are wanting to Instantiate.

Its doing something like this [33821-screenshot+2014-10-17+19.12.05.jpg|33821]

What have you got this script attached too?. If you have it attached to your fish, every time you create a fish you will get another spawner. I assume this is not what you want, you want to attach this to something that's only initialized once. eg. and Empty Game Object will do. You could then create a public GameObject say called fishPrefab and create from there.

YEs the script is attached to the object Actually I would like to attach it to the object itself rather but I understand what you're trying to say. .every other fish created by spawn will also spawn :/ I simply want to have my fishes or other objects spawn outside the camera bounds and at random Y coordinates, and let them move left to right or watever. Any tutorials or link to do this would be really helpful

Yeah, sorry about that. When I used this code in my game, I attached it to an empty gameObject that I called "Game Manager". Attaching to the prefab is a bad thing. Sorry I mislead you :( Also, I good way to then destroy the gameObjects, once they have left the screen is to use the void OnBecameInvisible() method on a script that you have attached to prefab. It's this simple: void OnBecameInvisible() { Destroy(gameObject); } Just know that when you use the OnBecameInvisible(), it doesn't count an object as invisible unless it's not visible in the game AND scene view.