using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.XR.Interaction.Toolkit.Utilities;
namespace UnityEngine.XR.Interaction.Toolkit.UI
{
///
/// Keeps track of canvases in a scene and optimizes them by removing unnecessary components in nested canvases and canvases out of view.
///
[AddComponentMenu("Event/Canvas Optimizer", 11)]
[HelpURL(XRHelpURLConstants.k_CanvasOptimizer)]
public class CanvasOptimizer : MonoBehaviour
{
class CanvasState
{
const float k_CanvasCheckInterval = 0.5f;
class CanvasSettings
{
public bool present { get; set; }
AdditionalCanvasShaderChannels m_AdditionalShaderChannels;
float m_NormalizedSortingGridSize;
bool m_OverridePixelPerfect;
bool m_OverrideSorting;
float m_PlaneDistance;
float m_ReferencePixelsPerUnit;
RenderMode m_RenderMode;
float m_ScaleFactor;
int m_SortingLayerID;
string m_SortingLayerName;
int m_SortingOrder;
int m_TargetDisplay;
public void CopyFrom(Canvas source)
{
m_AdditionalShaderChannels = source.additionalShaderChannels;
m_NormalizedSortingGridSize = source.normalizedSortingGridSize;
m_OverridePixelPerfect = source.overridePixelPerfect;
m_OverrideSorting = source.overrideSorting;
m_PlaneDistance = source.planeDistance;
m_ReferencePixelsPerUnit = source.referencePixelsPerUnit;
m_RenderMode = source.renderMode;
m_ScaleFactor = source.scaleFactor;
m_SortingLayerID = source.sortingLayerID;
m_SortingLayerName = source.sortingLayerName;
m_SortingOrder = source.sortingOrder;
m_TargetDisplay = source.targetDisplay;
}
public void CopyTo(Canvas dest)
{
dest.additionalShaderChannels = m_AdditionalShaderChannels;
dest.normalizedSortingGridSize = m_NormalizedSortingGridSize;
dest.overridePixelPerfect = m_OverridePixelPerfect;
dest.overrideSorting = m_OverrideSorting;
dest.planeDistance = m_PlaneDistance;
dest.referencePixelsPerUnit = m_ReferencePixelsPerUnit;
dest.renderMode = m_RenderMode;
dest.scaleFactor = m_ScaleFactor;
dest.sortingLayerID = m_SortingLayerID;
dest.sortingLayerName = m_SortingLayerName;
dest.sortingOrder = m_SortingOrder;
dest.targetDisplay = m_TargetDisplay;
}
}
class CanvasScalerSettings
{
public bool present { get; set; }
float m_DefaultSpriteDPI;
float m_DynamicPixelsPerUnit;
float m_FallbackScreenDPI;
float m_MatchWidthOrHeight;
CanvasScaler.Unit m_PhysicalUnit;
float m_ReferencePixelsPerUnit;
Vector2 m_ReferenceResolution;
float m_ScaleFactor;
CanvasScaler.ScreenMatchMode m_ScreenMatchMode;
CanvasScaler.ScaleMode m_UiScaleMode;
public void CopyFrom(CanvasScaler source)
{
m_DefaultSpriteDPI = source.defaultSpriteDPI;
m_DynamicPixelsPerUnit = source.dynamicPixelsPerUnit;
m_FallbackScreenDPI = source.fallbackScreenDPI;
m_MatchWidthOrHeight = source.matchWidthOrHeight;
m_PhysicalUnit = source.physicalUnit;
m_ReferencePixelsPerUnit = source.referencePixelsPerUnit;
m_ReferenceResolution = source.referenceResolution;
m_ScaleFactor = source.scaleFactor;
m_ScreenMatchMode = source.screenMatchMode;
m_UiScaleMode = source.uiScaleMode;
}
public void CopyTo(CanvasScaler dest)
{
dest.defaultSpriteDPI = m_DefaultSpriteDPI;
dest.dynamicPixelsPerUnit = m_DynamicPixelsPerUnit;
dest.fallbackScreenDPI = m_FallbackScreenDPI;
dest.matchWidthOrHeight = m_MatchWidthOrHeight;
dest.physicalUnit = m_PhysicalUnit;
dest.referencePixelsPerUnit = m_ReferencePixelsPerUnit;
dest.referenceResolution = m_ReferenceResolution;
dest.scaleFactor = m_ScaleFactor;
dest.screenMatchMode = m_ScreenMatchMode;
dest.uiScaleMode = m_UiScaleMode;
}
}
class GraphicRaycasterSettings
{
public bool present { get; set; }
LayerMask m_BlockingMask;
GraphicRaycaster.BlockingObjects m_BlockingObjects;
bool m_IgnoreReversedGraphics;
public void CopyFrom(GraphicRaycaster source)
{
m_BlockingMask = source.blockingMask;
m_BlockingObjects = source.blockingObjects;
m_IgnoreReversedGraphics = source.ignoreReversedGraphics;
}
public void CopyTo(GraphicRaycaster dest)
{
dest.blockingMask = m_BlockingMask;
dest.blockingObjects = m_BlockingObjects;
dest.ignoreReversedGraphics = m_IgnoreReversedGraphics;
}
}
CanvasTracker m_Tracker;
readonly CanvasSettings m_CanvasSettings = new CanvasSettings();
readonly CanvasScalerSettings m_CanvasScalerSettings = new CanvasScalerSettings();
readonly GraphicRaycasterSettings m_GraphicRaycasterSettings = new GraphicRaycasterSettings();
bool m_WasNested;
bool m_Nested;
bool m_RaysDisabled;
Canvas m_Canvas;
GraphicRaycaster m_Raycaster;
TrackedDeviceGraphicRaycaster m_TrackedDeviceGraphicRaycaster;
float m_CheckTimer;
internal void Initialize(CanvasTracker tracker)
{
m_Tracker = tracker;
var go = m_Tracker.gameObject;
go.TryGetComponent(out m_Canvas);
go.TryGetComponent(out m_Raycaster);
CheckForNestedChanges(true);
}
internal void CheckForNestedChanges(bool force = false)
{
if (!m_Tracker.transformDirty && !force)
return;
m_Tracker.transformDirty = false;
var transform = m_Tracker.transform;
// Check for nesting
var parent = transform.parent;
var parentCanvas = parent != null ? parent.GetComponentInParent