mixedreality/com.microsoft.mixedreality..../SDK/Features/UX/Interactable/Scripts/Events/InteractableEvent.cs

108 lines
3.6 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using Microsoft.MixedReality.Toolkit.Utilities.Editor;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
namespace Microsoft.MixedReality.Toolkit.UI
{
/// <summary>
/// Event base class for events attached to Interactables.
/// </summary>
[System.Serializable]
public class InteractableEvent
{
/// <summary>
/// Base Event used to initialize EventReceiver class
/// </summary>
public UnityEvent Event = new UnityEvent();
/// <summary>
/// ReceiverBase instantiation for this InteractableEvent. Used at runtime by Interactable class
/// </summary>
[NonSerialized]
public ReceiverBase Receiver;
/// <summary>
/// Defines the type of Receiver to associate. Type must be a class that extends ReceiverBase
/// </summary>
public Type ReceiverType
{
get
{
if (receiverType == null)
{
if (string.IsNullOrEmpty(AssemblyQualifiedName))
{
return null;
}
receiverType = Type.GetType(AssemblyQualifiedName);
}
return receiverType;
}
set
{
if (!value.IsSubclassOf(typeof(ReceiverBase)))
{
Debug.LogWarning($"Cannot assign type {value} that does not extend {typeof(ReceiverBase)} to ThemeDefinition");
return;
}
if (receiverType != value)
{
receiverType = value;
ClassName = receiverType.Name;
AssemblyQualifiedName = receiverType.AssemblyQualifiedName;
}
}
}
// Unity cannot serialize System.Type, thus must save AssemblyQualifiedName
// Field here for Runtime use
[NonSerialized]
private Type receiverType;
[SerializeField]
private string ClassName;
[SerializeField]
private string AssemblyQualifiedName;
[SerializeField]
private List<InspectorPropertySetting> Settings = new List<InspectorPropertySetting>();
/// <summary>
/// Create the event and setup the values from the inspector. If the asset is invalid,
/// returns null.
/// </summary>
public static ReceiverBase CreateReceiver(InteractableEvent iEvent)
{
if (string.IsNullOrEmpty(iEvent.ClassName))
{
// If the class name of this event is empty, the asset is invalid and loading types will throw errors. Return null.
return null;
}
// Temporary workaround
// This is to fix a bug in GA where the AssemblyQualifiedName was never actually saved. Functionality would work in editor...but never on device player
if (iEvent.ReceiverType == null)
{
var correctType = TypeCacheUtility.GetSubClasses<ReceiverBase>().Where(s => s?.Name == iEvent.ClassName).First();
iEvent.ReceiverType = correctType;
}
ReceiverBase newEvent = (ReceiverBase)Activator.CreateInstance(iEvent.ReceiverType, iEvent.Event);
InspectorGenericFields<ReceiverBase>.LoadSettings(newEvent, iEvent.Settings);
return newEvent;
}
}
}