Interact Destroy Problem

atmuc

Member
After interact stop I destroy interactable object. Because interact can't get TriggerExit event it still keeps m_DetectedTriggerObjectsCount. So I get "Error: The maximum number of trigger objects should be increased on the Interact ability." error and can't start ability.
 
UCC 3.0.8
Unity 2022.2.12
Max trigger object count=1
Enter interactable collider
Interact
Stop interact
destroy interactable object ( so trigger exit will not work for DetectObjectAbilityBase)
try to enter another interactable collider with the same interactable ID and try interact
you will get Error: The maximum number of trigger objects should be increased on the Interact ability.
Because m_DetectedTriggerObjectsCount=1 instead of 0. so you cannot start interact ability.

When you destroy a trigger after another collider entered in, trigger exit will not called. this is how unity works. in this case ability keeps m_DetectedTriggerObjectsCount as 1 and m_DetectedTriggerObjects[0] = null.
 
Thank you. You can fix this by adding the following to DetectObjectAbilityBase.cs:

Code:
        public override void Update()
        {
            base.Update();

            // Account for triggers that are destroyed or deactivated when the ability is active.
            if ((m_ObjectDetection & ObjectDetectionMode.Trigger) != 0) {
                for (int i = 0; i < m_DetectedTriggerObjectsCount; ++i) {
                    if (m_DetectedTriggerObjects[i] == null || !m_DetectedTriggerObjects[i].activeInHierarchy) {
                        m_DetectedTriggerObjects[i] = null;
                        // Ensure there is not a gap in the trigger object elements.
                        for (int j = i; j < m_DetectedTriggerObjectsCount - 1; ++j) {
                            m_DetectedTriggerObjects[j] = m_DetectedTriggerObjects[j + 1];
                        }
                        m_DetectedTriggerObjectsCount--;

                        // The detected object should be assigned to the oldest trigger object. This value may be null.
                        DetectedObject = m_DetectedTriggerObjects[0];
                    }
                }
            }
        }
 
Thanks @Justin. Is it the best way to place that check in Update function? Instead of running this on each update, placing it in DetectObjectAbilityBase/CanStartAbility should be better. In my case I just need that check, when I try to start ability. It can be a function called ValidateDetectedTriggerObjects like ValidateObject in DetectObjectAbilityBase. It can be called when it is necessary. I hope I could explain my suggestion.
 
Ah, so the ability isn't active. In that situation that code should be placed in InactiveUpdate. It would be nice if there was a generic way to have a callback when an object is destroyed but that would require you to add a component to each potential trigger. I could add a bool check which indicates if you want to check within the update loop, though that code really won't cause any performance issues.
 
I can add a component to my destroyable object for generic callback.

Or you can add "Destroy interactable" feature to Interact ability with delay property. So it can destroy interactable after interaction completed.
 
Top