// 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() { }
}
}