Interact ability causing MissingReferenceException

tippington

New member
I'm working on a project where a player can open chests, much like in Fortnite. When a chest is opened, it spawns a number of pickup objects and then destroys itself. A manager script will spawn new chests every 30 seconds in any empty chest spawn spots.

My issue is, after opening a chest and going to open a different one, I'm getting the following error in the Unity console:

Code:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
Opsive.UltimateCharacterController.Character.Abilities.DetectObjectAbilityBase.CanStartAbility () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/DetectObjectAbilityBase.cs:137)
Opsive.UltimateCharacterController.Character.Abilities.Interact.CanStartAbility () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Interact.cs:99)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.TryStartAbility (Opsive.UltimateCharacterController.Character.Abilities.Ability ability, System.Boolean ignorePriority, System.Boolean ignoreCanStartCheck) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1070)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.TryStartAbility (Opsive.UltimateCharacterController.Character.Abilities.Ability ability, System.Boolean ignorePriority) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1052)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.TryStartAbility (Opsive.UltimateCharacterController.Character.Abilities.Ability ability) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1041)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler.TryStartAbility (Opsive.UltimateCharacterController.Character.Abilities.Ability ability) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotionHandler.cs:231)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler.UpdateAbilityInput (Opsive.UltimateCharacterController.Character.Abilities.Ability[] abilities) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotionHandler.cs:128)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler.UpdateAbilityInput () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotionHandler.cs:98)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler.Update () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotionHandler.cs:73)

Is there something I'm doing wrong to cause this error to appear? Here's the code for my chest object:

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Opsive.UltimateCharacterController.Traits;

public class ChestBehavior : MonoBehaviour, IInteractableTarget
{
    [Header("Config")]
    public int totalItems;
    public List<GameObject> itemList;

    [HideInInspector] public ChestSpawnBehavior thisSpawn;

    private bool isOpen;

    private const float openDur = 0.32f;
    private const float dieDelay = 0.24f;

    public bool CanInteract(GameObject obj)
    {
        return !isOpen;
    }

    public void Interact(GameObject obj)
    {
        Open();
    }

    private void Open()
    {
        if (isOpen) { return; }
        isOpen = true;
        StartCoroutine(_Open());
    }

    private IEnumerator _Open()
    {
        Debug.Log("opening chest");
        // TODO: Play open animation
        yield return new WaitForSeconds(openDur);
        List<GameObject> itemsToSpawn = new List<GameObject>();
        for (int i = 0; i < totalItems; i++)
        {
            var thisItem = itemList[Random.Range(0, itemList.Count)];
            itemsToSpawn.Add(thisItem);
            if (i == totalItems - 1) { SpawnItems(itemsToSpawn); }
        }
        yield return new WaitForSeconds(dieDelay);
        Die();
    }

    private void SpawnItems(List<GameObject> itemsToSpawn)
    {
        for (int i = 0; i < itemsToSpawn.Count; i++)
        {
            Debug.Log("spawning item with index " + i.ToString());
            Instantiate(itemsToSpawn[i], transform.position, Quaternion.identity);
            // TODO: Add burst animation to items
        }
    }

    private void Die()
    {
        thisSpawn.ChestDespawned();
        Destroy(gameObject);
    }
}

Thanks in advance. :)
 
Hard to know what's going on without more info. Also we can't really debug entire custom scripts for you because of the support load it'd put on us. However...

The first line of your error - "MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it." - should be self-explanatory enough: UCC is attempting to access a destroyed gameObject. Generally speaking, especially when it comes to item spawns and such, UCC doesn't destroy gameObjects but simply deactivates them. I'm not sure what's happening inside of "ChestDespawned()", but I'd say instead of Destroying the gameObject, simply deactivate it. Let us know how that goes.
 
Yea, a little hard to tell without more context but here's the first offending line in DetectObjectAbilityBase, line 137:

Code:
} else if (!m_DetectedTriggerObjects[i].activeInHierarchy)

Not really much going on here, but on first look I'd take this to mean there's no m_DetectedTriggerObjects... which's weird 'cause it's in a for loop that checks for m_DetectedTriggerObjectsCount.

Maybe you've got a funky setting on your object pickup or the Interact ability ain't setup correctly?

Post back some pics or the setup of those if you could, forum's p awesome, you can paste images (up to 3) right in the chat here and resize em.

Thanks =)
 
Generally speaking, especially when it comes to item spawns and such, UCC doesn't destroy gameObjects but simply deactivates them.

This was the fix that worked for me; I set up object pooling and am now de-activating the object instead of destroying it. No more errors! Thanks all for your help.
 
Top