<|start_filename|>Runtime/Debugging/DebugCommandBase.cs<|end_filename|>

using System;

public class DebugCommandBase
{
    private string _commandId;
    private string _commandDescription;
    private string _commandFormat;
    
    public string commandId {get { return _commandId;}}
    public string commandDesc {get { return _commandDescription;}}
    public string commandFormat {get { return _commandFormat;}}

    public DebugCommandBase(string id, string description, string format)
    {
        _commandId = id;
        _commandDescription = description;
        _commandFormat = format;
    }
    
}

public class DebugCommand : DebugCommandBase
{
    public Action command;

    public DebugCommand(string id, string description, string format, Action command) : base(id, description, format)
    {
        this.command = command;
    }

    public void InvokeAntion()
    {
        command.Invoke();
    }

}

<|start_filename|>Runtime/OnTrigger/OnTrigger2D.cs<|end_filename|>
﻿using MyBox;
using UnityEngine;
using UnityEngine.Events;

namespace VOID.GE
{
    [RequireComponent(typeof(Collider2D))]
    public class OnTrigger2D : MonoBehaviour
    {
        [Tag]
        public string colliderTag;
        [Space]
        public UnityEvent onEnter;
        public UnityEvent onStay;
        public UnityEvent onExit;

        private void OnValidate()
        {
            GetComponent<Collider2D>().isTrigger = true;
        }

        private void OnTriggerEnter2D(Collider2D other)
        {
            if (!other.gameObject.CompareTag(colliderTag)) return;
            onEnter.Invoke();
        }
    
        private void OnTriggerStay2D(Collider2D other)
        {
            if(!other.gameObject.CompareTag(colliderTag)) return;
            onStay.Invoke();
        }

        private void OnTriggerExit2D(Collider2D other)
        {
            if(!other.gameObject.CompareTag(colliderTag)) return;
            onExit.Invoke();

        }
    }
}

<|start_filename|>Runtime/ScriptableObjects/Variables/ColorVariable.cs<|end_filename|>
﻿using UnityEngine;

namespace BirdTools
{
    [CreateAssetMenu(fileName = "color_", menuName = "BirdTools/Variables/Color", order = 0)]
    public class ColorVariable : ScriptableObject
    {
        public Color Value;
        public void SetValue(Color value)
        {
            Value = value;
        }

        public void SetValue(ColorVariable value)
        {
            Value = value.Value;
        }
        
        public void ApplyChange(Color amount)
        {
            Value += amount;
        }

        public void ApplyChange(ColorVariable amount)
        {
            Value += amount.Value;
        }
    }
}

<|start_filename|>Runtime/Events/GameEventListener.cs<|end_filename|>
﻿using System.Collections;
using UnityEngine;
using UnityEngine.Events;

namespace BirdTools
{
    public class GameEventListener : MonoBehaviour
    {
#if UNITY_EDITOR
        public string developerDescription = "RaiseBy: ";
#endif
        [Tooltip("Just raise event once")]
        public bool once = false;
        
        [Tooltip("Delay before raise the event")]
        [Range(0, 10)] public float delay = 0;
        
        [Tooltip("Raise this event on start")]
        public bool autoPlay = false;
        [Space]
        public GameEvent GameEvent;
        public UnityEvent Response;
        
        private bool isRaised = false;
        private void OnEnable()
        {
            GameEvent.SubscribeListener(this);
        }
        
        private void OnDisable()
        {
            GameEvent.UnsubscribeListener(this);
        }

        private void Start()
        {
            if(autoPlay) OnEventRaised();
        }

        public void OnEventRaised()
        {
            StartCoroutine(OnEventRaiseCoroutine());
            
        }

        private IEnumerator OnEventRaiseCoroutine()
        {
            if (once && isRaised) yield break;

            yield return new WaitForSeconds(delay);
            Response.Invoke();
            isRaised = true;
        }

    }
}

<|start_filename|>Runtime/ScriptableObjects/Variables/ColorReference.cs<|end_filename|>
using System;
using UnityEngine;
namespace BirdTools
{
    [Serializable]
    public class ColorReference : VariableReference
    {
        public Color ConstantValue;
        public ColorVariable Variable;

        public ColorReference()
        { }

        public ColorReference(Color value)
        {
            UseConstant = true;
            ConstantValue = value;
        }

        public Color Value
        {
            get { return UseConstant ? ConstantValue : Variable.Value; }
        }

        public static implicit operator Color(ColorReference reference)
        {
            return reference.Value;
        }
    }
}

<|start_filename|>package.json<|end_filename|>
{
  "name": "com.amirardroudi.birdtools",
  "displayName": "birdTools package",
  "version": "1.0.0",
  "unity": "2020.4",
  "keywords": [
    "Tools"
  ],
  "description": "birdTools is a handly toolbox for unity game development."
}

<|start_filename|>Runtime/OnTrigger/OnTrigger.cs<|end_filename|>
﻿using MyBox;
using UnityEngine;
using UnityEngine.Events;

namespace VOID.GE
{
    [RequireComponent(typeof(Collider))]
    public class OnTrigger : MonoBehaviour
    {
        [Tag]
        public string colliderTag;
        [Space]
        public UnityEvent onEnter;
        public UnityEvent onStay;
        public UnityEvent onExit;

        private void OnValidate()
        {
            GetComponent<Collider>().isTrigger = true;
        }

        private void OnTriggerEnter(Collider other)
        {
            if (!other.gameObject.CompareTag(colliderTag)) return;
            onEnter.Invoke();
        }
    
        private void OnTriggerStay(Collider other)
        {
            if(!other.gameObject.CompareTag(colliderTag)) return;
            onStay.Invoke();
        }

        private void OnTriggerExit(Collider other)
        {
            if(!other.gameObject.CompareTag(colliderTag)) return;
            onExit.Invoke();

        }
    }
}

<|start_filename|>Runtime/Debugging/DebugConsole.cs<|end_filename|>
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Object = System.Object;

//TODO: create command history window
//DONE: change keyboard focus from inputField to gameplay after clicking return key
//TODO: after opening console keyboard focus should be set on inputField
//TODO: event-based triggering commands

public class DebugConsole : MonoBehaviour
{
    [Header("Console Settings")]
    public Vector2 consolePosition = new Vector2(0, 30);
    public Color consoleColor = new Color(0.8f, 1, 0, 0.9f);
    public KeyCode consoleKey = KeyCode.BackQuote;
    
    [SerializeField]private string _input;
    
    public static DebugCommand God, Mecry, Help;
    public List<Object> commandList;
    public bool showConsole = false;
    public bool showHelp = false;
    private void Awake()
    {
        Help = new DebugCommand("help", "show me verses",
            "help",
            () =>
            {
                    showHelp = true;
            });
        
        God = new DebugCommand("command1", "command description ",
            "command1",
            () =>
            {

            });
        Mecry = new DebugCommand("command2", "command descripsion ",
            "command2",
            () =>
            {

            });
        
        
        commandList = new List<object>
        {
            Help,
            God,
            Mecry
        };

    }

    private void Update()
    {
        if (Input.GetKeyDown(consoleKey))
        {
            showConsole = true;
        }
    }
    
    private void HandleInput()
    {
        for (int i = 0; i < commandList.Count; i++)
        {
            DebugCommandBase commandBase = commandList[i] as DebugCommandBase;

            if (_input.Contains(commandBase.commandId))
            {
                DebugCommand command = commandList[i] as DebugCommand;
                command?.InvokeAntion();
            }
        }
    }

    private Vector2 _scroll;
    private void OnGUI()
    {
        if (Event.current.Equals(Event.KeyboardEvent("return")))
        {
            showConsole = false;
            // showHelp = false;

            GUIUtility.keyboardControl = 0;
            HandleInput();
            _input = "";
        }

        if (showConsole)
        {
            // ********************** inputfield viewport **********************
            GUI.Box(new Rect(consolePosition.x, Screen.height + consolePosition.y, Screen.width, 50), "");
            GUI.backgroundColor = consoleColor;
            GUI.SetNextControlName("input");
            _input = GUI.TextField(
                new Rect(consolePosition.x, Screen.height + consolePosition.y, Screen.width - 20f, 23f), _input);
            GUI.FocusControl("input");
            
            
            // ********************** help viewport **********************
            GUI.Box(new Rect(0, Screen.height - consolePosition.y - 50, Screen.width, 100),"");
            Rect viewport = new Rect(0,0, Screen.width - 30, 20 * commandList.Count);

            _scroll = GUI.BeginScrollView(new Rect(0, consolePosition.y + 5f, Screen.width, 90), _scroll, viewport);

            for (int i = 0; i < commandList.Count; i++)
            {
                DebugCommandBase command = commandList[i] as DebugCommandBase;

                string label = $"{command.commandFormat} - {command.commandDesc}";
                Rect labelRect = new Rect(5, 20 * i, viewport.width-100, 23);
                GUI.Label(labelRect, label);

            }
            GUI.backgroundColor = consoleColor;

            GUI.EndScrollView();
            // **********************************************************
        }
    }
}


<|start_filename|>Runtime/ScriptableObjects/Variables/StringVariable.cs<|end_filename|>
﻿using UnityEngine;

namespace BirdTools
{
    [CreateAssetMenu (fileName = "string_", menuName = "BirdTools/Variables/String")]
    public class StringVariable : ScriptableObject
    {
        public string Value;

        public void SetValue(string value)
        {
            Value = value;
        }
        public void SetValue(StringVariable value)
        {
            Value = value.Value;
        }
        
        

    }
}

<|start_filename|>Runtime/Events/AudioSO.cs<|end_filename|>
﻿using UnityEngine;

namespace BirdTools
{
    [CreateAssetMenu(fileName = "audioSO_title", menuName = "BirdTools/Variables/AudioClip")]
    public class AudioSO : AudioEvent
    {
        public AudioClip[] clips;
        [MinMax(0, 1)] public RangedFloat volume;
        [MinMax(-3, 3)] public RangedFloat pitch;

        public override void Play(AudioSource source)
        {
            if (clips.Length == 0) return;

            source.clip = clips[Random.Range(0, clips.Length)];
            source.volume = Random.Range(volume.Min, volume.Max);
            source.pitch =  Random.Range(pitch.Min, pitch.Max);
            source.Play();
        }
        
    }
    
}

<|start_filename|>Runtime/Events/AudioEvent.cs<|end_filename|>
﻿using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace BirdTools
{
    public abstract class AudioEvent : ScriptableObject
    {
        public abstract void Play(AudioSource source);
    }
    
#if UNITY_EDITOR
    [CustomEditor(typeof(AudioEvent), true)]
    public class AudioEventEditor : UnityEditor.Editor
    {
        [SerializeField] private AudioSource _previewer;

        private void OnEnable()
        {
            _previewer = EditorUtility.CreateGameObjectWithHideFlags("audio preview",
                    HideFlags.HideAndDontSave, typeof(AudioSource))
                .GetComponent<AudioSource>();
        }

        private void OnDisable()
        {
            DestroyImmediate(_previewer.gameObject);
        }

        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();
        
            EditorGUI.BeginDisabledGroup(serializedObject.isEditingMultipleObjects);
            if (GUILayout.Button("preview"))
            {
                ((AudioEvent) target).Play(_previewer);
            }
            EditorGUI.EndDisabledGroup();
        }
    }
#endif
}

<|start_filename|>Runtime/ScriptableObjects/Variables/FloatVariable.cs<|end_filename|>
﻿using UnityEngine;

namespace BirdTools
{
    [CreateAssetMenu(fileName = "float_", menuName = "BirdTools/Variables/Float")]
    public class FloatVariable : ScriptableObject
    {
        public float Value;
        public void SetValue(float value)
        {
            Value = value;
        }

        public void SetValue(FloatVariable value)
        {
            Value = value.Value;
        }
        
        public void ApplyChange(float amount)
        {
            Value += amount;
        }

        public void ApplyChange(FloatVariable amount)
        {
            Value += amount.Value;
        }
    }
}

<|start_filename|>Runtime/Events/GameEvent.cs<|end_filename|>
﻿using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace BirdTools
{
    [CreateAssetMenu(fileName = "ev_title", menuName = "BirdTools/Events/voidEvent")]
    public class GameEvent : ScriptableObject
    {
        /// <summary>
        /// By Raising this event, the list of listeners will notify 
        /// </summary>
        private readonly List<GameEventListener> _listeners = new List<GameEventListener>();

        public void Raise()
        {
            // We iterate through this list from its top without out of range exception
            // in the case that response of the listener was a call to remove it from the list.
            for (int i = _listeners.Count - 1; i >= 0; i--)
                _listeners[i].OnEventRaised();
        }

        public void UnsubscribeListener(GameEventListener listener)
        {
            if (_listeners.Contains(listener))
                _listeners.Remove(listener);
        }
        public void SubscribeListener(GameEventListener listener)
        {
            if (!_listeners.Contains(listener))
                _listeners.Add(listener);
        }
    }

#if UNITY_EDITOR
    
    [CustomEditor(typeof(GameEvent), editorForChildClasses: true)]
    public class GameEventEditor : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            
            base.OnInspectorGUI();

            GUI.enabled = true;
            
            GameEvent e = target as GameEvent;
            
            if(GUILayout.Button("Raise Event"))
                e.Raise();
        }
    }
    
#endif
}


<|start_filename|>Runtime/ScriptableObjects/Runtime Sets/RuntimeSet.cs<|end_filename|>
﻿using System.Collections.Generic;
using UnityEngine;

namespace BirdTools
{
    public abstract class RuntimeSet<T> : ScriptableObject
    {
        public List<T> Items = new List<T>();

        public void Add(T t)
        {
            if(!Items.Contains(t)) Items.Add(t);
        }

        public void Remove(T t)
        {
            if (Items.Contains(t)) Items.Remove(t);
        }

    }
}