#if VISUALSCRIPTING_1_8_OR_NEWER using System; using System.Collections.Generic; using System.Text; using Unity.VisualScripting; using UnityEngine.SubsystemsImplementation; using UnityEngine.XR.ARSubsystems; namespace UnityEngine.XR.ARFoundation.VisualScripting { /// /// Outputs all trackables managed by the input ARTrackableManager using its /// property. /// /// The AR Trackable Manager type. /// The tracking subsystem type. /// The subsystem descriptor type. /// The subsystem provider type. /// The session relative data type. /// The AR Trackable type. /// /// is not a serializable type, therefore we need a custom unit to /// copy the contents into a serializable List to use this data in a visual scripting context. /// public abstract class GetTrackablesUnit : Unit where TManager : ARTrackableManager where TSubsystem : TrackingSubsystem, new() where TSubsystemDescriptor : SubsystemDescriptorWithProvider where TProvider : SubsystemProvider where TSessionRelativeData : struct, ITrackable where TTrackable : ARTrackable { const string k_ManagerInPortLabel = "Manager"; // Used by GetTrackablesUnitDescriptor in the Editor assembly internal const string k_TrackablesInPortLabel = "List"; static bool s_IsFirstFrame = true; StringBuilder m_LogBuilder = new(); /// /// Flow input. /// [DoNotSerialize] [PortLabelHidden] public ControlInput flowIn { get; private set; } /// /// Flow output. /// [DoNotSerialize] [PortLabelHidden] public ControlOutput flowOut { get; private set; } /// /// AR Trackable Manager input. /// [DoNotSerialize] [PortLabel(k_ManagerInPortLabel)] public ValueInput managerIn { get; private set; } [DoNotSerialize] [PortLabel(k_TrackablesInPortLabel)] public ValueInput trackablesIn { get; private set; } /// /// Outputs a . /// [DoNotSerialize] [PortLabel(k_TrackablesInPortLabel)] public ValueOutput trackablesOut { get; private set; } protected override void Definition() { flowIn = ControlInput(nameof(flowIn), ProcessFlow); flowOut = ControlOutput(nameof(flowOut)); managerIn = ValueInput(nameof(managerIn)); trackablesIn = ValueInput>(nameof(trackablesIn)); trackablesOut = ValueOutput>(nameof(trackablesOut)); Requirement(managerIn, flowIn); Requirement(trackablesIn, flowIn); Succession(flowIn, flowOut); Assignment(flowIn, trackablesOut); } ControlOutput ProcessFlow(Flow flow) { var manager = flow.GetValue(managerIn) as ARTrackableManager; if (manager == null) { manager = Object.FindAnyObjectByType>(); } if (manager == null) throw new InvalidOperationException( $"Attempted to execute the {graph.title} Visual Scripting graph, which requires an active and enabled {typeof(TManager)} in your scene, but none was found."); if (!managerIn.hasValidConnection && s_IsFirstFrame) { if (managerIn.hasAnyConnection) m_LogBuilder.Append($"{k_ManagerInPortLabel} Input Port on {GetType().Name} in {graph.title} graph has an invalid connection."); else m_LogBuilder.Append($"{k_ManagerInPortLabel} Input Port on {GetType().Name} in {graph.title} graph is disconnected."); m_LogBuilder.Append(" AR Foundation searched and found a valid manager in your scene to fill this dependency," + " but for improved performance you should ensure that this port connection is valid."); Debug.LogWarning(m_LogBuilder.ToString()); m_LogBuilder.Clear(); } if (flow.GetValue(trackablesIn) is not List trackables) { trackables = new List(); if (s_IsFirstFrame) { if (trackablesIn.hasAnyConnection) m_LogBuilder.Append($"{k_TrackablesInPortLabel} Input Port on {GetType().Name} in {graph.title} graph has an invalid connection."); else m_LogBuilder.Append($"{k_TrackablesInPortLabel} Input Port on {GetType().Name} in {graph.title} graph is disconnected."); m_LogBuilder.Append(" AR Foundation allocated a new list to use as output, but this memory will require garbage collection." + " For improved performance you should ensure that this port connection is valid."); } } s_IsFirstFrame = false; trackables.Clear(); foreach (var t in manager.trackables) { trackables.Add(t); } flow.SetValue(trackablesOut, trackables); return flowOut; } } } #endif // VISUALSCRIPTING_1_8_OR_NEWER