You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
10 KiB
C#
261 lines
10 KiB
C#
using MalbersAnimations.Scriptables;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using MalbersAnimations.Events;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace MalbersAnimations.Utilities
|
|
{
|
|
[DefaultExecutionOrder(15)]
|
|
[SelectionBase]
|
|
[AddComponentMenu("Malbers/Interaction/Interactable")]
|
|
[HelpURL("https://malbersanimations.gitbook.io/animal-controller/global-components/interactable")]
|
|
public class MInteract : UnityUtils, IInteractable
|
|
{
|
|
[Tooltip("Own Index. This is used to Identify each Interactable. (Used on UnityEvents)")]
|
|
//[UnityEngine.Serialization.FormerlySerializedAs("m_ID")]
|
|
public IntReference m_ID = new IntReference(0);
|
|
[Tooltip("ID for the Interactor. Makes this Interactable to interact only with Interactors with this ID Value\n" +
|
|
"By default its -1, which means that can be activated by anyone")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("m_InteracterID")]
|
|
public IntReference m_InteractorID = new IntReference(-1);
|
|
|
|
[Tooltip("If the Interactor has this Interactable focused, it will interact with it automatically.\n" +
|
|
"It also is used by the AI Animals. If the Animal Reaches this gameobject to Interact with it this needs to be set to true")]
|
|
[SerializeField] private BoolReference m_Auto = new BoolReference(false);
|
|
|
|
[Tooltip("Interact Once, after that it cannot longer work, unlest the Interactable is Restarted. Disable the component")]
|
|
[SerializeField] private BoolReference m_singleInteraction = new BoolReference(false);
|
|
|
|
[Tooltip("Delay time to activate the events on the Interactable")]
|
|
public FloatReference m_Delay = new FloatReference(0);
|
|
|
|
[Tooltip("CoolDown between Interactions when the Interactable is NOT a Single/One time interaction")]
|
|
public FloatReference m_CoolDown = new FloatReference(0);
|
|
|
|
[Tooltip("When an Interaction is executed these events will be invoked." +
|
|
"\n\nOnInteractWithGO(GameObject) -> will have the *INTERACTER* gameObject as parameter" +
|
|
"\n\nOnInteractWith(Int) -> will have the *INTERACTER* ID as parameter")]
|
|
public InteractionEvents events = new InteractionEvents();
|
|
|
|
public GameObjectEvent OnFocused = new GameObjectEvent();
|
|
public GameObjectEvent OnUnfocused = new GameObjectEvent();
|
|
|
|
public int Index => m_ID;
|
|
|
|
public bool Active { get => enabled && !InCooldown; set => enabled = value; }
|
|
public bool SingleInteraction { get => m_singleInteraction.Value; set => m_singleInteraction.Value = value; }
|
|
public bool Auto { get => m_Auto.Value; set => m_Auto.Value = value; }
|
|
// public bool Active { get =>enabled; set => enabled = value; }
|
|
|
|
/// <summary>Delay time to Activate the Interaction on the Interactable</summary>
|
|
public float Delay { get => m_Delay.Value; set => m_Delay.Value = value; }
|
|
|
|
/// <summary>CoolDown Between Interactions</summary>
|
|
public float Cooldown { get => m_CoolDown.Value; set => m_CoolDown.Value = value; }
|
|
|
|
/// <summary>Is the Interactable in CoolDown?</summary>
|
|
public bool InCooldown => !MTools.ElapsedTime(CurrentActivationTime, Cooldown);
|
|
|
|
public IInteractor CurrentInteractor { get; set; }
|
|
|
|
private bool focused;
|
|
public bool Focused
|
|
{
|
|
get => focused;
|
|
set
|
|
{
|
|
if (focused != value)
|
|
{
|
|
focused = value;
|
|
|
|
if (focused)
|
|
{
|
|
OnFocused.Invoke(CurrentInteractor != null ? CurrentInteractor.Owner : null);
|
|
}
|
|
else
|
|
{
|
|
OnUnfocused.Invoke(CurrentInteractor != null ? CurrentInteractor.Owner : null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public GameObject Owner => gameObject;
|
|
|
|
private float CurrentActivationTime;
|
|
|
|
public string Description = "Invoke events when an Interactor interacts with it";
|
|
[HideInInspector] public bool ShowDescription = true;
|
|
[ContextMenu("Show Description")]
|
|
internal void EditDescription() => ShowDescription ^= true;
|
|
|
|
private void OnEnable()
|
|
{
|
|
CurrentActivationTime = -Cooldown;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
focused = false;
|
|
CurrentInteractor?.UnFocus(this); //Clean the Current Focused item
|
|
}
|
|
|
|
/// <summary> Receive an Interaction from the Interacter </summary>
|
|
/// <param name="InteracterID">ID of the Interacter</param>
|
|
/// <param name="interacter">Interacter's GameObject</param>
|
|
public bool Interact(int InteracterID, GameObject interacter)
|
|
{
|
|
if (Active)
|
|
{
|
|
if (m_InteractorID <= 0 || m_InteractorID == InteracterID) //Check for Interactor ID
|
|
{
|
|
CurrentActivationTime = Time.time;
|
|
|
|
this.Delay_Action(Delay, () =>
|
|
{
|
|
events.OnInteractWithGO.Invoke(interacter);
|
|
events.OnInteractWith.Invoke(InteracterID);
|
|
}
|
|
);
|
|
|
|
if (SingleInteraction)
|
|
{
|
|
Focused = false;
|
|
Active = false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary> Receive an Interaction from an gameObject </summary>
|
|
/// <param name="InteracterID">ID of the Interacter</param>
|
|
/// <param name="interacter">Interacter's GameObject</param>
|
|
public bool Interact(IInteractor interacter)
|
|
{
|
|
if (interacter != null)
|
|
return Interact(interacter.ID, interacter.Owner.gameObject);
|
|
|
|
return false;
|
|
}
|
|
|
|
public void Interact() => Interact(-1, null);
|
|
|
|
public virtual void Restart()
|
|
{
|
|
Focused = false;
|
|
Active = true;
|
|
CurrentActivationTime = -Cooldown;
|
|
}
|
|
|
|
[SerializeField] private int Editor_Tabs1;
|
|
|
|
}
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
[UnityEditor.CustomEditor(typeof(MInteract)),CanEditMultipleObjects]
|
|
public class MInteractEditor : UnityEditor.Editor
|
|
{
|
|
SerializedProperty m_ID, m_InteractorID, m_Auto, m_singleInteraction, m_Delay,
|
|
m_CoolDown, events, OnFocused, OnUnfocused, Editor_Tabs1, Description, ShowDescription;
|
|
protected string[] Tabs1 = new string[] { "General", "Events" };
|
|
MInteract M;
|
|
|
|
public static GUIStyle StyleBlue => MTools.Style(new Color(0, 0.5f, 1f, 0.3f));
|
|
private GUIStyle style;
|
|
private void OnEnable()
|
|
{
|
|
M = (MInteract)target;
|
|
m_ID = serializedObject.FindProperty("m_ID");
|
|
m_InteractorID = serializedObject.FindProperty("m_InteractorID");
|
|
m_Auto = serializedObject.FindProperty("m_Auto");
|
|
m_singleInteraction = serializedObject.FindProperty("m_singleInteraction");
|
|
m_Delay = serializedObject.FindProperty("m_Delay");
|
|
m_CoolDown = serializedObject.FindProperty("m_CoolDown");
|
|
events = serializedObject.FindProperty("events");
|
|
OnFocused = serializedObject.FindProperty("OnFocused");
|
|
OnUnfocused = serializedObject.FindProperty("OnUnfocused");
|
|
Editor_Tabs1 = serializedObject.FindProperty("Editor_Tabs1");
|
|
ShowDescription = serializedObject.FindProperty("ShowDescription");
|
|
Description = serializedObject.FindProperty("Description");
|
|
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
if (ShowDescription.boolValue)
|
|
{
|
|
if (style == null)
|
|
{
|
|
style = new GUIStyle(StyleBlue)
|
|
{
|
|
fontSize = 12,
|
|
fontStyle = FontStyle.Bold,
|
|
alignment = TextAnchor.MiddleLeft,
|
|
stretchWidth = true
|
|
};
|
|
}
|
|
|
|
style.normal.textColor = EditorStyles.label.normal.textColor;
|
|
Description.stringValue = UnityEditor.EditorGUILayout.TextArea(Description.stringValue, style);
|
|
}
|
|
|
|
|
|
//MalbersEditor.DrawDescription("Interactable Element that invoke events when an Interactor interact with it");
|
|
Editor_Tabs1.intValue = GUILayout.Toolbar(Editor_Tabs1.intValue, Tabs1);
|
|
|
|
if (Editor_Tabs1.intValue == 0)
|
|
DrawGeneral();
|
|
else DrawEvents();
|
|
|
|
if (Application.isPlaying)
|
|
{
|
|
EditorGUI.BeginDisabledGroup(true);
|
|
EditorGUILayout.ObjectField("Interactor",
|
|
M.CurrentInteractor != null ? M.CurrentInteractor.Owner : null, typeof(GameObject), false);
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
private void DrawGeneral()
|
|
{
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
{
|
|
EditorGUILayout.PropertyField(m_InteractorID, new GUIContent("Interactor ID"));
|
|
EditorGUILayout.PropertyField(m_ID, new GUIContent("Index"));
|
|
|
|
EditorGUILayout.PropertyField(m_Auto,new GUIContent("Auto Interact"));
|
|
EditorGUILayout.PropertyField(m_singleInteraction, new GUIContent("Single Interaction"));
|
|
EditorGUILayout.PropertyField(m_Delay);
|
|
if (!M.SingleInteraction) EditorGUILayout.PropertyField(m_CoolDown, new GUIContent("Cooldown"));
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUIUtility.labelWidth = 0;
|
|
}
|
|
|
|
private void DrawEvents()
|
|
{
|
|
EditorGUILayout.PropertyField(events, true);
|
|
if (events.isExpanded)
|
|
{
|
|
EditorGUILayout.PropertyField(OnFocused);
|
|
EditorGUILayout.PropertyField(OnUnfocused);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
} |