Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by PimajeXenja · Aug 06, 2015 at 04:59 PM · gameobjectbooleanrecycle

How to recycle random prefabs that spawn from a specific point.

Hello everyone! Thank you in advance for taking the time to help with my question. Long story short I am working on a 2d game. In the game I have cars spawning from both ends of the screen from a "spawn point" empty prefab. The cars would go to the opposite end of the screen where they would enter the trigger of another "end point" prefab and become destroyed. However on mobile devices, constant instantiating and destroying isn't good so I am cleaning up my code.

I was working on a way to recycle my car prefabs. What I was expecting my code to do is: Game Manager Script- Boolean check to see if any cars have spawned. If no cars have spawned, pick a random number either 0, or 1. Each number is a case referring to a different car prefab which subsequently gets placed at the "spawn point" and a shared-between-multiple-scripts boolean is set to true.

 public class GameManager : MonoBehaviour {
     CarSpawner Script;
     public Transform RightSpawnPoint;
     public bool TruckSpawned;
     public bool SilverCarSpawned;
     public bool CarSpawned;
     private GameObject TruckR;
     private GameObject SilverCarR;

 // Use this for initialization
 void Start () {
     //CarSpawned = true;
     TruckR = GameObject.Find ("TruckR2");
     SilverCarR = GameObject.Find ("SilverCarR2");
     RightSpawnPoint = GameObject.Find ("spawnPointRight").transform;
     Script = GameObject.Find ("DestroyPoint1").GetComponent<CarSpawner> ();
     Invoke ("CreateCarsRight", (Random.Range(0,1)));
 
 }
 
 // Update is called once per frame
 void Update () {
     TruckSpawned = Script.TruckOnScreen;
     SilverCarSpawned = Script.SilverCarOnScreen;

     if (TruckSpawned == false && SilverCarSpawned == false) {
         CarSpawned = false;
     }

     if (TruckSpawned == true || SilverCarSpawned == true) {
         CarSpawned = true;
     }
 
 }

 void CreateCarsRight () {
     float delay = Random.Range (2, 6);
     int CarR_Num = Random.Range (0, 2);
     if (CarSpawned == false) {
         switch (CarR_Num) {
         case 0: TruckR.transform.position = new Vector3(RightSpawnPoint.position.x, RightSpawnPoint.position.y, transform.position.z);
             TruckSpawned = true;
             break;
         case 1: SilverCarR.transform.position = new Vector3(RightSpawnPoint.position.x, RightSpawnPoint.position.y, transform.position.z);
             SilverCarSpawned = true;
             break;
         }
     }
     Invoke ("CreateCarsRight", delay);
 }

}

Car Controller Script- This script is attached to both vehicle prefabs. It has booleans for each vehicle. if both are false, then the car stops moving. if either are true, then the car can move.

public class RightCarController : MonoBehaviour {

 WheelJoint2D[] WheelJoints;
 private int Speed = 1000;
 JointMotor2D Motor;
 public bool TruckVisible;
 public bool SilverCarVisible;
 public Transform FrontWheel;
 public Transform RearWheel;
 private int Torque = 10000;
 GameManager Script;
 Rigidbody2D[] Rigidbodies;

 // Use this for initialization
 void Start () {
     Script = GameObject.Find ("GameEngine").GetComponent<GameManager> ();
 
 }
 
 // Update is called once per frame
 void Update () {
     TruckVisible = Script.TruckSpawned;
     SilverCarVisible = Script.SilverCarSpawned;

     if (TruckVisible == false || SilverCarVisible == false) {
         Rigidbodies[0].isKinematic = true;
         Rigidbodies[1].isKinematic = true;
         Rigidbodies[2].isKinematic = true;
         WheelJoints[0].useMotor = false;
         WheelJoints[1].useMotor = false;
         Rigidbodies[0].isKinematic = false;
         Rigidbodies[1].isKinematic = false;
         Rigidbodies[2].isKinematic = false;
     }

     if (TruckVisible == true || SilverCarVisible == true) {
         WheelJoints[0].useMotor = true;
         WheelJoints[1].useMotor = true;

     }
 }

 void Awake () {
     WheelJoints = GetComponentsInChildren<WheelJoint2D> ();
     Rigidbodies = GetComponentsInChildren<Rigidbody2D> ();
     Motor.motorSpeed = Speed;
     Motor.maxMotorTorque = Torque;
     WheelJoints[0].motor = Motor;
     WheelJoints [1].motor = Motor;
 }
 

}

End Point Script- This script is attached to the end point. I have the on trigger enter 2d here because the cars won't interact with the end point from their end, I believe, since the end point is kinematic. When a gameobject with a tag "car" comes into its trigger, its supposed to set the shared booleans to false.

public class EndPoint : MonoBehaviour {

 public bool TruckOnScreen;
 public bool SilverCarOnScreen;
 RightCarController Script;
 // Use this for initialization
 void Start () {
     Script = GameObject.Find ("TruckR2").GetComponent<RightCarController> ();

 }
 
 // Update is called once per frame
 void Update () {
     TruckOnScreen = Script.TruckVisible;
     SilverCarOnScreen = Script.SilverCarVisible;

 }

 void OnTriggerEnter2D(Collider2D other) {
     if (other.gameObject.tag == "Car")
         TruckOnScreen = false;
         SilverCarOnScreen = false;
 }

}

What actually happens, is that the vehicles get set to the spawn point and that is it. If I manually set one of the cars to true, both start rolling. Additionally, both seem to ignore being set to false from the end point and being set to the transform of the spawn point when false.

When testing one car and everything separately, everything seemed to work. Putting everything together, and adding an additional car seem to break it. It seems to me, that there is something wrong with the way my booleans are set up. Any help is greatly appreciated!.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by alteredgene-london · Aug 07, 2015 at 12:06 PM

Hi, i suggest you try a different approach on what your trying to implement. Here's what comes to my mind, first try to implement a object pooling script that will handle spawning and returning of cars.

Here's a sample object pooling code i made, attach this script to the same game object your car spawner is attached, set up objectPoolData after. Add a reference to this script to your car spawner and let your car spawner handle Spawning and Returning of objects.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class SampleObjectPoolingScript : MonoBehaviour {
 
     [System.Serializable]
     public class ObjectPoolData {
         public string key = "";
         public Transform objectTransform = null;
         public int initialSpawnCount = 5;
     }
 
     public ObjectPoolData[] objectPoolData;
     public Vector3 inActiveObjectPosition = Vector3.zero;
 
     private Dictionary<string, List<Transform>> activeObjects = null;
     
     private Dictionary<string, List<Transform>> inActiveObjects = null;
 
     private Dictionary <string, Transform> prefabDictionary = null;
 
     private Transform myTransform = null;
 
     public Transform SpawnObject (string key, Vector3 position) {
         if (inActiveObjects.ContainsKey (key)) {
             List<Transform> objectList = inActiveObjects[key];
             Transform t = null;
             if (objectList.Count > 0) {
                 t = objectList[0];
                 objectList.Remove (t);
                 t.parent = null;
                 t.position = position;
                 t.gameObject.SetActive (true);
             } else {
                 t = Instantiate (prefabDictionary[key], position, Quaternion.identity) as Transform;
             }
             activeObjects[key].Add (t);
             return t;
         }
         return null;
     }
     
     public void ReturnObject (string key, Transform t) {
         if (!activeObjects.ContainsKey (key)) { return; }
         DisableObject (t);
         activeObjects [key].Remove (t);
         inActiveObjects [key].Add (t);
     }
 
     void Start () {
         myTransform = transform;
         InitializeObjectPool ();
     }
 
     private void InitializeObjectPool () {
         foreach (ObjectPoolData data in objectPoolData) {
             List<Transform> objectList = new List<Transform> ();
             for (int i = 0; i < data.initialSpawnCount; i++) {
                 Transform t = Instantiate (data.objectTransform, inActiveObjectPosition, Quaternion.identity) as Transform;
                 DisableObject (t);
                 objectList.Add (t);
             }
             string poolKey = data.key.Equals ("") ? data.objectTransform.name : data.key;
             if (!inActiveObjects.ContainsKey (poolKey)) {
                 inActiveObjects.Add (poolKey, objectList);
                 activeObjects.Add (poolKey, new List<Transform> ());
                 prefabDictionary.Add (poolKey, data.objectTransform);
             }
         }                                     
     }
     
     private void DisableObject (Transform t) {
         t.gameObject.SetActive (false);
         t.parent = myTransform;
         t.position = inActiveObjectPosition;
     }
 }
 

Add this SampleVehicleHook script i made to each of your vehicle prefab:

 using UnityEngine;
 using System.Collections;
 
 public class SampleVehicleHook : MonoBehaviour {
 
     public delegate void CarReachedEndPointHook (Transform t);
     public CarReachedEndPointHook OnCarReachedEndPointHook;
     
     void OnTriggerEnter2D(Collider2D other) {
         if (OnCarReachedEndPointHook != null) {
             OnCarReachedEndPointHook (transform);
         }
     }
 }

Here is a SampleCarSpawner script i made as an example of how to use those 2 previous scripts above:

 using UnityEngine;
 using System.Collections;
 
 public class SampleVehicleSpawner : MonoBehaviour {
     
     public SampleObjectPoolingScript objectPoolingManager;
     
     public string carKey = "Car";
     
     public void SampleSpawnACar () {
         Transform t = objectPoolingManager.SpawnObject (carKey, Vector3.zero);
         var vehicleHook = t.GetComponent<SampleVehicleHook> ();
         vehicleHook.OnCarReachedEndPointHook = HandleOnCarReachedEndPointHook;
     }
     
     void HandleOnCarReachedEndPointHook (Transform t) {
         objectPoolingManager.ReturnObject (carKey, t);
     }
 }
 

Hope this helps :) PS. Wasn't able to test those scripts i just created them

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PimajeXenja · Aug 08, 2015 at 08:13 PM 0
Share

Thank you alteredgene-london! I haven't had a chance to apply your code yet, because I work out of town. But as soon as I get home I'll try it out!

avatar image PimajeXenja · Aug 11, 2015 at 07:00 AM 0
Share

Okay I'm back in town and applied the code you provided and I'm confused. If I am correct, I'm supposed to apply the object pooling script to the game object that I have delegated to be my spawn point, vehicle hook to my prefabs, and car spawner to my game manager. Afterwords, I am to fill out the object pool data size (number of gameobjects to be spawned), key (name), object transform (gameobject), and number to be spawned and lastly the position that I want the cars to be "inactive." I'm obviously doing something wrong since I get the error: NullReferenceException: Object reference not set to an instance of an object ObjectPoolingScript.InitializeObjectPool () (at Assets/Root/Scripts/ObjectPoolingScript.cs:65) ObjectPoolingScript.Start () (at Assets/Root/Scripts/ObjectPoolingScript.cs:53) It's probably something simple; it's just really late.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Turning a menu on and off onclick in hololens 0 Answers

Bool based on objects existing not changing. 2 Answers

Disable / enable script 2 Answers

Unable to show gameobjects at specific timing 0 Answers

Boolean Not Changing 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges