// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using System; using System.Linq; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Input { /// /// Defines a pointer option to assign to a controller. /// [Serializable] public struct PointerOption : ISerializationCallbackReceiver { /// /// Constructor. /// public PointerOption(SupportedControllerType controllerType, Handedness handedness, GameObject pointerPrefab, LayerMask[] prioritizedLayerMasks = null) { this.controllerType = controllerType; this.handedness = handedness; this.pointerPrefab = pointerPrefab; this.prioritizedLayerMasks = prioritizedLayerMasks ?? new LayerMask[1] { UnityEngine.Physics.DefaultRaycastLayers }; } [EnumFlags] [SerializeField] [Tooltip("The type of Controller this pointer can be attached to at runtime.")] private SupportedControllerType controllerType; /// /// The type of Controller this pointer can be attached to at runtime. /// /// If is selected, then it will attach to any controller type public SupportedControllerType ControllerType => controllerType; [SerializeField] [Tooltip("Defines valid hand(s) to create the pointer prefab on.")] private Handedness handedness; /// /// Defines valid hand(s) to create the pointer prefab on. /// public Handedness Handedness => handedness; [SerializeField] [Tooltip("The prefab with an IMixedRealityPointer component to create when a valid controller becomes available.")] private GameObject pointerPrefab; /// /// The prefab with an component to create when a valid controller becomes available. /// public GameObject PointerPrefab => pointerPrefab; [SerializeField] [Tooltip("The LayerMasks, in prioritized order, which are used to determine the target.")] private LayerMask[] prioritizedLayerMasks; /// /// The LayerMasks, in prioritized order, which are used to determine the target /// public LayerMask[] PrioritizedLayerMasks { get => prioritizedLayerMasks; internal set => prioritizedLayerMasks = value; } void ISerializationCallbackReceiver.OnBeforeSerialize() { if (pointerPrefab == null) { return; } IMixedRealityPointer pointer = pointerPrefab.GetComponent(); if (pointer.IsNull() || pointer.PrioritizedLayerMasksOverride == null || pointer.PrioritizedLayerMasksOverride.Length == 0 || (prioritizedLayerMasks != null && pointer.PrioritizedLayerMasksOverride.SequenceEqual(prioritizedLayerMasks))) { return; } int pointerPrioritizedLayerMasksOverrideCount = pointer.PrioritizedLayerMasksOverride.Length; if (prioritizedLayerMasks?.Length != pointerPrioritizedLayerMasksOverrideCount) { prioritizedLayerMasks = new LayerMask[pointerPrioritizedLayerMasksOverrideCount]; } Array.Copy(pointer.PrioritizedLayerMasksOverride, prioritizedLayerMasks, pointerPrioritizedLayerMasksOverrideCount); } void ISerializationCallbackReceiver.OnAfterDeserialize() { } } }