Framerate drops while hovering over inventory
ducakar opened this issue ยท 4 comments
Significant framerate drop (to only a few frames per second) occurs when hovering a mouse cursor over an inventory window during the flight scene.
There are no messages printed to the log. It only occurs during flight, it works fine in editor.
FindObjectsOfType() call in ModuleKISInventory.cs:835 seems to be the cause of this. Functions like Object.FindObjectsOfType(), Resources.FindObjectsOfTypeAll() etc. are extremly slow and should be avoided whereever possible, especially in methods that are called per-frame. A single such call per frame has drastic impact on framerate.
I've gotten this as well.
Theres also some camera wierdness going on in the VAB.SPH that might be related.
The lag is particularily bad when at a base that is already laggy
The call to FindObjectsOfType in ModuleKISInventory can be eliminated by adding a component to the window prefab which updates a static list of open UIPartActionWindows. Example:
[KSPAddon(KSPAddon.Startup.EditorAny, true)]
public class InitPartActionWindowTracker : MonoBehaviour
{
private void Awake() { UIPartActionWindowTracker.Init(); }
}
[KSPAddon(KSPAddon.Startup.Flight, true)]
public class FlightBootstrapper : InitPartActionWindowTracker
{
}
public class UIPartActionWindowTracker
{
private class WindowTrackerComponent : MonoBehaviour
{
private void Awake() { Add(GetComponent<UIPartActionWindow>()); }
private void OnDestroy() { Remove(GetComponent<UIPartActionWindow>()); }
}
public static readonly List<UIPartActionWindow> Windows = new List<UIPartActionWindow>();
public static void Init()
{
if (UIPartActionController.Instance.windowPrefab.gameObject.GetComponent<WindowTrackerComponent>() == null)
UIPartActionController.Instance.windowPrefab.gameObject.AddComponent<WindowTrackerComponent>();
}
private static void Add(UIPartActionWindow window)
{
if (window != null && !Windows.Contains(window))
Windows.Add(window);
}
private static void Remove(UIPartActionWindow window)
{
if (window != null && Windows.Contains(window))
Windows.Remove(window);
}
}
Then this line:
foreach (var window in GameObject.FindObjectsOfType(typeof(UIPartActionWindow))
.OfType<UIPartActionWindow>().Where(p => p.Display == UIPartActionWindow.DisplayType.Selected))
could be changed to
foreach (var window in UIPartActionWindowTracker.Windows.Where(p => p.Display == UIPartActionWindow.DisplayType.Selected)
and avoid the performance penalty