예제 #1
0
    private void SourceFound(InteractionSourceDetectedEventArgs obj)
    {
        if (obj.state.source.kind.ToString() != "Hand")
        {
            return;
        }

        InteractionSource source = obj.state.source;

        //Rob: I am destroying the mesh renderers for the hands spheres.
        if (handOne.obj == null)
        {
            handOne.obj = Instantiate(HandPrefab);
            handOne.obj.GetComponent <HandObject.Hand>().handDetection = this;
            handOne.obj.transform.localScale = scale;
            handOne.ID = obj.state.source.id;

            if (obj.state.sourcePose.TryGetPosition(out handOne.pos))
            {
                handOne.obj.transform.position = handOne.pos;
            }
        }
        else if (handTwo.obj == null)
        {
            handTwo.obj = Instantiate(HandPrefab);
            handTwo.obj.GetComponent <HandObject.Hand>().handDetection = this;
            handTwo.obj.transform.localScale = scale;
            handTwo.ID = obj.state.source.id;

            if (obj.state.sourcePose.TryGetPosition(out handTwo.pos))
            {
                handTwo.obj.transform.position = handTwo.pos;
            }
        }
    }
        /// <summary>
        /// When a controller is lost, the model is destroyed and the controller object
        /// is removed from the tracking dictionary.
        /// </summary>
        /// <param name="obj">The source event args to be used to determine the controller model to be removed.</param>
        private void InteractionManager_InteractionSourceLost(InteractionSourceLostEventArgs obj)
        {
            InteractionSource source = obj.state.source;

            if (source.kind == InteractionSourceKind.Controller)
            {
                MotionControllerInfo controllerInfo;
                if (controllerDictionary != null && controllerDictionary.TryGetValue(GenerateKey(source), out controllerInfo))
                {
                    if (OnControllerModelUnloaded != null)
                    {
                        OnControllerModelUnloaded(controllerInfo);
                    }

                    if (controllerInfo.Handedness == InteractionSourceHandedness.Left)
                    {
                        leftControllerModel = null;
                    }
                    else if (controllerInfo.Handedness == InteractionSourceHandedness.Right)
                    {
                        rightControllerModel = null;
                    }

                    controllerInfo.ControllerParent.SetActive(false);
                }
            }
        }
예제 #3
0
 private void StartTrackingController(InteractionSource source)
 {
     if (source.kind == InteractionSourceKind.Controller && !controllerDictionary.ContainsKey(source.id))
     {
         StartCoroutine(LoadControllerModel(source));
     }
 }
        private IEnumerator LoadControllerModel(InteractionSource source)
        {
            loadingControllers.Add(GenerateKey(source));

            if (AlwaysUseAlternateLeftModel && source.handedness == InteractionSourceHandedness.Left)
            {
                if (AlternateLeftController == null)
                {
                    Debug.LogWarning("Always use the alternate left model is set on " + name + ", but the alternate left controller model was not specified.");
                    yield return(LoadSourceControllerModel(source));
                }
                else
                {
                    LoadAlternateControllerModel(source);
                }
            }
            else if (AlwaysUseAlternateRightModel && source.handedness == InteractionSourceHandedness.Right)
            {
                if (AlternateRightController == null)
                {
                    Debug.LogWarning("Always use the alternate right model is set on " + name + ", but the alternate right controller model was not specified.");
                    yield return(LoadSourceControllerModel(source));
                }
                else
                {
                    LoadAlternateControllerModel(source);
                }
            }
            else
            {
                yield return(LoadSourceControllerModel(source));
            }
        }
예제 #5
0
        /// <summary>
        /// Remove the selected controller from the Active Store
        /// </summary>
        /// <param name="interactionSourceState">Source State provided by the SDK to remove</param>
        private void RemoveController(InteractionSource interactionSource)
        {
            var controller = GetOrAddController(interactionSource, false);

            if (controller != null)
            {
                Service?.RaiseSourceLost(controller.InputSource, controller);

                foreach (IMixedRealityPointer pointer in controller.InputSource.Pointers)
                {
                    if (pointer != null)
                    {
                        pointer.Controller = null;
                    }
                }

                var visualizer = controller.Visualizer;

                if (visualizer != null && !visualizer.Equals(null) &&
                    visualizer.GameObjectProxy != null)
                {
                    visualizer.GameObjectProxy.SetActive(false);
                }
            }

            activeControllers.Remove(interactionSource.id);
        }
        public static void StartHaptics(this InteractionSource interactionSource, float intensity, float durationInSeconds)
        {
#if !UNITY_EDITOR && UNITY_2017_2_OR_NEWER
            UnityEngine.WSA.Application.InvokeOnUIThread(() =>
            {
                IReadOnlyList <SpatialInteractionSourceState> sources = SpatialInteractionManager.GetForCurrentView().GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));

                foreach (SpatialInteractionSourceState sourceState in sources)
                {
                    if (sourceState.Source.Id.Equals(interactionSource.id))
                    {
                        SimpleHapticsController simpleHapticsController = sourceState.Source.Controller.SimpleHapticsController;
                        foreach (SimpleHapticsControllerFeedback hapticsFeedback in simpleHapticsController.SupportedFeedback)
                        {
                            if (hapticsFeedback.Waveform.Equals(ContinuousBuzzWaveform))
                            {
                                if (durationInSeconds.Equals(float.MaxValue))
                                {
                                    simpleHapticsController.SendHapticFeedback(hapticsFeedback, intensity);
                                }
                                else
                                {
                                    simpleHapticsController.SendHapticFeedbackForDuration(hapticsFeedback, intensity, TimeSpan.FromSeconds(durationInSeconds));
                                }
                                return;
                            }
                        }
                    }
                }
            }, true);
#endif
        }
        private void StartTrackingController(InteractionSource source)
        {
            string key = GenerateKey(source);

            MotionControllerInfo controllerInfo;

            if (source.kind == InteractionSourceKind.Controller)
            {
                if (!controllerDictionary.ContainsKey(key) && !loadingControllers.Contains(key))
                {
                    StartCoroutine(LoadControllerModel(source));
                }
                else if (controllerDictionary.TryGetValue(key, out controllerInfo))
                {
                    if (controllerInfo.Handedness == InteractionSourceHandedness.Left)
                    {
                        leftControllerModel = controllerInfo;
                    }
                    else if (controllerInfo.Handedness == InteractionSourceHandedness.Right)
                    {
                        rightControllerModel = controllerInfo;
                    }

                    controllerInfo.ControllerParent.SetActive(true);

                    if (OnControllerModelLoaded != null)
                    {
                        OnControllerModelLoaded(controllerInfo);
                    }
                }
            }
        }
        private IEnumerator Attach(GameObject target, Transform parent, InteractionSource source)
        {
            yield return(ControllerHelpers.AttachModel(target, parent, source, GLTFMaterial, GLTFMaterial));

            inProgressSources.Remove(source.id);
            FinishControllerSetup(target, source.handedness.ToString(), source.id);

            if (ShowDebugAxis)
            {
                TraceHelper.LogOnUnityThread("Attaching Debug Axis to " + source.handedness);
                if (source.handedness == InteractionSourceHandedness.Left)
                {
                    axisRendererLeft = target.AddComponent <AxisRenderer>();
                }
                else
                {
                    axisRendererRight = target.AddComponent <AxisRenderer>();
                }
            }

#if SKIPNPUTMODULE
            WinMRSnippets.Samples.Input.MotionControllerInputModule.Instance.AddController(source.id);
            WinMRSnippets.Samples.Input.MotionControllerInputModule.Instance.AddController(source.id);
#endif
        }
        /// <summary>
        /// Remove the selected controller from the Active Store
        /// </summary>
        /// <param name="interactionSourceState">Source State provided by the SDK to remove</param>
        private void RemoveController(InteractionSource interactionSource)
        {
            var controller = GetController(interactionSource, false);

            if (controller != null)
            {
                IMixedRealityInputSystem inputSystem = Service as IMixedRealityInputSystem;

                inputSystem?.RaiseSourceLost(controller.InputSource, controller);

                foreach (IMixedRealityPointer pointer in controller.InputSource.Pointers)
                {
                    if (pointer != null)
                    {
                        pointer.Controller = null;
                    }
                }

                if (controller.Visualizer != null &&
                    controller.Visualizer.GameObjectProxy != null)
                {
                    controller.Visualizer.GameObjectProxy.SetActive(false);
                }
            }

            activeControllers.Remove(interactionSource.id);
        }
        private IEnumerator Attach(GameObject target, Transform parent, InteractionSource source)
        {
            yield return(ControllerHelpers.AttachModel(target, parent, source, GLTFMaterial, GLTFMaterial));

            if (AnimateControllerModel)
            {
                var newControllerInfo = new MotionControllerInfo()
                {
                };
                newControllerInfo.LoadInfo(target.GetComponentsInChildren <Transform>(), this);
                controllerInfoForAnimation.Add(source.id, newControllerInfo);
                TraceHelper.Log("Controller added for animation");
            }

            if (ShowDebugAxis)
            {
                if (source.handedness == InteractionSourceHandedness.Left)
                {
                    axisRendererLeft = target.AddComponent <AxisRenderer>();
                }
                else
                {
                    axisRendererRight = target.AddComponent <AxisRenderer>();
                }
            }
        }
 private void AddDevice(InteractionSource source)
 {
     if (!imDevices.ContainsKey(source.id))
     {
         TraceHelper.Log("MotionControllerInput:AddDevice:" + source.id);
         CreateControllerVisual(source);
     }
 }
예제 #12
0
        void InitializeSelf(InteractionSource source)
        {
#if DEBUG
            Debug.Assert(SourceId == defaultValue, "We expect to never initialize this instance without a proper SourceLost");
#endif
            SourceId = source.id;
            IsActive = true;
            UpdateControllerProperties(source);
        }
        protected virtual void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args)
        {
            InteractionSourceState state  = args.state;
            InteractionSource      source = state.source;

            if (source.kind == InteractionSourceKind.Controller && source.handedness == handedness)
            {
                SetupController(source);
            }
        }
    void CreateControllerVisual(InteractionSource source)
    {
        GameObject go = new GameObject();

        go.transform.parent  = ControllersRoot;
        go.name              = "Controller" + source.id;
        imDevices[source.id] = go.transform;
        InputState.Current.DetectedControllers = this.imDevices.Keys.Count;
        var coroutine = StartCoroutine(Attach(go, ControllersRoot, source));
    }
        protected virtual void InteractionManager_InteractionSourceReleased(InteractionSourceReleasedEventArgs args)
        {
            InteractionSourceState state  = args.state;
            InteractionSource      source = state.source;

            if (source.kind == InteractionSourceKind.Controller && source.handedness == handedness)
            {
                UpdateButtonState(args.pressType, state);
            }
        }
예제 #16
0
        // Get the handedness of a source
        private bool CorrectHand(InteractionSource source)
        {
            if (_handedness.HasFlag(TrackerHandedness.Left | TrackerHandedness.Right))
            {
                return(true);
            }

            return((source.handedness == InteractionSourceHandedness.Right)
                   == (TrackerHandedness.Right == _handedness));
        }
        /// <summary>
        /// Remove the selected controller from the Active Store
        /// </summary>
        /// <param name="interactionSourceState">Source State provided by the SDK to remove</param>
        private void RemoveController(InteractionSource interactionSource)
        {
            var controller   = GetOrAddController(interactionSource, false);
            var controllerId = GetControllerId(interactionSource);

            if (controller != null)
            {
                RemoveControllerFromScene(controller);
                activeControllers.Remove(controllerId);
            }
        }
        private void StartTrackingController(InteractionSource source)
        {
            if (source.kind == InteractionSourceKind.Controller && !controllerDictionary.ContainsKey(source.id))
            {
#if !EXTEND_TOOLKIT_MOTION_CONTROLLER
                StartCoroutine(LoadControllerModel(source));
#else
                LoadControllerModelFromProvider(source);
#endif
            }
        }
        /// <summary>
        /// Stops haptics feedback on the specified interaction source.
        /// </summary>
        /// <param name="interactionSource">The source to stop haptics for.</param>
        public static void StopHaptics(this InteractionSource interactionSource)
        {
            if (!IsHapticsAvailable)
            {
                return;
            }

#if WINDOWS_UWP || DOTNETWINRT_PRESENT
            interactionSource.GetSpatialInteractionSource()?.Controller.SimpleHapticsController.StopFeedback();
#endif // WINDOWS_UWP || DOTNETWINRT_PRESENT
        }
        /// <summary>
        /// Remove the selected controller from the Active Store
        /// </summary>
        /// <param name="interactionSourceState">Source State provided by the SDK to remove</param>
        private void RemoveController(InteractionSource interactionSource)
        {
            var controller = GetController(interactionSource, false);

            if (controller != null)
            {
                MixedRealityToolkit.InputSystem?.RaiseSourceLost(controller.InputSource, controller);
            }

            activeControllers.Remove(interactionSource.id);
        }
예제 #21
0
 private void LoadControllerModelFromProvider(InteractionSource source)
 {
     if (!inProgressSources.Contains(source.id))
     {
         inProgressSources.Add(source.id);
         GameObject go = new GameObject();
         go.transform.parent = ControllersRoot;
         go.name             = "Controller " + source.id;
         var coroutine = StartCoroutine(Attach(go, ControllersRoot, source));
     }
 }
        protected virtual void InteractionManager_InteractionSourceLost(InteractionSourceLostEventArgs args)
        {
            InteractionSourceState state  = args.state;
            InteractionSource      source = state.source;

            if (source.kind == InteractionSourceKind.Controller && source.handedness == handedness)
            {
                index = uint.MaxValue;
                currentButtonState = new ButtonState();
                isDetected         = false;
            }
        }
        /// <summary>
        /// Retrieve the source controller from the Active Store, or create a new device and register it
        /// </summary>
        /// <param name="interactionSource">Source State provided by the SDK</param>
        /// <param name="addController">Should the Source be added as a controller if it isn't found?</param>
        /// <returns>New or Existing Controller Input Source</returns>
        private WindowsMixedRealityController GetController(InteractionSource interactionSource, bool addController = true)
        {
            //If a device is already registered with the ID provided, just return it.
            if (activeControllers.ContainsKey(interactionSource.id))
            {
                var controller = activeControllers[interactionSource.id] as WindowsMixedRealityController;
                Debug.Assert(controller != null);
                return(controller);
            }

            if (!addController)
            {
                return(null);
            }

            Handedness controllingHand;

            switch (interactionSource.handedness)
            {
            default:
                controllingHand = Handedness.None;
                break;

            case InteractionSourceHandedness.Left:
                controllingHand = Handedness.Left;
                break;

            case InteractionSourceHandedness.Right:
                controllingHand = Handedness.Right;
                break;
            }

            var    pointers           = interactionSource.supportsPointing ? RequestPointers(typeof(WindowsMixedRealityController), controllingHand) : null;
            string nameModifier       = controllingHand == Handedness.None ? interactionSource.kind.ToString() : controllingHand.ToString();
            var    inputSource        = MixedRealityToolkit.InputSystem?.RequestNewGenericInputSource($"Mixed Reality Controller {nameModifier}", pointers);
            var    detectedController = new WindowsMixedRealityController(TrackingState.NotTracked, controllingHand, inputSource);

            if (!detectedController.SetupConfiguration(typeof(WindowsMixedRealityController)))
            {
                // Controller failed to be setup correctly.
                // Return null so we don't raise the source detected.
                return(null);
            }

            for (int i = 0; i < detectedController.InputSource?.Pointers?.Length; i++)
            {
                detectedController.InputSource.Pointers[i].Controller = detectedController;
            }

            activeControllers.Add(interactionSource.id, detectedController);
            return(detectedController);
        }
        /// <summary>
        /// Gets the source data for the specified interaction source if it already exists, otherwise creates it.
        /// </summary>
        /// <param name="interactionSource">Interaction source for which data should be retrieved.</param>
        /// <returns>The source data requested.</returns>
        private SourceData GetOrAddSourceData(InteractionSource interactionSource)
        {
            SourceData sourceData;

            if (!sourceIdToData.TryGetValue(interactionSource.id, out sourceData))
            {
                sourceData = new SourceData(interactionSource.id);
                sourceIdToData.Add(sourceData.SourceId, sourceData);
                newSources.Add(sourceData.SourceId);
            }

            return(sourceData);
        }
예제 #25
0
 void UpdateControllerProperties(InteractionSource source)
 {
     _currentState.SupportsGrasp      = source.supportsGrasp;
     _currentState.SupportsMenu       = source.supportsMenu;
     _currentState.SupportsPointing   = source.supportsPointing;
     _currentState.SupportsTouchpad   = source.supportsTouchpad;
     _currentState.SupportsThumbstick = source.supportsThumbstick;
     _currentState.VendorId           = source.vendorId;
     _currentState.ProductVersion     = source.productVersion;
     _currentState.Id          = source.id;
     _currentState.IsLeftHand  = source.handedness == InteractionSourceHandedness.Left;
     _currentState.IsRightHand = source.handedness == InteractionSourceHandedness.Right;
 }
예제 #26
0
 public void InitStaticProperties(InteractionSource source)
 {
     SupportsGrasp      = source.supportsGrasp;
     SupportsMenu       = source.supportsMenu;
     SupportsPointing   = source.supportsPointing;
     SupportsTouchpad   = source.supportsTouchpad;
     SupportsThumbstick = source.supportsThumbstick;
     VendorId           = source.vendorId;
     ProductVersion     = source.productVersion;
     Id          = source.id;
     IsLeftHand  = source.handedness == InteractionSourceHandedness.Left;
     IsRightHand = source.handedness == InteractionSourceHandedness.Right;
 }
        /// <summary>
        /// Gets the current native SpatialInteractionSourceState for this InteractionSource.
        /// </summary>
        /// <param name="interactionSource">This InteractionSource to search for via the native Windows APIs.</param>
        /// <returns>The current native SpatialInteractionSourceState.</returns>
        public static SpatialInteractionSourceState GetSpatialInteractionSourceState(this InteractionSource interactionSource)
        {
            IReadOnlyList <SpatialInteractionSourceState> sources = WindowsMixedRealityUtilities.SpatialInteractionManager?.GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.UtcNow));

            for (var i = 0; i < sources?.Count; i++)
            {
                if (sources[i].Source.Id.Equals(interactionSource.id))
                {
                    return(sources[i]);
                }
            }

            return(null);
        }
예제 #28
0
        /// <summary>
        /// Gets the source data for the specified interaction source if it already exists, otherwise creates it.
        /// </summary>
        /// <param name="interactionSource">Interaction source for which data should be retrieved.</param>
        /// <returns>The source data requested.</returns>
        private SourceData GetOrAddSourceData(InteractionSource interactionSource)
        {
            SourceData sourceData;

            if (!sourceIdToData.TryGetValue(interactionSource.id, out sourceData))
            {
                sourceData = new SourceData(interactionSource);
                sourceIdToData.Add(sourceData.SourceId, sourceData);

                // TODO: robertes: whenever we end up adding, should we first synthesize a SourceDetected? Or
                //       perhaps if we keep strict track of all sources, we should never need to just-in-time add anymore.
            }

            return(sourceData);
        }
        /// <summary>
        /// When a controller is lost, the model is destroyed and the controller object
        /// is removed from the tracking dictionary.
        /// </summary>
        /// <param name="obj">The source event args to be used to determine the controller model to be removed.</param>
        private void InteractionManager_InteractionSourceLost(InteractionSourceLostEventArgs obj)
        {
            InteractionSource source = obj.state.source;

            if (source.kind == InteractionSourceKind.Controller)
            {
                MotionControllerInfo controller;
                if (controllerDictionary != null && controllerDictionary.TryGetValue(source.id, out controller))
                {
                    controllerDictionary.Remove(source.id);

                    Destroy(controller.ControllerParent);
                }
            }
        }
        public static IEnumerator AttachModel(GameObject target, Transform parent,
                                              InteractionSource source, Material colorMaterial, Material noColorMaterial, float timeOut = 15f)
        {
            float endTime = Time.time + timeOut;

            while (Time.time < endTime)
            {
                string id = ControllerModelProvider.Instance.GetProductId(source);
                if (id != string.Empty)
                {
                    yield return(AttachModelById(target, parent, id, colorMaterial, noColorMaterial));

                    break;
                }
            }
        }
예제 #31
0
		private void ButtonGUI (Button button, string suffix, InteractionSource source)
		{
			bool isEnabled = !button.isDisabled;
			isEnabled = EditorGUILayout.Toggle ("Enabled:", isEnabled);
			button.isDisabled = !isEnabled;
			
			if (source == InteractionSource.AssetFile)
			{
				button.assetFile = (ActionListAsset) EditorGUILayout.ObjectField ("Interaction:", button.assetFile, typeof (ActionListAsset), false);
			}
			else if (source == InteractionSource.CustomScript)
			{
				button.customScriptObject = (GameObject) EditorGUILayout.ObjectField ("Object with script:", button.customScriptObject, typeof (GameObject), true);
				button.customScriptFunction = EditorGUILayout.TextField ("Message to send:", button.customScriptFunction);
			}
			else if (source == InteractionSource.InScene)
			{
				EditorGUILayout.BeginHorizontal ();
				button.interaction = (Interaction) EditorGUILayout.ObjectField ("Interaction:", button.interaction, typeof (Interaction), true);
				
				if (button.interaction == null)
				{
					if (GUILayout.Button ("Auto-create", autoWidth))
					{
						Undo.RecordObject (_target, "Create Interaction");
						Interaction newInteraction = AdvGame.GetReferences ().sceneManager.AddPrefab ("Logic", "Interaction", true, false, true).GetComponent <Interaction>();
						
						string hotspotName = _target.gameObject.name;
						if (_target.hotspotName != "")
						{
							hotspotName = _target.hotspotName;
						}
						
						newInteraction.gameObject.name = AdvGame.UniqueName (suffix + ": " + hotspotName);
						button.interaction = newInteraction;
					}
				}
				EditorGUILayout.EndHorizontal ();
			}
			
			button.playerAction = (PlayerAction) EditorGUILayout.EnumPopup ("Player action:", button.playerAction);
			
			if (button.playerAction == PlayerAction.WalkTo || button.playerAction == PlayerAction.WalkToMarker)
			{
				button.isBlocking = EditorGUILayout.Toggle ("Cutscene while moving?", button.isBlocking);
				button.faceAfter = EditorGUILayout.Toggle ("Face after moving?", button.faceAfter);
				
				if (button.playerAction == PlayerAction.WalkTo)
				{
					button.setProximity = EditorGUILayout.Toggle ("Set minimum distance?", button.setProximity);
					if (button.setProximity)
					{
						button.proximity = EditorGUILayout.FloatField ("Proximity:", button.proximity);
					}
				}
			}
		}
        private void ButtonGUI(Button button, string suffix, InteractionSource source)
        {
            bool isEnabled = !button.isDisabled;
            isEnabled = EditorGUILayout.Toggle ("Enabled:", isEnabled);
            button.isDisabled = !isEnabled;

            if (source == InteractionSource.AssetFile)
            {
                button.assetFile = (ActionListAsset) EditorGUILayout.ObjectField ("Interaction:", button.assetFile, typeof (ActionListAsset), false);
            }
            else if (source == InteractionSource.CustomScript)
            {
                button.customScriptObject = (GameObject) EditorGUILayout.ObjectField ("Object with script:", button.customScriptObject, typeof (GameObject), true);
                button.customScriptFunction = EditorGUILayout.TextField ("Message to send:", button.customScriptFunction);
            }
            else if (source == InteractionSource.InScene)
            {
                EditorGUILayout.BeginHorizontal ();
                button.interaction = (Interaction) EditorGUILayout.ObjectField ("Interaction:", button.interaction, typeof (Interaction), true);

                if (button.interaction == null)
                {
                    if (GUILayout.Button ("Create", autoWidth))
                    {
                        Undo.RecordObject (_target, "Create Interaction");
                        Interaction newInteraction = SceneManager.AddPrefab ("Logic", "Interaction", true, false, true).GetComponent <Interaction>();

                        string hotspotName = _target.gameObject.name;
                        if (_target != null && _target.hotspotName != null && _target.hotspotName.Length > 0)
                        {
                            hotspotName = _target.hotspotName;
                        }

                        newInteraction.gameObject.name = AdvGame.UniqueName (hotspotName + ": " + suffix);
                        button.interaction = newInteraction;
                    }
                }
                EditorGUILayout.EndHorizontal ();
            }

            button.playerAction = (PlayerAction) EditorGUILayout.EnumPopup ("Player action:", button.playerAction);

            if (button.playerAction == PlayerAction.WalkTo || button.playerAction == PlayerAction.WalkToMarker)
            {
                if (button.playerAction == PlayerAction.WalkToMarker && _target.walkToMarker == null)
                {
                    EditorGUILayout.HelpBox ("You must assign a 'Walk-to marker' above for this option to work.", MessageType.Warning);
                }
                if (KickStarter.settingsManager == null || KickStarter.settingsManager.movementMethod != MovementMethod.UltimateFPS)
                {
                    button.isBlocking = EditorGUILayout.Toggle ("Cutscene while moving?", button.isBlocking);
                }
                button.faceAfter = EditorGUILayout.Toggle ("Face after moving?", button.faceAfter);

                if (button.playerAction == PlayerAction.WalkTo)
                {
                    button.setProximity = EditorGUILayout.Toggle ("Set minimum distance?", button.setProximity);
                    if (button.setProximity)
                    {
                        button.proximity = EditorGUILayout.FloatField ("Proximity:", button.proximity);
                    }
                }
            }
        }
        private void EditOptionGUI(ButtonDialog option, InteractionSource source)
        {
            EditorGUILayout.BeginVertical ("Button");

            if (option.lineID > -1)
            {
                EditorGUILayout.LabelField ("Speech Manager ID:", option.lineID.ToString ());
            }

            option.label = EditorGUILayout.TextField ("Label:", option.label);

            if (source == InteractionSource.AssetFile)
            {
                option.assetFile = (ActionListAsset) EditorGUILayout.ObjectField ("Interaction:", option.assetFile, typeof (ActionListAsset), false);
            }
            else if (source == InteractionSource.CustomScript)
            {
                option.customScriptObject = (GameObject) EditorGUILayout.ObjectField ("Object with script:", option.customScriptObject, typeof (GameObject), true);
                option.customScriptFunction = EditorGUILayout.TextField ("Message to send:", option.customScriptFunction);
            }
            else if (source == InteractionSource.InScene)
            {
                EditorGUILayout.BeginHorizontal ();
                option.dialogueOption = (DialogueOption) EditorGUILayout.ObjectField ("Interaction:", option.dialogueOption, typeof (DialogueOption), true);
                if (option.dialogueOption == null)
                {
                    if (GUILayout.Button ("Create", GUILayout.MaxWidth (60f)))
                    {
                        Undo.RecordObject (_target, "Auto-create dialogue option");
                        DialogueOption newDialogueOption = SceneManager.AddPrefab ("Logic", "DialogueOption", true, false, true).GetComponent <DialogueOption>();

                        newDialogueOption.gameObject.name = AdvGame.UniqueName (_target.gameObject.name + "_Option");
                        newDialogueOption.Initialise ();
                        EditorUtility.SetDirty (newDialogueOption);
                        option.dialogueOption = newDialogueOption;
                    }
                }
                EditorGUILayout.EndHorizontal ();
            }

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Icon texture:", GUILayout.Width (155f));
            option.icon = (Texture2D) EditorGUILayout.ObjectField (option.icon, typeof (Texture2D), false, GUILayout.Width (70f), GUILayout.Height (30f));
            EditorGUILayout.EndHorizontal ();

            option.isOn = EditorGUILayout.Toggle ("Is enabled?", option.isOn);
            if (source == InteractionSource.CustomScript)
            {
                EditorGUILayout.HelpBox ("Using a custom script will cause the conversation to end when finished, unless it is re-run explicitly.", MessageType.Info);
            }
            else
            {
                option.conversationAction = (ConversationAction) EditorGUILayout.EnumPopup ("When finished:", option.conversationAction);
                if (option.conversationAction == AC.ConversationAction.RunOtherConversation)
                {
                    option.newConversation = (Conversation) EditorGUILayout.ObjectField ("Conversation to run:", option.newConversation, typeof (Conversation), true);
                }
            }

            if (_target.isTimed)
            {
                if (_target.options.IndexOf (option) != _target.defaultOption)
                {
                    if (GUILayout.Button ("Make default", GUILayout.MaxWidth (80)))
                    {
                        Undo.RecordObject (_target, "Change default conversation option");
                        _target.defaultOption = _target.options.IndexOf (option);
                        EditorUtility.SetDirty (_target);
                    }
                }
            }

            EditorGUILayout.EndVertical ();
        }