How to destroy object after it moves out of screen
Hi i have alot of cars moving in my screen, as time goes by, it will be hundred or thousand cars create randomly moves in my screen. How do i destroy object if it already out from my screen? I want to clean memory for that or it will create thousand not even 1 hour?
Answer by thor348k · Aug 17, 2016 at 06:26 PM
To keep things simple, use OnBecameInvisible.
void OnBecameInvisible() {
Destroy(gameObject);
}
This will destroy the object when is is out of view of the camera. Here is the API reference: http://docs.unity3d.com/ScriptReference/Renderer.OnBecameInvisible.html
this is the simple script that i need and powerfull hahahah. thanks!
It's probably worth mentioning for anyone just discovering this, that OnBecameInvisible takes into account EVERY camera, including the editor view one. While this wouldn't cause any problem once your game is built and released, it may make things difficult during development if (like I was just now), you're expecting objects to be automatically culled, but they aren't.
Ideally, OnBecameInvisible would allow you to specify which/any/all cameras to test for. And in no scenario should it be taking into account the editor camera since that's just an arbitrary point in world space and of no relevance to the game itself.
Answer by Yujingping · Aug 17, 2016 at 07:13 AM
Hey there. If you are making a 2D game, you may find a fully explained answer here. Actually I don't quite agree with Ronnie's solution, since creating too many colliders and detecting their collisions is very expensive on whatever device you target for. If you are making a 3D game, you may use Camera.WorldToScreenPoint to get the viewport position of the cars based on your indicated camera. You may then check whether the Vector2 position is valid or not. If the x value doesn't drop in [0, Screen.width] or the y value doesn't drop in [0, Screen.height], it is obvious that the car is definitely out of the screen. However in order to avoid a jurky destroy you may set the bounds more flexible. Such as [-0.04 * Screen.width, Screen.width * 1.04] or something.
Here is an example:
using UnityEngine;
using System.Collections;
public class CarDetection : MonoBehaviour
{
private Camera mainCamera;
public Vector2 widthThresold;
public Vevtor2 heightThresold;
void Awake ()
{
//Get your mainCamera here. If you are pretty sure that the camera is always the Camera.main you don't need to implement here. Just call for Camera.main later.
}
void Update ()
{
Vector2 screenPosition = mainCamera.WorldToScreenPoint (transform.position);
if (screenPosition.x < widthThresold.x || screenPosition.x > widthThresold.y || screenPosition.y < heightThresold.x || screenPosition.y > heightThresold.y)
Destroy (gameObject);
}
}
This method doesn't require any box-colliders and meanwhile the MVP transformation is very efficient. If you are always creating many new cars while destroying old ones, I highly recommend you to have a look at Object Pool to make your program much more efficient.
Please feel free for further questions.
GL & HF!
Just to mention a bit, I really recommend you to manage the cars through one single script. Both creating and destroying cars are controlled by this script, let's say, CarSpawn$$anonymous$$anager. You may keep an array of all the active cars and track their visibility quite similar to the code I provided above. GL & HF!
Answer by RonnieThePotatoDEV · Aug 17, 2016 at 06:47 AM
You should make a trigger box collider, either 2d or 3D depending on your game. Make the collider cover the scene, the cars that are beyond this collider will be destroyed, so place it where you want the cars to be. On a script use OnTriggerExit like so,
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Car"))
{
other.gameObject.SetActive (false);
}
}
Modify that to fit your needs.
Hi, actually i already tried before your tips but still not destroy my object and my objest is not gameObject but sprite and it clone randomly alot within every couple seconds. It wasnt prefabs also and not child too. Do you have any idea?
Every Sprite is a game object, it has a transform and sprite renderer, at least. If the script is attached to the game object (sprite), you can just use:
Destroy(gameObject);
This will destroy the object, that the script is attached to. Also, I'd recommend using a prefab, it's less extensive than cloning directly. Save that for when you need to modify individual variables, like for example, carSpeed. Even then, you spawn a prefab, and can edit it directly like so:
GameObject car = (GameObject) Instantiate(carPrefab, transform.position, Quaternion.identity);
car.GetComponent<Car>().carSpeed = 2.0f;
Answer by Nicoroots · Dec 18, 2019 at 10:02 PM
This works for 3D too ? I'm trying and can"t make it work. I know it does work for 2D though
Your answer
Follow this Question
Related Questions
2D sprite won't destroy on collision 0 Answers
SetActive is destroying objects instead of settings them as false 0 Answers
Destroy GameObject after certain amount is reached? 1 Answer
Bullets not destroying enemies 0 Answers
Why i can't acces a global list in my class from OnDestroy() function 0 Answers