Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bug / Crash  Destroying GameObjects immediately is not permitted during physics trigger/contact
#1
Code:
public void AttachRope()
        {
            _blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
            var fatherConnectionPoint = _playersContainer[PlayerCharacter.Father].ConnectionPoint;
            var sonConnectionPoint = _playersContainer[PlayerCharacter.Son].ConnectionPoint;
            Vector3 father = ObiRope.transform.InverseTransformPoint(fatherConnectionPoint.position);
            Vector3 son = ObiRope.transform.InverseTransformPoint(sonConnectionPoint.position);
            lineFromObiRope.SetStartEndPositions(father, son);
            int allLayers = (1 << 16) - 1;
            int excludeLayer15 = ~(1 << 15);
            int finalMask = allLayers & excludeLayer15;

            int filter = ObiUtils.MakeFilter(finalMask,
                1);
            _blueprint.path.Clear();
            _blueprint.groups.Clear();
            _blueprint.path.AddControlPoint(father,
                -father.normalized,
                father.normalized,
                Vector3.zero,
                _controlPointsMass,
                _controlPointsMass,
                1,
                filter,
                Color.white,
                "start");

            _blueprint.path.AddControlPoint(son,
                -son.normalized,
                son.normalized,
                Vector3.zero,
                _controlPointsMass,
                _controlPointsMass,
                1,
                filter,
                Color.white,
                "end");

            _blueprint.path.FlushEvents();
            _blueprint.Generate();
            ObiRope.ropeBlueprint = _blueprint;

            var pinConstraints = ObiRope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
            pinConstraints.Clear();
            var batch = new ObiPinConstraintsBatch();

            batch.AddConstraint(ObiRope.solverIndices[0],
                _fatherConnectionPointObiCollider,
                Vector3.zero,
                Quaternion.identity,
                0,
                0,
                float.PositiveInfinity);

            batch.AddConstraint(ObiRope.solverIndices[_blueprint.activeParticleCount - 1],
                _sonConnectionPointObiCollider,
                Vector3.zero,
                Quaternion.identity,
                0,
                0,
                float.PositiveInfinity);

            batch.activeConstraintCount = 2;
            pinConstraints.AddBatch(batch);
            ObiRope.SetConstraintsDirty(Oni.ConstraintType.Pin);
        }
I made a rope hitch like in the Hook example. And now every time I get this error in ObiCollisionWorld when I use the above AttachRope method.
Code:
public void DecreaseReferenceCount()
        {
            if (--refCount <= 0 && gameObject != null)
                DestroyImmediate(gameObject); 
        }
Code:
Destroying GameObjects immediately is not permitted during physics trigger/contact, animation event callbacks, rendering callbacks or OnValidate. You must use Destroy instead.
UnityEngine.Object:DestroyImmediate (UnityEngine.Object)
Obi.BurstColliderWorld:DecreaseReferenceCount () (at Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderWorld.cs:61)
Obi.BurstSolverImpl:Destroy () (at Assets/Obi/Scripts/Common/Backends/Burst/Solver/BurstSolverImpl.cs:189)
Obi.BurstBackend:DestroySolver (Obi.ISolverImpl) (at Assets/Obi/Scripts/Common/Backends/Burst/BurstBackend.cs:21)
Obi.ObiSolver:Teardown () (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:905)
Obi.ObiSolver:RemoveActor (Obi.ObiActor) (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:1201)
Obi.ObiActor:RemoveFromSolver () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:362)
Obi.ObiRope:set_ropeBlueprint (Obi.ObiRopeBlueprint) (at Assets/Obi/Scripts/RopeAndRod/Actors/ObiRope.cs:152)
_src.Scripts.PlayerFeatures.Connection.ThreadProxy_s.ThreadProxy:AttachRope () (at Assets/_src/Scripts/PlayerFeatures/Connection/ThreadProxy's/ThreadProxy.cs:124)
_src.Scripts.PlayerFeatures.Connection.ConnectionHandler:AttachPhysicalRope () (at Assets/_src/Scripts/PlayerFeatures/Connection/ConnectionHandler.cs:407)
_src.Scripts.PlayerFeatures.Connection.ConnectionHandler:EnablePermanentPhysicalConnection () (at Assets/_src/Scripts/PlayerFeatures/Connection/ConnectionHandler.cs:398)
_src.Scripts.PlayerFeatures.Connection.ConnectionHandler/<ChangeMode>d__46:MoveNext () (at Assets/_src/Scripts/PlayerFeatures/Connection/ConnectionHandler.cs:276)
Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:Start<_src.Scripts.PlayerFeatures.Connection.ConnectionHandler/<ChangeMode>d__46> (_src.Scripts.PlayerFeatures.Connection.ConnectionHandler/<ChangeMode>d__46&) (at Library/PackageCache/com.cysharp.unitask@c170af5642/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs:111)
_src.Scripts.PlayerFeatures.Connection.ConnectionHandler:ChangeMode (_src.Scripts.PlayerFeatures.Connection.ConnectionMode,single)
_src.Scripts.Core.PermanentConnectionZone:EnablePermanentMode () (at Assets/_src/Scripts/Core/PermanentConnectionZone.cs:78)
UnityEngine.Events.UnityEvent:Invoke ()
_src.Scripts.Core.TwoPlayersTrigger:CheckPlayersInTrigger () (at Assets/_src/Scripts/Core/TwoPlayersTrigger.cs:69)
_src.Scripts.Core.PermanentConnectionZone:OnTriggerStay (UnityEngine.Collider) (at Assets/_src/Scripts/Core/PermanentConnectionZone.cs:47)

Code:
_src.Scripts.PlayerFeatures.Connection.ThreadProxy_s.ThreadProxy:AttachRope () (at Assets/_src/Scripts/PlayerFeatures/Connection/ThreadProxy's/ThreadProxy.cs:124)
124 point is 
Code:
ObiRope.ropeBlueprint = _blueprint;

in AttachRope method

Iam use [6.5.2] obiRope
Reply
#2
(17-09-2024, 01:14 PM)Alexander34 Wrote: I made a rope hitch like in the Hook example. And now every time I get this error in ObiCollisionWorld when I use the above AttachRope method.

Hi,

Where are you calling AttachRope() from? Judging from your stack trace, it would seem like you are doing this from OnTriggerStay() which is a trigger callback.

You're deleting the rope and creating it anew, this triggers the collision system destruction (the DestroyImmediate call) during a trigger callback, which as the error message itself is telling you isn't allowed:

Quote:Destroying GameObjects immediately is not permitted during physics trigger/contact

Simplest workaround is to store the condition using a boolean, and attach the rope during Update() or some other callback that's not part of the triggers/collision system.

kind regards,
Reply
#3
(17-09-2024, 01:30 PM)josemendez Wrote: Hi,

Where are you calling AttachRope() from?

kind regards,
Generally from many places, I switch the state of the players and at that moment I just disable the rope object(not solver) and then enable and call AttachRope again, so that the new rope takes into account the changed position of the players in space and a new rope of a new length is generated.
The death event can be triggered by a collision with a dangerous object or trigger, it switches the player's state to death and does the above with the rope
actually everything works fine in general, but it's the regular warning that bothers me, and if I change the method to Destroy() instead of DestroyImmediately(), the burst starts complaining that it loses references to objects while executing jobs.
Reply
#4
(17-09-2024, 01:37 PM)Alexander34 Wrote: The death event can be triggered by a collision with a dangerous object or trigger, it switches the player's state to death and does the above with the rope

Right, but you can't do this operation on a collision/trigger callback. As explained, the correct way to do this is to store some indication that the rope must be attached, then do the actual AttachRope() call outside of the trigger callback.

This is similar to what you'd do for reacting for input on FixedUpdate(): you can't read input on FixedUpdate() since it may not be called every frame and you'd be missing keystrokes, so you read input in Update(), store input indicators (booleans, enums, etc) and then react to it during FixedUpdate().

(17-09-2024, 01:37 PM)Alexander34 Wrote: if I change the method to Destroy() instead of DestroyImmediately(), the burst starts complaining that it loses references to objects while executing jobs.

You can't do this, since Destroy() defers destruction until the end of the frame which is too late in this case. We use DestroyImmediate() instead for a reason.
Reply
#5
(17-09-2024, 01:30 PM)josemendez Wrote: Hi,

Where are you calling AttachRope() from? Judging from your stack trace, it would seem like you are doing this from OnTriggerStay() which is a trigger callback.

You're deleting the rope and creating it anew, this triggers the collision system destruction (the DestroyImmediate call) during a trigger callback, which as the error message itself is telling you isn't allowed:


Simplest workaround is to store the condition using a boolean, and attach the rope during Update() or some other callback that's not part of the triggers/collision system.

kind regards,
Yes cashing bool and use it in update was helpful, thank's.
But perhaps, we can unload rope more safe?
Reply
#6
(17-09-2024, 02:13 PM)Alexander34 Wrote: Yes cashing bool and use it in update was helpful, thank's.


You're welcome Guiño

(17-09-2024, 02:13 PM)Alexander34 Wrote: But perhaps, we can unload rope more safe?

Not really. Unloading the last rope in the scene causes the destruction of the collision system, which must be done using DestroyImmediate(). Doing this in response to a collision/trigger is forbidden by Unity.

kind regards,
Reply