CORE dashboard + a lot of changes
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
using RPGCore.Core.Objects;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCore.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface allow any <see cref="BaseObject"/> to call <see cref="OnEnter"/> and <see cref="OnExit"/>.<br/>
|
||||
/// Setting <see cref="Collider"/>'s <see cref="Collider.isTrigger"/> to true is required!<br/>
|
||||
/// </summary>
|
||||
public interface ITrigger
|
||||
{
|
||||
public void OnEnter(BaseObject obj);
|
||||
public void OnExit(BaseObject obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace RPGCore.Core
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ObjectModuleAttribute : Attribute
|
||||
{
|
||||
public string name;
|
||||
public string description;
|
||||
public bool required;
|
||||
|
||||
public ObjectModuleAttribute(string name, string description, bool required = false)
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.required = required;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7732c0ab6a6148ddb8c17a80facf5204
|
||||
timeCreated: 1780777138
|
||||
@@ -13,13 +13,11 @@ namespace RPGCore.Core.Objects
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
[RequireComponent(typeof(EventModule))]
|
||||
[RequireComponent(typeof(ActionModule))]
|
||||
[RequireComponent(typeof(DataModule))]
|
||||
public abstract class BaseObject : MonoBehaviour
|
||||
{
|
||||
[field: SerializeField, ReadOnly] public new Rigidbody rigidbody { get; private set; }
|
||||
[field: SerializeField, ReadOnly] public EventModule events { get; private set; }
|
||||
[field: SerializeField, ReadOnly] public ActionModule actions { get; private set; }
|
||||
[field: SerializeField, ReadOnly] public DataModule data { get; private set; }
|
||||
|
||||
[DynamicValueProvider]
|
||||
@@ -34,7 +32,6 @@ namespace RPGCore.Core.Objects
|
||||
{
|
||||
rigidbody = GetComponent<Rigidbody>();
|
||||
events = GetComponent<EventModule>();
|
||||
actions = GetComponent<ActionModule>();
|
||||
data = GetComponent<DataModule>();
|
||||
GetComponents<ObjectModule>().ForEach(module => module.parent = this);
|
||||
}
|
||||
@@ -42,25 +39,31 @@ namespace RPGCore.Core.Objects
|
||||
/// <summary>Removes this object from game.</summary>
|
||||
public void Remove()
|
||||
{
|
||||
events.Invoke(new TriggerClearEvent { obj = this });
|
||||
events.Invoke(new RemoveEvent{ obj = this });
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
events.Invoke(new TriggerClearEvent { obj = this });
|
||||
}
|
||||
|
||||
/// <summary>It'll execute <see cref="ITrigger"/>.<see cref="ITrigger.OnEnter"/> when this object enter its collider.</summary>
|
||||
/// <summary>It'll execute <see cref="Trigger"/>.<see cref="Trigger.OnEnter"/> when this object enter its collider.</summary>
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
other.GetComponentsInParent<ITrigger>().ForEach(trigger => {
|
||||
other.GetComponentsInParent<Trigger>().ForEach(trigger => {
|
||||
trigger.OnEnter(this);
|
||||
events.Invoke(new TriggerEnterEvent { target = this, trigger = trigger });
|
||||
events.Invoke(new TriggerEnterEvent { obj = this, trigger = trigger });
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>It'll execute <see cref="ITrigger"/>.<see cref="ITrigger.OnExit"/> when this object exit its collider.</summary>
|
||||
/// <summary>It'll execute <see cref="Trigger"/>.<see cref="Trigger.OnExit"/> when this object exit its collider.</summary>
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
other.GetComponentsInParent<ITrigger>().ForEach(trigger => {
|
||||
other.GetComponentsInParent<Trigger>().ForEach(trigger => {
|
||||
trigger.OnExit(this);
|
||||
events.Invoke(new TriggerExitEvent { target = this, trigger = trigger });
|
||||
events.Invoke(new TriggerExitEvent { obj = this, trigger = trigger });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using RPGCore.ObjectModules.ActionObjectModule;
|
||||
using RPGCoreCommon.DynamicValues;
|
||||
using RPGCoreCommon.Helpers.PropertyAttributeDrawers;
|
||||
using UnityEngine;
|
||||
@@ -6,16 +7,19 @@ using UnityEngine;
|
||||
namespace RPGCore.Core.Objects
|
||||
{
|
||||
[RequireComponent(typeof(CapsuleCollider))]
|
||||
[RequireComponent(typeof(ActionModule))]
|
||||
public class UnitObject : BaseObject
|
||||
{
|
||||
[DynamicValueProvider]
|
||||
private ObjectModule<UnitObject> UnitModuleProvider(Type moduleType) => GetComponent(moduleType) as ObjectModule<UnitObject>;
|
||||
|
||||
[field: SerializeField, ReadOnly] public CapsuleCollider unitCollider { get; private set; }
|
||||
[field: SerializeField, ReadOnly] public ActionModule actions { get; private set; }
|
||||
|
||||
protected new void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
actions = GetComponent<ActionModule>();
|
||||
unitCollider = GetComponent<CapsuleCollider>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RPGCore.Core.Objects;
|
||||
using RPGCore.ObjectModules.EventObjectModule.Events;
|
||||
using RPGCoreCommon.Settings;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCore.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This MonoBehaviour allow any <see cref="BaseObject"/> to call <see cref="OnEnter"/> and <see cref="OnExit"/>.<br/>
|
||||
/// Setting <see cref="Collider"/>'s <see cref="Collider.isTrigger"/> to true is required!<br/>
|
||||
/// </summary>
|
||||
public class Trigger : MonoBehaviour
|
||||
{
|
||||
private event Action<BaseObject> OnEnterEvent;
|
||||
private event Action<BaseObject> OnExitEvent;
|
||||
|
||||
private readonly Dictionary<BaseObject, int> _collisionCounter = new();
|
||||
|
||||
public static Trigger AddToGameObject(GameObject go, Action<BaseObject> onEnter, Action<BaseObject> onExit)
|
||||
{
|
||||
go.layer = SettingsManager.Get<CoreSettings>().triggerLayer;
|
||||
|
||||
var interactTrigger = go.AddComponent<Trigger>();
|
||||
interactTrigger.OnEnterEvent += onEnter;
|
||||
interactTrigger.OnExitEvent += onExit;
|
||||
|
||||
return interactTrigger;
|
||||
}
|
||||
|
||||
internal void OnEnter(BaseObject obj)
|
||||
{
|
||||
var alreadyTouching = _collisionCounter.ContainsKey(obj);
|
||||
if (!alreadyTouching) _collisionCounter.Add(obj, 0);
|
||||
_collisionCounter[obj]++;
|
||||
|
||||
if (!alreadyTouching)
|
||||
{
|
||||
obj.events.Register<TriggerClearEvent>(OnClear);
|
||||
OnEnterEvent?.Invoke(obj);
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnExit(BaseObject obj)
|
||||
{
|
||||
if (!_collisionCounter.ContainsKey(obj))
|
||||
{
|
||||
Debug.LogError("Object tried to leave trigger, but never entered it!", obj);
|
||||
return;
|
||||
}
|
||||
|
||||
_collisionCounter[obj]--;
|
||||
if (_collisionCounter[obj] == 0) Clear(obj);
|
||||
}
|
||||
|
||||
private void OnClear(TriggerClearEvent ev)
|
||||
{
|
||||
Clear(ev.obj);
|
||||
}
|
||||
|
||||
private void Clear(BaseObject obj)
|
||||
{
|
||||
obj.events.Unregister<TriggerClearEvent>(OnClear);
|
||||
_collisionCounter.Remove(obj);
|
||||
OnExitEvent?.Invoke(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,19 @@ using UnityEngine;
|
||||
namespace RPGCore.ObjectModules.ActionObjectModule
|
||||
{
|
||||
[Serializable]
|
||||
[ObjectModule(
|
||||
name: "[Core] Actions",
|
||||
description: "[Built-in module] Module that can be attached to <b>UnitObject</b>. " +
|
||||
"Can execute any implementations of <b>BaseAction</b> with queue and/or instant execution.",
|
||||
required: true
|
||||
)]
|
||||
public class ActionModule : ObjectModule<UnitObject>
|
||||
{
|
||||
private List<BaseActionParallel> _actionParallels = new();
|
||||
private List<BaseAction> _actionParallels = new();
|
||||
private readonly List<BaseAction> _actionQueue = new();
|
||||
private BaseAction _actionCurrent;
|
||||
|
||||
public List<BaseActionParallel> actionParallels => _actionParallels.ToList();
|
||||
public List<BaseAction> actionParallels => _actionParallels.ToList();
|
||||
public List<BaseAction> actionQueue => _actionQueue.ToList();
|
||||
public BaseAction actionCurrent => _actionCurrent;
|
||||
|
||||
@@ -30,7 +36,7 @@ namespace RPGCore.ObjectModules.ActionObjectModule
|
||||
/// 1. Checks if the action can be executed outside the queue.<br/>
|
||||
/// 2. If allowed, executes the action and handles potential errors.
|
||||
/// </summary>
|
||||
public void Execute(BaseActionParallel action)
|
||||
public void Execute(BaseAction action)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace RPGCore.ObjectModules.ActionObjectModule
|
||||
{
|
||||
public abstract class BaseActionParallel : BaseAction
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e46b8a02e3894ecb87b4455602287715
|
||||
timeCreated: 1762624491
|
||||
@@ -8,7 +8,7 @@ namespace RPGCore.ObjectModules.EventObjectModule.Data
|
||||
[Serializable]
|
||||
public class BaseObjectData : BaseData<BaseObject>
|
||||
{
|
||||
[Header("Uniqueness")]
|
||||
[field: Header("Uniqueness")]
|
||||
[field: SerializeField, ReadOnly] public string guid { get; private set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Header("Display")]
|
||||
|
||||
@@ -8,7 +8,12 @@ using UnityEngine;
|
||||
namespace RPGCore.ObjectModules.EventObjectModule
|
||||
{
|
||||
[Serializable]
|
||||
[RequireComponent(typeof(BaseObject))]
|
||||
[ObjectModule(
|
||||
name: "[Core] Data",
|
||||
description: "[Built-in module] Manages all implementations of <b>BaseData</b>. " +
|
||||
"Automatically adds matching data to attached implementation of <b>BaseObject</b>.",
|
||||
required: true
|
||||
)]
|
||||
public class DataModule : ObjectModule<BaseObject>
|
||||
{
|
||||
// SERIALIZED
|
||||
@@ -48,6 +53,9 @@ namespace RPGCore.ObjectModules.EventObjectModule
|
||||
|
||||
public T Get<T>() where T : BaseData
|
||||
{
|
||||
if (!_dataDict.ContainsKey(typeof(T)))
|
||||
_dataDict.Add(typeof(T), Activator.CreateInstance(typeof(T)) as T);
|
||||
|
||||
return (T)_dataDict[typeof(T)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,28 @@
|
||||
using System.Collections.Generic;
|
||||
using RPGCore.Core;
|
||||
using RPGCore.Core.Objects;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGCore.ObjectModules.EventObjectModule
|
||||
{
|
||||
[Serializable]
|
||||
[ObjectModule(
|
||||
name: "[Core] Data",
|
||||
description: "[Built-in module] Manages all implementations of <b>BaseEvent</b> and <b>BasePreventableEvent</b>. " +
|
||||
"Allows for registering and invoking events by its type.",
|
||||
required: true
|
||||
)]
|
||||
public class EventModule : ObjectModule<BaseObject>
|
||||
{
|
||||
// TODO: tutaj dodać serializowane eventy w postaci SerializableDictionary<SerializableType, UnityAction>
|
||||
// TODO: dodatkowo mozna zmienić preventableEvents na dwa osobne słowniki before i after
|
||||
// TODO: 1. tutaj dodać serializowane eventy w postaci SerializableDictionary<SerializableType, UnityAction>
|
||||
// TODO: w Awake() zrobić bridge to uruchamiania serializowanych eventów jak uruchamia się ten runtimeowy
|
||||
// TODO: 2. dodatkowo mozna zmienić preventableEvents na dwa osobne słowniki before i after
|
||||
|
||||
internal readonly Dictionary<Type, Delegate> events = new();
|
||||
internal readonly Dictionary<Type, Delegate[]> preventableEvents = new();
|
||||
|
||||
/***** INVOKE *****/
|
||||
|
||||
public void Invoke<T>(T baseEvent) where T : BaseEvent
|
||||
{
|
||||
events.TryAdd(typeof(T), null);
|
||||
@@ -23,19 +33,17 @@ namespace RPGCore.ObjectModules.EventObjectModule
|
||||
public void Register<T>(Action<T> action) where T : BaseEvent
|
||||
{
|
||||
events.TryAdd(typeof(T), null);
|
||||
var temp = (Action<T>)events[typeof(T)];
|
||||
temp += action;
|
||||
events[typeof(T)] = temp;
|
||||
events[typeof(T)] = (Action<T>)events[typeof(T)] + action;
|
||||
}
|
||||
|
||||
public void Unregister<T>(Action<T> action) where T : BaseEvent
|
||||
{
|
||||
events.TryAdd(typeof(T), null);
|
||||
var temp = (Action<T>)events[typeof(T)];
|
||||
temp -= action;
|
||||
events[typeof(T)] = temp;
|
||||
events[typeof(T)] = (Action<T>)events[typeof(T)] - action;
|
||||
}
|
||||
|
||||
|
||||
/***** INVOKE BEFORE *****/
|
||||
|
||||
public void InvokeBefore<T>(T basePreventableEvent) where T : BasePreventableEvent
|
||||
{
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
@@ -45,22 +53,25 @@ namespace RPGCore.ObjectModules.EventObjectModule
|
||||
public void RegisterBefore<T>(Action<T> action) where T : BasePreventableEvent
|
||||
{
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
var temp = (Action<T>)preventableEvents[typeof(T)][0];
|
||||
temp += action;
|
||||
preventableEvents[typeof(T)][0] = temp;
|
||||
preventableEvents[typeof(T)][0] = (Action<T>)preventableEvents[typeof(T)][0] + action;
|
||||
}
|
||||
|
||||
public void UnregisterBefore<T>(Action<T> action) where T : BasePreventableEvent
|
||||
{
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
var temp = (Action<T>)preventableEvents[typeof(T)][0];
|
||||
temp -= action;
|
||||
preventableEvents[typeof(T)][0] = temp;
|
||||
preventableEvents[typeof(T)][0] = (Action<T>)preventableEvents[typeof(T)][0] - action;
|
||||
}
|
||||
|
||||
|
||||
/***** INVOKE AFTER *****/
|
||||
|
||||
public void InvokeAfter<T>(T basePreventableEvent) where T : BasePreventableEvent
|
||||
{
|
||||
if (basePreventableEvent.isPrevented) throw new EventPreventedException("Event is prevented and can't be invoked!");
|
||||
if (basePreventableEvent.isPrevented)
|
||||
{
|
||||
Debug.LogWarning("Event is prevented and can't be invoked!");
|
||||
return;
|
||||
}
|
||||
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
(preventableEvents[typeof(T)][1] as Action<T>)?.Invoke(basePreventableEvent);
|
||||
}
|
||||
@@ -68,17 +79,13 @@ namespace RPGCore.ObjectModules.EventObjectModule
|
||||
public void RegisterAfter<T>(Action<T> action) where T : BasePreventableEvent
|
||||
{
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
var temp = (Action<T>)preventableEvents[typeof(T)][1];
|
||||
temp += action;
|
||||
preventableEvents[typeof(T)][1] = temp;
|
||||
preventableEvents[typeof(T)][1] = (Action<T>)preventableEvents[typeof(T)][1] + action;
|
||||
}
|
||||
|
||||
public void UnregisterAfter<T>(Action<T> action) where T : BasePreventableEvent
|
||||
{
|
||||
preventableEvents.TryAdd(typeof(T), new Delegate[2]);
|
||||
var temp = (Action<T>)preventableEvents[typeof(T)][1];
|
||||
temp -= action;
|
||||
preventableEvents[typeof(T)][1] = temp;
|
||||
preventableEvents[typeof(T)][1] = (Action<T>)preventableEvents[typeof(T)][1] - action;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace RPGCore.ObjectModules.EventObjectModule
|
||||
{
|
||||
public class EventPreventedException : Exception
|
||||
{
|
||||
public EventPreventedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a647e5d4d4ed44c28fd6961d60943fe4
|
||||
timeCreated: 1761917482
|
||||
@@ -0,0 +1,15 @@
|
||||
using RPGCore.Core;
|
||||
using RPGCore.Core.Objects;
|
||||
|
||||
namespace RPGCore.ObjectModules.EventObjectModule.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Executed when <see cref="BaseObject"/> forcefully exits <see cref="Trigger"/> by non-physics means, by default
|
||||
/// it is when object is <b>Disabled</b> or <b>Removed</b>.<br/><br/>
|
||||
/// Execute this if you want to object exit its trigger.
|
||||
/// </summary>
|
||||
public class TriggerClearEvent : BaseEvent<BaseObject>
|
||||
{
|
||||
public BaseObject obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b02fda53526495c88e8c59795782dec
|
||||
timeCreated: 1779650139
|
||||
@@ -3,9 +3,12 @@ using RPGCore.Core.Objects;
|
||||
|
||||
namespace RPGCore.ObjectModules.EventObjectModule.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Executed when <see cref="BaseObject"/> enters <see cref="Trigger"/>'s colliders.
|
||||
/// </summary>
|
||||
public class TriggerEnterEvent : BaseEvent<BaseObject>
|
||||
{
|
||||
public BaseObject target;
|
||||
public ITrigger trigger;
|
||||
public BaseObject obj;
|
||||
public Trigger trigger;
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,12 @@ using RPGCore.Core.Objects;
|
||||
|
||||
namespace RPGCore.ObjectModules.EventObjectModule.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Executed when <see cref="BaseObject"/> exits <see cref="Trigger"/>'s colliders.
|
||||
/// </summary>
|
||||
public class TriggerExitEvent : BaseEvent<BaseObject>
|
||||
{
|
||||
public BaseObject target;
|
||||
public ITrigger trigger;
|
||||
public BaseObject obj;
|
||||
public Trigger trigger;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user