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.
368 lines
13 KiB
C#
368 lines
13 KiB
C#
using MalbersAnimations.Events;
|
|
using MalbersAnimations.Scriptables;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace MalbersAnimations.Utilities
|
|
{
|
|
[AddComponentMenu("Malbers/Utilities/Effects - Audio/Effect Manager")]
|
|
public class EffectManager : MonoBehaviour, IAnimatorListener
|
|
{
|
|
[RequiredField, Tooltip("Root Gameobject of the Hierarchy")]
|
|
public Transform Owner;
|
|
|
|
public List<Effect> Effects;
|
|
|
|
private void Awake()
|
|
{
|
|
foreach (var e in Effects)
|
|
{
|
|
e.Initialize();
|
|
}
|
|
}
|
|
|
|
/// <summary>Plays an Effect using its ID value</summary>
|
|
public virtual void PlayEffect(int ID)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.ID == ID && effect.active == true);
|
|
|
|
if (effects != null)
|
|
foreach (var effect in effects) Play(effect);
|
|
}
|
|
|
|
|
|
/// <summary>Plays an Effect using its ID value</summary>
|
|
public virtual void PlayEffect(string name)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.Name == name && effect.active == true);
|
|
|
|
if (effects != null)
|
|
foreach (var effect in effects) Play(effect);
|
|
}
|
|
|
|
/// <summary>Stops an Effect using its ID value</summary>
|
|
public virtual void StopEffect(int ID) => Effect_Stop(ID);
|
|
|
|
/// <summary>Plays an Effect using its ID value</summary>
|
|
public virtual void Effect_Play(int ID) => PlayEffect(ID);
|
|
public virtual void EffectPlay(int ID) => PlayEffect(ID);
|
|
public virtual void Effect_Play(string name) => PlayEffect(name);
|
|
public virtual void EffectPlay(string name) => PlayEffect(name);
|
|
|
|
/// <summary>Stops an Effect using its ID value</summary>
|
|
public virtual void Effect_Stop(int ID)
|
|
{
|
|
var effects = Effects.FindAll(effect => effect.ID == ID && effect.active == true);
|
|
|
|
Stop_Effects(effects);
|
|
}
|
|
|
|
private void Stop_Effects(List<Effect> effects)
|
|
{
|
|
if (effects != null)
|
|
{
|
|
foreach (var e in effects)
|
|
{
|
|
e.Modifier?.StopEffect(e); //Play Modifier when the effect play
|
|
e.OnStop.Invoke();
|
|
|
|
if (!e.effect.IsPrefab())
|
|
{
|
|
if (e.disableOnStop) e.Instance?.SetActive(false);
|
|
}
|
|
else
|
|
Destroy(e.Instance);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Stops an Effect using its ID value</summary>
|
|
public virtual void Effect_Stop(string name)
|
|
{
|
|
var effects = Effects.FindAll(effect => effect.Name == name && effect.active == true);
|
|
Stop_Effects(effects);
|
|
}
|
|
|
|
private IEnumerator Life(Effect e)
|
|
{
|
|
if (e.life > 0)
|
|
{
|
|
yield return new WaitForSeconds(e.life);
|
|
|
|
e.Modifier?.StopEffect(e); //Play Modifier when the effect play
|
|
e.OnStop.Invoke();
|
|
|
|
if (e.effect.IsPrefab())
|
|
{
|
|
Destroy(e.Instance); //Means the effect is a Prefab destroy the Instance
|
|
}
|
|
else
|
|
{
|
|
if (e.disableOnStop) e.effect.SetActive(false);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
protected virtual void Play(Effect e)
|
|
{
|
|
e.Modifier?.PreStart(e); //Execute the Method PreStart Effect if it has a modifier
|
|
|
|
//Delay an action
|
|
this.Delay_Action(e.delay,
|
|
() =>
|
|
{
|
|
//Play Audio
|
|
if (!e.Clip.NullOrEmpty() && e.audioSource != null)
|
|
{
|
|
e.audioSource.clip = e.Clip.GetValue();
|
|
if (e.audioSource.isPlaying) e.audioSource.Stop();
|
|
e.audioSource.Play();
|
|
}
|
|
|
|
if (e.effect != null)
|
|
{
|
|
if (e.effect.IsPrefab()) //If instantiate is active (meaning is a prefab)
|
|
{
|
|
e.Instance = Instantiate(e.effect); //Instantiate!
|
|
e.Instance.gameObject.SetActive(false);
|
|
}
|
|
else
|
|
{
|
|
e.Instance = e.effect; //Use the effect as the gameobject
|
|
}
|
|
|
|
if (Owner == null) Owner = transform.root;
|
|
if (e.Owner == null) e.Owner = Owner; //Save in all effects that the owner of the effects is this transform
|
|
|
|
|
|
if (e.Instance)
|
|
{
|
|
e.Instance.gameObject.SetActive(true);
|
|
e.Instance.transform.localScale = Vector3.Scale(e.Instance.transform.localScale, e.ScaleMultiplier); //Scale the Effect
|
|
|
|
|
|
//Apply Offsets
|
|
if (e.root)
|
|
{
|
|
e.Instance.transform.position = e.root.position;
|
|
|
|
if (e.isChild)
|
|
{
|
|
e.Instance.transform.parent = e.root;
|
|
|
|
e.Instance.transform.localPosition += e.PositionOffset;
|
|
e.Instance.transform.localRotation *= Quaternion.Euler(e.RotationOffset);
|
|
}
|
|
else
|
|
{
|
|
e.Instance.transform.position = e.root.TransformPoint(e.PositionOffset);
|
|
}
|
|
|
|
if (e.useRootRotation) e.Instance.transform.rotation = e.root.rotation; //Orient to the root rotation
|
|
|
|
}
|
|
|
|
|
|
if (e.effect.IsPrefab()) //get the trailrenderer and particle system from the Instance instead of the prefab
|
|
{
|
|
e.IsTrailRenderer = e.Instance.FindComponent<TrailRenderer>();
|
|
e.IsParticleSystem = e.Instance.FindComponent<ParticleSystem>();
|
|
}
|
|
|
|
if (e.IsTrailRenderer) e.IsTrailRenderer.Clear();
|
|
if (e.IsParticleSystem) e.IsParticleSystem.Play();
|
|
|
|
if (e.Modifier) e.Modifier.StartEffect(e); //Apply Modifier when the effect play
|
|
|
|
StartCoroutine(Life(e));
|
|
}
|
|
}
|
|
e.OnPlay.Invoke(); //Invoke the Play Event
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
/// <summary>IAnimatorListener function </summary>
|
|
public virtual bool OnAnimatorBehaviourMessage(string message, object value) => this.InvokeWithParams(message, value);
|
|
|
|
//─────────────────────────────────CALLBACKS METHODS───────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Disables all effects using their name </summary>
|
|
public virtual void Effect_Disable(string name)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.Name.ToUpper() == name.ToUpper());
|
|
|
|
if (effects != null)
|
|
{
|
|
foreach (var e in effects) e.active = false;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("No effect with the name: " + name + " was found");
|
|
}
|
|
}
|
|
|
|
/// <summary> Disables all effects using their ID</summary>
|
|
public virtual void Effect_Disable(int ID)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.ID == ID);
|
|
|
|
if (effects != null)
|
|
{
|
|
foreach (var e in effects) e.active = false;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("No effect with the ID: " + ID + " was found");
|
|
}
|
|
}
|
|
|
|
/// <summary>Enable all effects using their name</summary>
|
|
public virtual void Effect_Enable(string name)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.Name.ToUpper() == name.ToUpper());
|
|
|
|
if (effects != null)
|
|
{
|
|
foreach (var e in effects) e.active = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("No effect with the name: " + name + " was found");
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary> Enable all effects using their ID</summary>
|
|
public virtual void Effect_Enable(int ID)
|
|
{
|
|
List<Effect> effects = Effects.FindAll(effect => effect.ID == ID);
|
|
|
|
if (effects != null)
|
|
{
|
|
foreach (var e in effects) e.active = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("No effect with the ID: " + ID + " was found");
|
|
}
|
|
}
|
|
|
|
private void Reset()
|
|
{
|
|
Owner = transform.root;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
[ContextMenu("Create Event Listeners")]
|
|
void CreateListeners()
|
|
{
|
|
MEventListener listener = gameObject.FindComponent<MEventListener>();
|
|
|
|
if (listener == null) listener = gameObject.AddComponent<MEventListener>();
|
|
if (listener.Events == null) listener.Events = new List<MEventItemListener>();
|
|
|
|
MEvent effectEnable = MTools.GetInstance<MEvent>("Effect Enable");
|
|
MEvent effectDisable = MTools.GetInstance<MEvent>("Effect Disable");
|
|
|
|
if (listener.Events.Find(item => item.Event == effectEnable) == null)
|
|
{
|
|
var item = new MEventItemListener()
|
|
{
|
|
Event = effectEnable,
|
|
useVoid = false,
|
|
useString = true,
|
|
useInt = true
|
|
};
|
|
|
|
UnityEditor.Events.UnityEventTools.AddPersistentListener(item.ResponseInt, Effect_Enable);
|
|
UnityEditor.Events.UnityEventTools.AddPersistentListener(item.ResponseString, Effect_Enable);
|
|
listener.Events.Add(item);
|
|
|
|
Debug.Log("<B>Effect Enable</B> Added to the Event Listeners");
|
|
}
|
|
|
|
if (listener.Events.Find(item => item.Event == effectDisable) == null)
|
|
{
|
|
var item = new MEventItemListener()
|
|
{
|
|
Event = effectDisable,
|
|
useVoid = false,
|
|
useString = true,
|
|
useInt = true
|
|
};
|
|
|
|
UnityEditor.Events.UnityEventTools.AddPersistentListener(item.ResponseInt, Effect_Disable);
|
|
UnityEditor.Events.UnityEventTools.AddPersistentListener(item.ResponseString, Effect_Disable);
|
|
listener.Events.Add(item);
|
|
|
|
Debug.Log("<B>Effect Disable</B> Added to the Event Listeners");
|
|
}
|
|
|
|
UnityEditor.EditorUtility.SetDirty(listener);
|
|
}
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class Effect
|
|
{
|
|
public string Name = "EffectName";
|
|
public int ID;
|
|
public bool active = true;
|
|
public Transform root;
|
|
|
|
public bool isChild;
|
|
public bool disableOnStop = true;
|
|
public bool useRootRotation = true;
|
|
public GameObject effect;
|
|
public Vector3 RotationOffset;
|
|
public Vector3 PositionOffset;
|
|
public Vector3 ScaleMultiplier = Vector3.one;
|
|
public AudioSource audioSource;
|
|
public AudioClipReference Clip;
|
|
|
|
/// <summary>Life of the Effect</summary>
|
|
public float life = 10f;
|
|
|
|
/// <summary>Delay Time to execute the effect after is called.</summary>
|
|
public float delay;
|
|
|
|
/// <summary>Scriptable Object to Modify anything you want before, during or after the effect is invoked</summary>
|
|
public EffectModifier Modifier;
|
|
|
|
|
|
public UnityEvent OnPlay;
|
|
public UnityEvent OnStop;
|
|
|
|
/// <summary>Returns the Owner of the Effect </summary>
|
|
public Transform Owner { get; set; }
|
|
|
|
/// <summary>Returns the Instance of the Effect Prefab </summary>
|
|
public GameObject Instance { get => instance; set => instance = value; }
|
|
|
|
public TrailRenderer IsTrailRenderer { get; set; }
|
|
public ParticleSystem IsParticleSystem { get; set; }
|
|
|
|
[System.NonSerialized]
|
|
private GameObject instance;
|
|
|
|
internal void Initialize()
|
|
{
|
|
if (effect != null && !effect.IsPrefab()) //Store if the effect its not a prefab
|
|
{
|
|
effect.gameObject.SetActive(false); //Deactivate at start
|
|
IsTrailRenderer = effect.FindComponent<TrailRenderer>();
|
|
IsParticleSystem = effect.FindComponent<ParticleSystem>();
|
|
}
|
|
}
|
|
}
|
|
} |