Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Proper way to delete a (Obi)Rigidbody (if there is one)
#3
(05-10-2023, 06:42 AM)josemendez Wrote: Hi!

Having one updater per rope will yield rather poor performance, since it forces all ropes in your scene to be simulated sequentially  - instead of taking advantage of multithreading. Ideally you should have a single updater per scene, in charge of updating all your solvers. This is far more efficient. See:

http://obi.virtualmethodstudio.com/manua...aters.html
http://obi.virtualmethodstudio.com/manua...cture.html

Having one solver per rope is also very wasteful, unless each rope requires different global parameters (such as the reference frame, gravity, or constraint settings).


At which point in the frame are you calling Destroy() on the updater/solver/rope/rigidbody? I can only imagine this being an issue if you do it during the updater's update cycle, since it will prevent it from cleaning up data associated to destroyed rigidbodies.

kind regards,


Hello again!

I managed to figure out how to delete the rope and make a new one without any errors. It was tricky and took some trial and error, but it does seem to work fine.

I originally implemented Obi rope a while ago (maybe last year? Or earlier this year, something like that), and honestly I don't remember what I originally intended, but I made it so each rope has it's own updater and solver, with a script that disables both of those components the moment the rope stops being interacted with by the player character. In my use case each rope just hangs there perfectly still, unless the player character is climbing up one of them, in which case it gets enabled to react realistically while being climbed, and then when the player lets go, the rope falls straight again and the solver and updater are disabled almost immediately. I might have intended to just leave it that way until later when I further optimize everything, but for now that seemed to work fine. If there are 20 ropes, then there are 20 solvers and 20 updaters, but all of them are disabled, except for whichever rope is being climbed (if any). Thanks for reminding me that you can have multiple solvers with a single updater, because I definitely forgot that from when I first implemented it. When I go to further optimize later, I'll definitely keep that in mind.

So what I ended up doing to fix the errors, was to use GetComponent<ObiParticleAttachment>() to grab the particle attachment component that was referencing the rigidbody, then disabled it first before deleting the whole rope, THEN deleted the rope. This stopped the endless loop of rigidbody errors, but it created a new error in BurstColliderWorld.cs at line 61. It said I wasn't allowed to use DestroyImmediate(). I realized it was probably deleting something while it was in the middle of updating, so instead of just deleting the whole rope right away, I set up a timer in the script to delete the whole rope 5 physics frames after disabling the particle attachment. That fixed the error for DestroyImmediate(), but then created another "object reference not set to an instance of an object" error in ObiColliderWorld.cs in the UpdateColliders() method. For some reason, it didn't like referencing colliderHandles.Count in the for loop. So I changed it to this:

public void UpdateColliders()
        {

            int colliderHandlesCount = colliderHandles.Count;

            // update all colliders:
            for (int i = 0; i < colliderHandlesCount; ++i)
                colliderHandles[i].owner.UpdateIfNeeded();
        }


And poof, no more errors. Literally no idea why the for loop was throwing errors in the first place, though. I was using Debug.Log() to tell me if colliderHandles ever became null while I was experimenting and it never did. I'm thinking maybe it was some weird quirk of Visual Studio? Or perhaps something to do with the version of Unity I'm using. Or some combination thereof. But it works, and thought you might find it interesting how I did it. Also, I should mention I'm using Obi Rope 6.2. I don't know if that matters but that was the latest version when I first implemented it, and haven't updated since.


Anyway, thank you for your time and assistance! I appreciate you, sir. Gran sonrisa


PS: Oh you asked me at what point I was deleting the old rope originally. The process was: player presses up on the D pad which sets an animator controller trigger, which makes the character transition to an animation of him shooting the bow at the ceiling. In the animation itself, there's an event call, which calls method ShootRopeArrow(). In ShootRopeArrow(), it tests object reference ropeArrowRope to see if it's null. If it's null, then it just fires an arrow at the ceiling, which spawns a new rope (i.e. first rope created). If it's not null (a rope exists already), then it used Destroy() to get rid of it, then fired the arrow to create a new one. Now instead of that, it disables the particle component first and then deletes the rope 5 frames later.
Reply


Messages In This Thread
RE: Proper way to delete a (Obi)Rigidbody (if there is one) - by Lazerpants - 10-10-2023, 11:59 PM