Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Missing Ref Exception when deleting Obi Cloth
#1
I've encountered this error when I attempt to Destroy() a obi cloth object in the scene that has been instantiated and then create a new obi cloth object in its place. This issue does not occur if I Destroy the object first then instantiate a new one afterward in a separate method, but I cannot perform the Destruction in the same method without receiving this error for the missing ObiSkinnedClothBlueprint. Is there a way I can disable this one the obi cloth to be destroyed to prevent this error?



Code:
MissingReferenceException: The object of type 'ObiSkinnedClothBlueprint' 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.
UnityEngine.Object.Instantiate[T] (T original) (at <fe84f4a754da4a6bb64fca409d40938a>:0)
Obi.ObiActor.StoreState () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:1028)
Obi.ObiActor.UnloadBlueprint (Obi.ObiSolver solver) (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:1071)
Obi.ObiClothBase.UnloadBlueprint (Obi.ObiSolver solver) (at Assets/Obi/Scripts/Cloth/Actors/ObiClothBase.cs:179)
Obi.ObiSolver.RemoveActor (Obi.ObiActor actor) (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:1114)
Obi.ObiActor.RemoveFromSolver () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:326)
Obi.ObiActor.OnDisable () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:292)
Obi.ObiSkinnedCloth.OnDisable () (at Assets/Obi/Scripts/Cloth/Actors/ObiSkinnedCloth.cs:123)
UnityEngine.Object:DestroyImmediate(Object, Boolean)
OutfitChanger_Fem:DeleteClothingItem() (at Assets/Scripts/OutfitChanger_Fem.cs:181)
OutfitChanger_Fem:LoadOutfitBundlePrefab(String) (at Assets/Scripts/OutfitChanger_Fem.cs:172)
UnityEngine.EventSystems.EventSystem:Update() (at C:/Program Files/Unity/Hub/Editor/2020.1.15f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:376)
Reply
#2
(26-02-2021, 09:45 PM)fluidman84 Wrote: I've encountered this error when I attempt to Destroy() a obi cloth object in the scene that has been instantiated and then create a new obi cloth object in its place. This issue does not occur if I Destroy the object first then instantiate a new one afterward in a separate method, but I cannot perform the Destruction in the same method without receiving this error for the missing ObiSkinnedClothBlueprint. Is there a way I can disable this one the obi cloth to be destroyed to prevent this error?



Code:
MissingReferenceException: The object of type 'ObiSkinnedClothBlueprint' 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.
UnityEngine.Object.Instantiate[T] (T original) (at <fe84f4a754da4a6bb64fca409d40938a>:0)
Obi.ObiActor.StoreState () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:1028)
Obi.ObiActor.UnloadBlueprint (Obi.ObiSolver solver) (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:1071)
Obi.ObiClothBase.UnloadBlueprint (Obi.ObiSolver solver) (at Assets/Obi/Scripts/Cloth/Actors/ObiClothBase.cs:179)
Obi.ObiSolver.RemoveActor (Obi.ObiActor actor) (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:1114)
Obi.ObiActor.RemoveFromSolver () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:326)
Obi.ObiActor.OnDisable () (at Assets/Obi/Scripts/Common/Actors/ObiActor.cs:292)
Obi.ObiSkinnedCloth.OnDisable () (at Assets/Obi/Scripts/Cloth/Actors/ObiSkinnedCloth.cs:123)
UnityEngine.Object:DestroyImmediate(Object, Boolean)
OutfitChanger_Fem:DeleteClothingItem() (at Assets/Scripts/OutfitChanger_Fem.cs:181)
OutfitChanger_Fem:LoadOutfitBundlePrefab(String) (at Assets/Scripts/OutfitChanger_Fem.cs:172)
UnityEngine.EventSystems.EventSystem:Update() (at C:/Program Files/Unity/Hub/Editor/2020.1.15f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:376)

Hi, can you post the code that results in this error? keep in mind that Destroy() does not destroy the object immediately, it just marks it for destruction at the end of the frame. This can lead to subtle bugs.
Reply
#3
Hi Jose,

Here is the code that is loading Asset Bundles and resulting the error when attempting to Destroy the instance from the Asset Bundle. 


Code:
public GameObject femModel;

    AssetBundle myLoadedAssetbundle;
    public string path;
    public string prefabName;
    public GameObject prefab;
    public GameObject newClone;

    void LoadAssetBundle(string bundleUrl)
    {

        if (myLoadedAssetbundle != null)
        {
            myLoadedAssetbundle.Unload(true);
        }

        myLoadedAssetbundle = AssetBundle.LoadFromFile(bundleUrl);

        Debug.Log(myLoadedAssetbundle == null ? " failed to load AssetBundle" : " AssetBundle successfully loaded");
    }

    void InstatiateObjectFromBundle(string assetName)
    {
        prefab = myLoadedAssetbundle.LoadAsset<GameObject>(assetName);
        newClone = Instantiate(prefab, transform.position, transform.rotation, femModel.transform);
    }

    public void LoadOutfitAssetBundle(string path)
    {
        LoadAssetBundle(path);
    }

    public void LoadOutfitBundlePrefab(string prefabName)
    {
        DeleteClothingItem();
        InstatiateObjectFromBundle(prefabName);
    }

    public void DeleteClothingItem ()
    {
        if (newClone != null)
        {
            DestroyImmediate(newClone, true);
        }
    }

If I call the DeleteClothingItem separately everything works fine. It's only when calling DeleteClothingItem while InstatiateObjectFromBundle in same method that the error and subsequent crash occurs.
Reply
#4
Hi there!

I've been testing your code, but I'm so far unable to reproduce the issue. This is the setup I have:

- Created an AssetBundle out of a few cloth prefabs.

- Empty scene, one GameObject with your script (named BundleLoader). Added a call to LoadOutfitAssetBundle() in its Awake() method, added a couple calls to LoadOutfitBundlePrefab() in Update(), passing different prefab names whenever I press various keyboard keys like so:

Code:
public void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
           LoadOutfitBundlePrefab(prefabs[0]);

        if (Input.GetKeyDown(KeyCode.B))
           LoadOutfitBundlePrefab(prefabs[1]);
       
//....etc
    }

- Created a ObiSolver+FixedUpdater GameObject, passing it to your script as the "FemModel". This way, prefabs are instantiated under the solver and simulated right away.

- Run the scene, press the prefab keys at random to load a new prefab each time, unloading the previous one. Works fine, no errors pop up.

can you spot any appreciable difference with what you're doing?
cheers,

Quote:If I call the DeleteClothingItem separately everything works fine. It's only when calling DeleteClothingItem while InstatiateObjectFromBundle in same method that the error and subsequent crash occurs.

I don't see any difference when calling them separate + together. Unless they're called at different points in time (different frames, by using a coroutine, or just calling them in response to different user input) there's no actual difference in calling them in the same method or different methods.
Reply
#5
Thank you for testing that! 

Yes, after you verified the execution order I found that the loaded Asset Bundle was being destroyed before the prefab was instantiated to the scene. Once I changed the execution order of the instance and the destroy commands, everything is working as it should.
Reply
#6
(03-03-2021, 08:20 PM)fluidman84 Wrote: Thank you for testing that! 

Yes, after you verified the execution order I found that the loaded Asset Bundle was being destroyed before the prefab was instantiated to the scene. Once I changed the execution order of the instance and the destroy commands, everything is working as it should.

Glad you got it working! Sonrisa
Reply