Created
January 16, 2020 13:05
-
-
Save Moe-Baker/4f127f78c36e62a4019e7fbf30c08ca6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using UnityEngine.SceneManagement; | |
using UnityEngine.AI; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
using UnityEditorInternal; | |
#endif | |
using Object = UnityEngine.Object; | |
using Random = UnityEngine.Random; | |
namespace Game | |
{ | |
public class SpriteSheetAnimator : MonoBehaviour | |
{ | |
[SerializeField] | |
protected Texture2D source; | |
public Texture2D Source { get { return source; } } | |
[SerializeField] | |
protected List<Point> elements; | |
public List<Point> Elements { get { return elements; } } | |
[Serializable] | |
public class Point | |
{ | |
[SerializeField] | |
protected Motion[] motions; | |
public Motion[] Motions { get { return motions; } } | |
[SerializeField] | |
protected FloatToggleValue frameTime; | |
public FloatToggleValue FrameTime { get { return frameTime; } } | |
public Point(Motion[] motions) | |
{ | |
this.motions = motions; | |
} | |
public Point(Motion motion) : this(new Motion[] { motion }) | |
{ | |
} | |
public Point(Sprite sprite) : this(new Motion(sprite)) | |
{ | |
} | |
} | |
[Serializable] | |
public class Motion | |
{ | |
[SerializeField] | |
protected Sprite sprite; | |
public Sprite Sprite { get { return sprite; } } | |
[SerializeField] | |
protected int channel = 0; | |
public int Channel { get { return channel; } } | |
[SerializeField] | |
protected bool clear = false; | |
public bool Clear { get { return clear; } } | |
public Motion(Sprite sprite) | |
{ | |
this.sprite = sprite; | |
} | |
} | |
[Header("Playback")] | |
[SerializeField] | |
protected float frameTime = 0.1f; | |
public float FrameTime { get { return frameTime; } } | |
[SerializeField] | |
protected bool playOnAwake; | |
public bool PlayOnAwake { get { return playOnAwake; } } | |
[SerializeField] | |
protected bool loop; | |
public bool Loop { get { return loop; } } | |
[SerializeField] | |
protected ChannelsController channels; | |
public ChannelsController Channels { get { return channels; } } | |
[Serializable] | |
public class ChannelsController | |
{ | |
public Dictionary<int, SpriteRenderer> Dictionary { get; protected set; } | |
public int Count => Dictionary.Count; | |
public SpriteRenderer this[int index] => Retrieve(index); | |
public Sandbox Reference { get; protected set; } | |
public virtual void Init(Sandbox reference) | |
{ | |
this.Reference = reference; | |
Dictionary = new Dictionary<int, SpriteRenderer>(); | |
} | |
public virtual SpriteRenderer Retrieve(int index) | |
{ | |
if (Dictionary.ContainsKey(index)) | |
return Dictionary[index]; | |
else | |
{ | |
var instance = Create(index); | |
Dictionary.Add(index, instance); | |
return instance; | |
} | |
} | |
public virtual SpriteRenderer Create(int index) | |
{ | |
var gameObject = new GameObject("Channel " + index); | |
gameObject.transform.SetParent(Reference.transform); | |
gameObject.transform.localPosition = Vector3.zero; | |
gameObject.transform.localRotation = Quaternion.identity; | |
gameObject.transform.localScale = Vector3.one; | |
var renderer = gameObject.AddComponent<SpriteRenderer>(); | |
renderer.sortingOrder = index; | |
return renderer; | |
} | |
public virtual void ForAll(Action<SpriteRenderer> action) | |
{ | |
foreach (var renderer in Dictionary.Values) | |
action(renderer); | |
} | |
public void Clear() | |
{ | |
ForAll(Action); | |
void Action(SpriteRenderer renderer) => renderer.sprite = null; | |
} | |
} | |
private void Awake() | |
{ | |
channels.Init(this); | |
if (playOnAwake) Play(); | |
} | |
#if UNITY_EDITOR | |
private void Reset() | |
{ | |
ConvertSource(); | |
} | |
void ConvertSource() | |
{ | |
if (source == null) | |
{ | |
} | |
else | |
{ | |
var path = AssetDatabase.GetAssetPath(source); | |
var sprites = AssetDatabase.LoadAllAssetsAtPath(path).OfType<Sprite>().ToList(); | |
elements = new List<Point>(); | |
for (int i = 0; i < sprites.Count; i++) | |
{ | |
var instance = new Point(sprites[i]); | |
elements.Add(instance); | |
} | |
} | |
} | |
#endif | |
public void Play() | |
{ | |
if(coroutine != null) StopCoroutine(coroutine); | |
if(elements.Count == 0) | |
{ | |
Debug.LogWarning("No sprites defined, ignoring play request"); | |
return; | |
} | |
channels.Clear(); | |
coroutine = StartCoroutine(Procedure()); | |
} | |
Coroutine coroutine; | |
IEnumerator Procedure() | |
{ | |
var index = 0; | |
while (true) | |
{ | |
var element = elements[index]; | |
for (int i = 0; i < element.Motions.Length; i++) | |
Apply(element.Motions[i]); | |
yield return new WaitForSeconds(element.FrameTime.Evaluate(frameTime)); | |
if (++index == elements.Count) | |
{ | |
channels.Clear(); | |
if (loop) | |
index = 0; | |
else | |
break; | |
} | |
} | |
coroutine = null; | |
} | |
protected virtual void Apply(Motion motion) | |
{ | |
var channel = channels[motion.Channel]; | |
if (motion.Clear) channels.Clear(); | |
channels[motion.Channel].sprite = motion.Sprite; | |
} | |
[CustomEditor(typeof(Sandbox))] | |
public class Inspector : Editor | |
{ | |
new IList<Sandbox> targets; | |
private void OnEnable() | |
{ | |
targets = base.targets.Cast<Sandbox>().ToArray(); | |
} | |
public override void OnInspectorGUI() | |
{ | |
base.OnInspectorGUI(); | |
DrawProcessButton(); | |
} | |
void DrawProcessButton() | |
{ | |
if(GUILayout.Button("Convert Source")) | |
{ | |
for (int i = 0; i < targets.Count; i++) | |
{ | |
targets[i].ConvertSource(); | |
} | |
} | |
} | |
} | |
} | |
[Serializable] | |
public class ComplexToggleValue : ToggleValue<ComplexToggleValue.Data> | |
{ | |
[Serializable] | |
public class Data | |
{ | |
public IntToggleValue _int; | |
public FloatToggleValue _float; | |
public StringToggleValue _string; | |
public ColorToggleValue _color; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment