visualdesigncafe / nature-renderer

Nature Renderer is a plugin for the Unity game engine to efficiently render vegetation on your terrains.
https://visualdesigncafe.com/nature-renderer/
0 stars 0 forks source link

IndexOutOfRangeException: Index was outside the bounds of the array. #78

Open Jaakk0S opened 1 day ago

Jaakk0S commented 1 day ago

Sometimes the DLL starts throwing this exception and will not stop until recompile. It is somehow related to instantiating NatureInstances in an editor script.

I have a procedural instantiation script that runs in edit mode at the click of an editor button. It takes objects in the scene and instantiates new instances based on those objects. Some of those instantiated objects have NatureInstance components. These objects work fine under NI.

My procuderal script can process individual objects and groups of objects. If I run it on a single NatureInstance gameobject, it works fine with any object and 100% of times. But when I run it for a group of objects (multiple objects instantiated in the same Editor frame), 100% of times what happens is the script works fine except that this error starts filling the log:

IndexOutOfRangeException: Index was outside the bounds of the array. VisualDesignCafe.Rendering.Nature.NatureInstanceStreamer.ClearEmptyCells () (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Nature/NatureInstanceStreamer.cs:288) VisualDesignCafe.Rendering.Nature.NatureInstanceStreamer.GetBuffersForCellsInRange (UnityEngine.Camera camera, System.Int32 frameId, System.Double range, VisualDesignCafe.Rendering.Instancing.CullingSettings cullingSettings, System.Collections.Generic.List1[T] buffers) (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Nature/NatureInstanceStreamer.cs:212) VisualDesignCafe.Rendering.Instancing.CameraRenderer.RenderObject (VisualDesignCafe.Rendering.Instancing.CameraRenderer+ObjectRenderData obj, VisualDesignCafe.Rendering.Instancing.SceneRenderSettings& sceneSettings) (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Instancing/CameraRenderer.cs:343) VisualDesignCafe.Rendering.Instancing.CameraRenderer.Render () (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Instancing/CameraRenderer.cs:266) VisualDesignCafe.Rendering.Instancing.FrameRenderer.OnBeginContextRendering (UnityEngine.Rendering.ScriptableRenderContext context, System.Collections.Generic.List1[T] cameras) (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Instancing/FrameRenderer.cs:36) UnityEngine.Debug:LogException(Exception) VisualDesignCafe.Rendering.Instancing.FrameRenderer:OnBeginContextRendering(ScriptableRenderContext, List1) (at C:/Visual Design Cafe/Projects/Nature Renderer/Unity/Nature Renderer 2021/Assets/Visual Design Cafe/Nature Renderer/Plugins/Runtime/VisualDesignCafe.Rendering.Instancing/FrameRenderer.cs:40) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)`

After having instantiated the object and edited its transform, I am calling Refresh() on it, so that's not the issue.

Based on error message looks like a simple indexing bug. But not much debugging can be done because it happens inside the DLL.

Version 2021.2.1 on Unity 2021.3.32f1

Jaakk0S commented 1 day ago

Ok, I found a way to work around the issue.

Before instantiating, I am disabling the NatureInstance component. Then after instantiating and working with the instance's transform, I delete the NI component and recreate it manually. Then the instance is registered to NatureRenderer and no errors.

        foreach (var instance in this.GeneratedObjects) {
            NatureInstance ni = instance.GetComponent<NatureInstance>();
            if (ni) {
                GameObject prefab = ni.Prefab;
                DestroyImmediate(ni);
                ni = instance.AddComponent<NatureInstance>();
                ni.Prefab = prefab;
            }
        }