using System.Linq; using Unity.VisualScripting; using UnityEditor; using UnityEngine; using static UDE_HAND_INTERACTION.InteractableObject; namespace UDE_HAND_INTERACTION { [CustomEditor(typeof(InteractableObject))] public class InteractableObjectEditor : Editor { InteractableObject interactableObject { get { return target as InteractableObject; } } SerializedProperty handInteractions; SerializedProperty interactionPlan; SerializedProperty ObjInteractEvent; SerializedProperty ObjDisableEvent; bool OptionalSet = false; private void OnEnable() { ObjInteractEvent = serializedObject.FindProperty("WhenObjInteract"); ObjDisableEvent = serializedObject.FindProperty("WhenObjDisable"); handInteractions = serializedObject.FindProperty("HandInteractions"); interactionPlan = serializedObject.FindProperty("InteractionPlan"); } public override void OnInspectorGUI() { serializedObject.Update(); DrawRawParamaters(); GUILayout.Space(10); AutoCheckPoseButton(); AddVirtualHandButton(); AddOutlineComponent(); AddInteractSoundComponent(); GUILayout.Space(10); ExtraParamUI(); EditorGUILayout.Separator(); if (GUI.changed) { EditorUtility.SetDirty(interactableObject); } } void DrawRawParamaters() { EditorGUILayout.PropertyField(ObjInteractEvent); EditorGUILayout.PropertyField(ObjDisableEvent); interactableObject.enablePhysicalProperties = EditorGUILayout.Toggle("Enable Physical Prorerties", interactableObject.enablePhysicalProperties); if (interactableObject.enablePhysicalProperties) { if(interactableObject.TryGetComponent(out var _rigid)) _rigid.isKinematic = false; interactableObject.enableMotionTrace = EditorGUILayout.Toggle("Enable Object Motion Trace", interactableObject.enableMotionTrace); if(interactableObject.enableMotionTrace) { var seconds = EditorGUILayout.FloatField("Trace Visible Seconds", interactableObject.traceVisibleSeconds); interactableObject.traceVisibleSeconds = seconds > 0 ? seconds : 0; if (interactableObject.GetComponent() == null) { var line = interactableObject.AddComponent(); line.positionCount = 0; line.materials = AssetDatabase.LoadAssetAtPath("Assets/SDK/Interaction SDK/Prefabs/PhysicalLineRenderer.prefab").sharedMaterials; line.startWidth = 0.02f; line.endWidth = 0.02f; } } else if(!interactableObject.enableMotionTrace) { DestroyImmediate(interactableObject.GetComponent()); } } else { DestroyImmediate(interactableObject.GetComponent()); } EditorGUILayout.PropertyField(handInteractions); interactableObject.enableInteractionPlans = EditorGUILayout.Toggle("Enable Interaction Plans", interactableObject.enableInteractionPlans); if (interactableObject.enableInteractionPlans) { GUILayout.Space(10); EditorGUILayout.PropertyField(interactionPlan); } serializedObject.ApplyModifiedProperties(); } void ExtraParamUI() { int Priority = EditorGUILayout.IntField("Interact Priority", interactableObject.InteractPriority); if(Priority >= 0) { interactableObject.InteractPriority = Priority; } GUILayout.Space(2); interactableObject.objectFollowType = (ObjectFollowType)EditorGUILayout.EnumPopup("Object Follow Type", interactableObject.objectFollowType); if(interactableObject.objectFollowType != ObjectFollowType.NoPose && interactableObject.objectFollowType != ObjectFollowType.Instant) { if(interactableObject.objectFollowType == ObjectFollowType.Distance) { var TrackDistance = EditorGUILayout.FloatField("Tracking Max Distance", interactableObject.TrackingDistance); interactableObject.TrackingDistance = TrackDistance >= 0 ? TrackDistance : 0f; interactableObject.TryGetComponent(out var NewCollider); if (NewCollider == null) { NewCollider = interactableObject.AddComponent(); NewCollider.radius = 0.5f; } NewCollider.isTrigger = true; } var TrackTime = EditorGUILayout.FloatField("Tracking Time", interactableObject.TrackingTime); interactableObject.TrackingTime = TrackTime >= 0 ? TrackTime : 0f; } GUILayout.Space(5); OptionalSet = EditorGUILayout.Foldout(OptionalSet, "Optional", true); if(OptionalSet) { interactableObject.InsideOperationPart = (Transform)EditorGUILayout.ObjectField("Inside Operation Part", interactableObject.InsideOperationPart, typeof(Transform), true); if(interactableObject.InsideOperationPart) { var MoveTime = EditorGUILayout.FloatField("Moving Time", interactableObject.MovingOnTime); interactableObject.MovingOnTime = MoveTime >= 0 ? MoveTime : 0f; } } } void AutoCheckPoseButton() { if(GUILayout.Button("Auto Check Pose")) { var interactions = interactableObject.GetComponentsInChildren().ToList(); for (int i = interactions.Count - 1; i >= 0; i--) { if (interactions[i].transform.TryGetComponent(out FingerUseInteraction UseInteract)) { interactions.Remove(UseInteract.PreposeInteraction); } } interactableObject.HandInteractions = interactions.ToArray(); } } void AddVirtualHandButton() { if (GUILayout.Button("Add Virtual Hand Pose")) { GameObject DefaultVirtualHand = AssetDatabase.LoadAssetAtPath("Assets/SDK/Interaction SDK/Prefabs/DefaultVirtualHand.prefab"); interactableObject.DefaultVirtualHand = DefaultVirtualHand; GameObject virtualhand = Instantiate(DefaultVirtualHand, interactableObject.transform, false); virtualhand.GetComponent()._relativeTo = interactableObject.transform; var interactions = interactableObject.GetComponentsInChildren(); interactableObject.HandInteractions = interactions; } } void AddOutlineComponent() { if (GUILayout.Button("Add Outline Component")) { if(interactableObject.GetComponent() == null) { interactableObject.AddComponent(); } } } void AddInteractSoundComponent() { if(GUILayout.Button("Add Interact Sound")) { if (interactableObject.GetComponent() == null) { var source = interactableObject.AddComponent(); source.clip = AssetDatabase.LoadAssetAtPath("Assets/SDK/Interaction SDK/Resources/InteractSound.mp3"); source.playOnAwake = false; interactableObject.SetInteractSound = true; } } } } }