Search Unity

Resolved Bullet not moving after implementing object pooling

Discussion in 'Scripting' started by Alacz, Dec 29, 2022.

  1. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    I tried to implement object pooling for my asteroid mockup, but the bullet won't move anymore, just stays at where it is activated.

    Pooling script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. public class Preload : MonoBehaviour
    7. {
    8.     public static Preload SharedInstance;
    9.     public List<GameObject> preloadobj;
    10.     public GameObject objtoload;
    11.     public int preloadamount;
    12.     public float bspeed = 10f;
    13.  
    14.     public PBullet_Pis ppisbullet;
    15.  
    16.     private Rigidbody2D brb;
    17.  
    18.     private void Awake()
    19.     {
    20.         SharedInstance = this;
    21.     }
    22.  
    23.     // Start is called before the first frame update
    24.     void Start()
    25.     {
    26.         preloadobj = new List<GameObject>();
    27.         GameObject tmp;
    28.         for (int i = 0; i < preloadamount; i++)
    29.         {
    30.             tmp = Instantiate(objtoload);
    31.             tmp.SetActive(false);
    32.             preloadobj.Add(tmp);
    33.         }
    34.         brb = ppisbullet.GetComponent<Rigidbody2D>();
    35.     }
    36.  
    37.     // Update is called once per frame
    38.     void Update()  
    39.     {
    40.        
    41.     }
    42.  
    43.     public GameObject GetPreloadObject()
    44.     {
    45.         for (int i = 0; i < preloadamount; i++)
    46.         {
    47.             if (!preloadobj[i].activeInHierarchy)
    48.             {
    49.                 return preloadobj[i];
    50.             }
    51.         }
    52.         return null;
    53.     }
    54.     public void Shooting(Vector2 direc) //Me desperately trying to bring moving func from bullet script
    55.     {
    56.         brb.AddForce(direc * this.bspeed); //add a force to bullet
    57.         //Destroy(this.gameObject , this.time); //destroy when time up
    58.     }
    59. }
    60.  
    Bullet Script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Threading;
    4. using UnityEditor.Tilemaps;
    5. using UnityEngine;
    6.  
    7. public class PBullet_Pis : MonoBehaviour
    8. {
    9.     private Rigidbody2D rb; //bullet physics refer
    10.     private Vector2 bulletdirec;
    11.  
    12.     public GameObject bspawn;
    13.  
    14.     public float bspeed = 10.0f; //bullet speed
    15.     public float time = 10.0f; //time for bullet to despawn
    16.  
    17.     private void Awake()
    18.     {
    19.         rb = GetComponent<Rigidbody2D>();
    20.         //get components
    21.     }
    22.  
    23.     private void FixedUpdate()
    24.     {
    25.         if (gameObject.activeInHierarchy)
    26.         {
    27.             rb.velocity = this.transform.forward * bspeed;
    28.          //   rb.AddForce(bspawnup.transform. * bspeed);
    29.             if (time> 0)
    30.             {
    31.                time -= Time.deltaTime;
    32.             }
    33.             else
    34.             {
    35.                 gameObject.SetActive(false);
    36.                 time = 10;
    37.             }
    38.         }
    39.     }
    40.  
    41.     public void Shooting() //shooting function, direc variable is refered from player:this.bspawn.up
    42.     {
    43.         //rb.AddForce(direc * this.bspeed); //add a force to bullet
    44.         //Destroy(this.gameObject , this.time); //destroy when time up
    45.     }
    46. }
    Shooting function from player:
    Code (CSharp):
    1.     void Shoot()
    2.     {
    3.         rigbod.velocity = new Vector2(rot.x , rot.y).normalized * thrust; //apply a new velocity with the negative direction and the thrust, find out the effects of normalized.
    4.         GameObject bullet = Preload.SharedInstance.GetPreloadObject();
    5.         if (bullet != null )
    6.         {
    7.             bullet.transform.position = bspawn.transform.position;
    8.             bullet.transform.rotation = bspawn.transform.rotation;
    9.             bullet.SetActive(true);
    10.            // brb.AddForce(transform.forward * preload.Bspeed());
    11.         }
    12.        // PBullet_Pis bullet = Instantiate(this.bulletpf, this.bspawn.position, this.bspawn.rotation); //instance bullet
    13.        
    I tried calling transform from pooled object, doesn't work. Tried calling rigidbody at pooling script from bullet and move the bullet there, doesn't work. All other tutorial I found only let bullet travel in a fixed direction, instead on where the player is aiming...

    Thanks in advance!!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    Well there's your problem! You have discovered some of the costs and issues associated with object pooling / pools:

    https://forum.unity.com/threads/object-pooling.1329729/#post-8405055

    https://forum.unity.com/threads/object-pooling-in-a-tower-defense-game.1076897/#post-6945089

    Pooling is a disaster and will rarely benefit your project. I highly recommend RIPPING OUT all the pooling code.

    If you really want to get it working then it is time for you to start debugging. Here's how:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    When in doubt, print it out!(tm)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.

    In general, DO NOT OPTIMIZE "JUST BECAUSE..." If you don't have a problem, DO NOT OPTIMIZE!

    If you DO have a problem, there is only ONE way to find out. Always start by using the profiler:

    Window -> Analysis -> Profiler

    Failure to use the profiler first means you're just guessing, making a mess of your code for no good reason.

    Not only that but performance on platform A will likely be completely different than platform B. Test on the platform(s) that you care about, and test to the extent that it is worth your effort, and no more.

    https://forum.unity.com/threads/is-...ng-square-roots-in-2021.1111063/#post-7148770

    Remember that optimized code is ALWAYS harder to work with and more brittle, making subsequent feature development difficult or impossible, or incurring massive technical debt on future development.

    Notes on optimizing UnityEngine.UI setups:

    https://forum.unity.com/threads/how...form-data-into-an-array.1134520/#post-7289413

    At a minimum you want to clearly understand what performance issues you are having:

    - running too slowly?
    - loading too slowly?
    - using too much runtime memory?
    - final bundle too large?
    - too much network traffic?
    - something else?

    If you are unable to engage the profiler, then your next solution is gross guessing changes, such as "reimport all textures as 32x32 tiny textures" or "replace some complex 3D objects with cubes/capsules" to try and figure out what is bogging you down.

    Each experiment you do may give you intel about what is causing the performance issue that you identified. More importantly let you eliminate candidates for optimization. For instance if you swap out your biggest textures with 32x32 stamps and you STILL have a problem, you may be able to eliminate textures as an issue and move onto something else.

    This sort of speculative optimization assumes you're properly using source control so it takes one click to revert to the way your project was before if there is no improvement, while carefully making notes about what you have tried and more importantly what results it has had.
     
    Alacz likes this.
  3. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I will spare you a 100 line diatribe against pooling and say it should only require a bit of adjustment to get it to work. If there is a problem with pooling objects I'd like to see something official recommending that it not be done. Instead we have tutorials explaining how to do it.

    That said I don't think a List is a good collection to use (but it will work of course). I use a Queue. It doesn't require but does support prefilling.

    What you are experiencing I believe is something I spent a day on as well. It made no sense to me then and I still don't understand what is going on behind the scenes BUT it is due to your setting the object inactive. Apparently (if the videos are to be believed) the use of an Array would not cause this behavior. So you can switch to an Array or see what happens if you do not inactivate the objects.

    Again I'm queuing bullets in my Queue as they are fired so it only grows to the size needed in real-time use. If nobody fires a bullet the Queue remains empty. Firing 100's of bullets doesn't require 100 stored in the Queue, if a bullet is not available another is instantiated and the Queue grows to cover that case but typically some will have been returned before another one is needed.

    Try it and let us know.
     
    Alacz likes this.
  4. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I've kept my opinions to myself for months but do you honestly believe these types of answers result in the outcome you are hoping for? If you are unable to engage the profiler did he ask about the profiler?
     
    chemicalcrux likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    The outcome I'm hoping for is people start writing software in a constructive fashion without wasting time on silly things that do not help their project (object pooling) and generally wreck it (misdirected optimization in general).

    By that measure, yes, I've already helped many people here avoid bad choices regarding the above two things, and I hope to help more people.

    No but OP said, and I quote:

    That either means:

    - "I wanna learn about object pooling!" in which case OP doesn't need us because pooling is VERY well understood, even if it is in the general average case a useless gesture

    - or more likely OP "read on the internet that pooling makes games faster" (a total lie!!) and now they've wrecked their project by mis-implementing pooling.

    If OP wants his game to be faster, at least START with the profiler.

    I stand firmly by 100% of everything I posted above.
     
  6. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    720
    I agree that there is no point in object pooling. Unity has some tutorials that imply object pooling is useful for even small numbers of objects. This is...not really true.

    Pooling might be useful if you're running into serious garbage collection problems: lots of time being spent cleaning up and making room in memory for big piles of objects. It also might be useful if it's very expensive to create and destroy the objects.

    Neither of these are true for a few hundred bullets in a shmup.

    (and if you really want to have tens of thousands of bullets flying all over the place...look into ECS)
     
    Kurt-Dekker likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    I want people to have fun making games: bullets and space ships and zombies and players and balls and monkeys and lasers and dynamite...

    In my wildest dreams, people here should JUST GO CRAZY with game development!

    Unity3D makes it possible for the average person to pick it up, learn a little bit at a time, and move towards something they can be proud of, something they can enjoy playing, something they can show their friends and parents ("Look what I made!" followed by "Whoa, you made a really fun game here!") and something that they could perhaps even make money at someday.

    That's beautiful, truly a beautiful thing in this world.

    In every way, speculative optimization and object pooling DESTROYS that. Speculative optimization and object pooling DESTROYS projects and makes me sad. And it's just SO unnecessary, so much work and struggle and sadness created by these two simple things.

    That's why I try to guide people away from these poor choices.
     
    chemicalcrux likes this.
  8. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    720
    That's why I use LINQ pretty frequently :D

    Code (CSharp):
    1. var wokenUp = enemies.Where(x => (x.transform.position - player.transform.position).magnitude < 25)
    2. .Where(x => x.name != "Sleepy Joe")
    3. .Where(x => x.sleeping)
    4. .Where(x => x.sleepiness < 1);
    5.  
    6. foreach (var enemy in wokenUp) {
    7.   enemy.WakeUp();
    8. }
    Is it maximally efficient? Hell no. Is it fast enough for almost everything? Yep.

    I only think about optimization when...
    • It's a huge difference. Think about O(N) vs. O(2^N) vs O(N!)
    • The result is convenient for me. If I'm going to grab a reference to a component and never let go of it, I might as well just make a field for it.
    • It's actually vital (and I have Profiler data to back me up). I wrote an AI system for an RTS game that does gradient descent to find the optimal location for buildings, units, etc. It got slow very quickly, so I learned how to rewrite the entire thing as a bursted parallel job -- and hoo boy, it sure is fast now!
     
  9. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    There isn't some universally acceptable way to learn and if someone wants to implement object pooling it can be a good exercise. But that said the way to dissuade bad habits or to encourage good ones isn't to post 100 line "hey look at all the paragraphs I can cut and paste".

    The generally accepted fact is that dialog works better than diatribe.
     
  10. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    It is reasonable to believe that if object pooling had no value (or negative value as some would have us believe) then it wouldn't have been implemented by Unity. It wouldn't likely be the subject of numerous Unity-related videos, courses and such. Notable developers and instructors, Asbjørn Thirslund for instance, would have probably outlined the downsides rather than how to do accomplish it


    Can it be misused? That goes without saying, but if the situation arises that will benefit from object pooling it is best to know how to do it correctly. That comes with practice. The same goes for generic lists, dictionaries and a host of other options available to us. If one has no understanding of how say pub/sub, works it seems to me if the perfect use case showed up, such a developer wouldn't be able to leverage it.

    Learn stuff when you don't need it so you can use it confidently when you do.
     
  11. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    I don't really see issues in your code. The only thing I could imagine is that your player shoots more bullets than there are instances in the pool. But in this case your pool would just return null and no more bullets would be spawned.

    The
    if (gameObject.activeInHierarchy)
    part seems unnecessary because FixedUpdate won't be called on (components on) deactivated GameObjects.

    Also your pool looks a bit stange to me. I would just create new projectiles if the pool is too small and let them all live in memory - or destroy them when they are returned to the pool.

    Also you don't have to set any velocity on your projectiles from your player or your pool, your projectile accelerates on it's own.

    My assumption is that your projectile-prefab has wrong settings. The
    bspeed
    variable is probably null, because otherwise it woule be moving. Or your Rigidbody is set to "isKinematic". Or you don't even have a prefab assigned but a scene object instead, which has
    bspeed
    set to 0.

    TL;DR: Code seems fine to me, it's probably a setting in the inspector of your Bullet-Script, Bullet-Rigidbody or Pool.

    Also I would make the pool create itself on demand, so you don't have to worry about having the singleton sit in your hierarchy.

    And you should have a look at the pooling classes unity provides:
    https://docs.unity3d.com/ScriptReference/Pool.ObjectPool_1.html
     
  12. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    And to the whole conversation about speculative optimization:

    Fixing Performance and rewriting code to be more performant isn't really fun. It's more fun to just keep a few patterns while writing the code so you don't have to worry about it at all. At least in my experience.

    And when you know that you will have thousands of bullets spawned and despawned within a few seconds, I see no reason to wait for the profiler to tell me that not using a pool was a bad decision.
    Same with hundreds of raycasts per frame - there is a RaycastCommand suited for such cases.

    I code everything with performance in mind, even when attending a game jam where I have to make a game in 2 or 3 days. It doesn't slow me down at all. It won't make my code any more complex because I have systems that handle such cases for me, it's not like I re-invent pooling every time I need it, I just call
    ObjectPool.Get(prefab)
    and
    ObjectPool.Return(instance)
    instead of
    Instantiate(prefab)
    and
    Destroy(instance)
    .

    Worst case scenario in this regard is working on a game for one or two years, only to find out that the performance is really bad and you have to rewrite a lot of systems, which will introduce bugs into your game, this means you have to test and fix everything .. and yea, this sounds really bad to me.
    And when you see performance issues, when the game already stutters, it's usually not just one new script that causes these problems, it usually means that all the performance problems have piled up and you have to fix everything to support this new level where 10 enemies are active at the same time.

    In my second last game I wasted two entire months just fixing performance issues (and to find out that lightmapping does not work in big game worlds).

    So unless you are working on a flappy bird clone or anything with very low complexity, I'd advice keeping performance in mind at all times, not just code, but also game-design, level-design and so on.

    At the end of the day we are all working on realtime simulations that should run at consistent 30-60fps (or more). And "fixing it when needed" is not always the most efficient approach. Sometimes, sure, but not always.

    Sorry for the wall of text. xD
     
  13. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    As we reach the one-day mark on this post, why has OP not yet posted this:

    --------------------------------------------------------------

    "I put this line of code in PBullet_Pis.cs on line 27:

    Code (csharp):
    1. Debug.Log( "rb.velocity = " + rb.velocity);
    And here is what printed out:"

    --------------------------------------------------------------

    Why don't we have that post? Come on OP, you're gonna have to debug this. Nobody here can.

    EDIT: I guess OP hasn't even come back yet... or maybe they came back and got scared by our raging conversation and ran away.
     
    Last edited: Dec 31, 2022
    John_Leorid likes this.
  14. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I'm telling you it is due to him having set it inactive. I'm waiting for him to test the theory and to confirm that. Meanwhile I believe that he absolutely needs to reset force, position and rotation on spawned items. Both angular velocity and velocity should be set to zero when he is done with them or they are theoretically "still moving".
     
    Last edited: Dec 31, 2022
  15. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    To the original poster: I would tend to instantiate the List in Awake

    But more importantly (I think) this isn't a Singleton pattern if that is your intent.

    Code (CSharp):
    1.  private void Awake()
    2.     {
    3.         SharedInstance = this;
    4.     }
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.         preloadobj = new List<GameObject>();
    9.  
     
  16. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    Well, both the post commenters and my seniors are telling me to give up on it since I'm only making this as a side project and it didn't even require enhancements in the first place... I wanted to put this in my portfolio but for now I might settle with spawn-despawn, tho I will try it out if I had the chance! Thanks for the info!
     
  17. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    Sorry, I was busy on assignments (am a uni student) so I just came back now...
     
  18. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    Thanks all of you for sharing your insights! I only got time now to fix it, but I am doing it now!
     
  19. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    Both the rigidbody is dynamic and bspeed isn't null:
    upload_2023-1-1_22-1-2.png
     
  20. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    rb.velocity = (0.00, 0.00)
    This is the result.
    I'm gonna try out using array instead of list. And should I make a new follow up post?
     
  21. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    I'm sorry but... How would I debug if the bullet is null.....?
     
  22. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    What I should've did if I don't inactive my bullet? And yeah, I know there's a problem on passed on velocity but I wanted to focus more on letting the bullet move first...
     
  23. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    I had put the preloadobj into awake(), nothing changed?
    I'm trying to make another object pooling that works with array/queue instead of list, will let you know if anything happened.
     
  24. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    Guys... I don't think I have any idea on making the pooler array based instead of list based, so we are back to square one.
    Tho to clarify, I don't have any performance issues currently, and I just did pooling because I wanted to learn it. I might still use it at the asteroid spawning, but time will tell.
    Thanks a lot for all your help and suppot!
     
  25. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Real quick... this is a video that shows how to use the Unity-based pool and he demonstrates the memory savings


    Moving preloadobj into awake wasn't supposed to fix anything. It is just a better place to allocate your list making it available a few moments sooner. And there is still a question about your method of making a Singleton.

    I believe I was mistaken about using a list BTW. A friend of mine uses a list and he sets the objects inactive so if that was the issue his wouldn't work. One thing he does different than your code however is he removes the object in use from the pool and returns it when it is no longer in use. You are using some array syntax to return a reference.
     
    Last edited: Jan 1, 2023
  26. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    By not setting inactive you mean by this?
    Code (CSharp):
    1. void Start()
    2.     {
    3.         //preloadobj = new List<GameObject>();
    4.         GameObject tmp;
    5.         for (int i = 0; i < preloadamount; i++)
    6.         {
    7.             tmp = Instantiate(objtoload);
    8.             tmp.SetActive(true);
    9.             preloadobj.Add(tmp);
    10.         }
    The bullet still remains at where I shot it, not moving. Will watch the video now. Thanks!
     
  27. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    More or less but something else seems to be amiss. You have to add force as you pull the object from the pool. Best to watch a video or two and perhaps you can find some code where it all works to use as an example.
     
  28. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    BEAUTIFUL! Step #1 has been taken. Now, find out the quantities going into that value.

    I'll speculate your
    bspeed
    or your
    thrust
    is set to zero. Prove me wrong.

    This is just simple debugging, work through it, fix it, then you can say you implemented an object pooling system, and you can know how much of a hassle it is and advise others not to waste their time either. :)
     
  29. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    I tried adding force in this manner:
    Code (CSharp):
    1. /**/ GameObject bullet = Preload.SharedInstance.GetPreloadObject();
    2.         brb = bullet.GetComponent<Rigidbody2D>();
    3.         if (bullet != null )
    4.         {
    5.             bullet.transform.position = bspawn.transform.position;
    6.             bullet.transform.rotation = bspawn.transform.rotation;
    7.             bullet.SetActive(true);
    8.             brb.AddForce(transform.forward * bthrust);
    How can I code this otherwise?

    Edit: BTW, adding the addforce resulted in this error:
    NullReferenceException: Object reference not set to an instance of an object
     
  30. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    Sadly, bspeed is not zero, which means that I'm still far away from the source of error...
    Tho I sure will tell the tales of how I fought my life thru just to get one function correct.

    Here's the proof taken directly from the pooled object:
    upload_2023-1-2_1-28-28.png

    Thanks for the help!
     
  31. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    Fix that first. Everything is irrelevant until you do.

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Three steps to success:
    - Identify what is null <-- any other action taken before this step is WASTED TIME
    - Identify why it is null
    - Fix that
     
  32. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Everything is a hassle when it is written incorrectly and the code being used is more than a little incorrect. It wouldn't matter if there was no pooling involved it may not have worked. In fact a good pooling system should allow for turning it off in an instant.

    Well respected developers and the Unity development group have determined that there can be a benefit to pooling of objects. The video I posted demonstrates the improvement and the code works without hassle.

    You are stating there isn't a benefit while providing zero evidence. We've all heard similar things about every subject under the sun. Demonstrate it if you can so we can all understand how wrong we've all been.
     
  33. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Pardon me for explaining it in these terms but you are grasping at straws. The code is poorly constructed if a) it doesn't work and b) random odd errors pop-up. The likelihood that bullet would be null is zero in this case you only one line above used it to obtain a reference to the rigidbody.

    I would guess that brb is null but you must learn to solve any exceptions in your code by learning to narrow in on the likely cause. I will suggest at this point that you focus your efforts on finding a model you can use for pooling. Mine works, my friend's works, the ones in the videos posted all work.
     
  34. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    I don't concern myself with "well-respected developers."

    I concern myself with developers who ship and maintain games that make lots and lots of money.

    This may come as a surprise to you, but a LOT of the "well respected developers" you speak of haven't even shipped a single top-charting game. Not even ONE game.

    I do not need to demonstrate. I have offered my observation as a software professional:

    - I have yet to see a casual game context where pooling measurably improves the situation, especially with beginners learning how to program

    - I have seen MANY places where pooling makes the code far harder to maintain, ESPECIALLY when mis-implemented, as it almost always is.

    By definition, if someone is in this forum posting about a problem in their pooling solution, they have no business making a pooling solution.
     
  35. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    I found a fix online! But thank you too!
    I know that I can't call it because it is an object instantiated by the pooler, but how can I access the gameobject that is spawned in a pooler? Is there a guide?

    Thanks for your help!
     
  36. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    Traditionally a pooler (or ANY source of a new object, such as Instantiate<T>() ) would return a reference to the recycled object for you.

    As seen here:

     
  37. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16
    I found a fix online! But thank you too!
    I know that including a call to the rigidbody of the bullet when it is being instantiated by pooler is sketchy, which is why I didn't include it in the first place, but I was out of luck before, but not anymore!
    Thanks for your help!
     
  38. Alacz

    Alacz

    Joined:
    Jul 23, 2018
    Posts:
    16

    Oh, that's how.
    I'm glad that I learn a lot from one single post, so thank you!
     
  39. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    Usually there are two last steps:

    You write down the real issue you found and how you fixed it, so when anyone comes here from a google search, they will find a solution.

    and

    You mark the thread as "Resolved" by clicking on the "Edit Thread" button at the very top.

    It's up to you if you want to follow those unspoken rules of this forum. As the problem is commonly discussed and multiple finished "bullet spawning & pooling" solutions are online, no one will be mad if you don't. ^^
     
  40. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    This will no doubt be a shock to you but many developers who make lots of money may or may not be good developers and they have implemented pooling.

    I and others like me (including the developers of Unity are software professionals. The worst developers I ever worked with were professional developers.

    It can hardly be mis-implemented if one is following a tutorial from someone on the Unity team and or (to use your measure) a software developer who has written games and earns a lot of money.

    That is seriously the worst definition I have ever read about the use of a support forum. If I post a question about a problem I have with animation I have no business using animation.

    Your continual pounding on people about your expertise tends to reveal you have little. And I've given you another opportunity for another 100 lines off-point reply.
     
  41. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Just so we have our terminology correct. Nothing that is returned by the pool is "instantiated". It was instantiated prior to be placing into the pool and the pool only returns a long ago instantiated object.

    The more I think about it the more I'm convinced that each person should attempt to write a routine to pool objects as a mechanism to understand basics of C#. Pooling isn't something only used in Unity development.
     
  42. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    I'm no expert but to me this sounds mis-implemented:

    - It worked ("anymore" implies this)
    - He added pooling
    - It stopped working

    Not sure how much more you have to do to be considered mis-implemented.

    I suppose we'll just have to disagree.