Skip to content

Instantly share code, notes, and snippets.

@axelrindle
Last active April 12, 2019 13:30
Show Gist options
  • Save axelrindle/3bae3bc676f45c898f8e7a60009f7590 to your computer and use it in GitHub Desktop.
Save axelrindle/3bae3bc676f45c898f8e7a60009f7590 to your computer and use it in GitHub Desktop.
Unity3D Script Collection

Unity3D Script Collection

A Collection of useful Unity3D C# scripts.

License

MIT License

Copyright (c) 2019 Axel Rindle <axel.rindle@gmx.de>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

using System.Collections.Generic;
/// <summary>
/// A bundle holds data that will be saved to disk later.
/// </summary>
public class Bundle
{
#region Fields
private readonly Dictionary<string, object> _data;
/// <summary>
/// Returns the amount of data included.
/// </summary>
public int Count {
get {
return _data.Count;
}
}
#endregion
#region Constructors
public Bundle (Dictionary<string, object> data)
{
_data = data;
}
public Bundle () : this (new Dictionary<string, object> ())
{
}
#endregion
#region Put Methods
public Bundle Put (string key, object obj)
{
_data.Add (key, obj);
return this;
}
public Bundle PutString (string key, string str)
{
_data.Add (key, str);
return this;
}
public Bundle PutInt (string key, int i)
{
_data.Add (key, i);
return this;
}
public Bundle PutFloat (string key, float f)
{
_data.Add (key, f);
return this;
}
public Bundle PutBundle (string key, Bundle bundle)
{
_data.Add (key, bundle);
return this;
}
#endregion
#region Get Methods
public object Get (string key)
{
return _data [key];
}
public string GetString (string key)
{
var obj = _data [key];
return obj as string;
}
public int GetInt (string key)
{
var obj = _data [key];
if (obj is int) {
return (int)obj;
}
return -1;
}
public float GetFloat (string key)
{
var obj = _data [key];
if (obj is float) {
return (float)obj;
}
return -1;
}
public Bundle GetBundle (string key)
{
var obj = _data [key];
return obj as Bundle;
}
#endregion
}
using System;
using InfoProjekt.Util;
using UnityEditor;
using UnityEngine;
/// <summary>
/// An Editor Script used to remove multiple components from all selected GameObjects.
/// </summary>
public class RemoveMultipleComponents : ScriptableObject
{
[MenuItem("Utilities/Remove Multiple MeshCollider")]
static void Execute()
{
UniversalRemove(typeof(MeshCollider));
}
private static void UniversalRemove(Type type)
{
var selected = Selection.gameObjects;
foreach (var obj in selected)
{
var components = obj.GetComponents(type);
if (components.Length <= 1)
continue;
var sub = components.SubArray(1, components.Length - 1);
foreach(var _sub in sub)
{
DestroyImmediate(_sub);
}
}
}
}
using UnityEngine;
using System;
using System.Collections;
/// <summary>
/// A Sequence is a list of functions that are called successively.
/// </summary>
public class Sequence
{
#region Init
/// <summary>
/// Creates a new Sequence.
/// </summary>
/// <param name="mb">The MonoBehaviour to run this on.</param>
/// <returns></returns>
public static Sequence Create(MonoBehaviour mb)
{
return new Sequence(mb);
}
private MonoBehaviour mb;
private ArrayList items;
private Invokeable finished;
private bool isRunning;
private Sequence(MonoBehaviour mb)
{
this.mb = mb;
this.items = new ArrayList();
}
#endregion
#region Items
/// <summary>
/// A default function.
/// </summary>
public delegate void Invokeable();
/// <summary>
/// Delegate function for an item that is asynchronous but not a coroutine.
/// </summary>
/// <param name="done">Should be called when the work is done.</param>
public delegate void AsyncInvokeable(Action done);
/// <summary>
/// Adds a normal function.
/// </summary>
/// <param name="invoked">The delegate function.</param>
/// <returns>This Sequence to allow for function chaining.</returns>
public Sequence Push(Invokeable invoked)
{
items.Add(invoked);
return this;
}
/// <summary>
/// Adds an async function, which takes one parameter "done" which
/// resolves this part of the sequence.
/// </summary>
/// <param name="invoked">The delegate function.</param>
/// <returns>This Sequence to allow for function chaining.</returns>
public Sequence PushAsync(AsyncInvokeable invoked)
{
items.Add(invoked);
return this;
}
/// <summary>
/// Adds an IEnumerator which blocks the execution of the Sequence
/// until it finishes it's work.
/// </summary>
/// <param name="invoked">The IEnumerator.</param>
/// <returns>This Sequence to allow for function chaining.</returns>
public Sequence PushCoroutine(IEnumerator invoked)
{
items.Add(invoked);
return this;
}
/// <summary>
/// Adds a delay to the function execution. Execution is blocked for
/// the given amount of seconds.
/// </summary>
/// <param name="seconds">The amount of seconds to block execution for.</param>
/// <returns>This Sequence to allow for function chaining.</returns>
public Sequence Delay(float seconds)
{
items.Add(seconds);
return this;
}
/// <summary>
/// Sets a listener, which is called the Sequence has come to it's end.
/// </summary>
/// <param name="finished">The delegate function.</param>
/// <returns>This Sequence to allow for function chaining.</returns>
public Sequence OnFinish(Invokeable finished)
{
this.finished = finished;
return this;
}
#endregion
/// <summary>
/// Starts this sequence.
/// </summary>
public void Play()
{
if (isRunning)
{
Debug.LogWarning("A sequence can't be started twice!");
return;
}
isRunning = true;
mb.StartCoroutine(Invoke());
}
#region Internal
private IEnumerator Invoke()
{
Debug.Log("A Sequence has started.");
if (items.Count > 0)
{
foreach (object item in items)
{
if (item is float)
{
float sec = (float)item;
yield return new WaitForSeconds(sec);
}
else if (item is Invokeable)
{
Invokeable i = (Invokeable)item;
i.Invoke();
}
else if (item is AsyncInvokeable)
{
AsyncInvokeable ai = (AsyncInvokeable)item;
yield return new AsyncYieldInstruction(ai);
}
else if (item is IEnumerator)
{
IEnumerator enumerator = (IEnumerator)item;
yield return enumerator;
}
}
// all items have been invoked
isRunning = false;
if (finished != null)
{
finished.Invoke();
}
Debug.Log("A Sequence has ended.");
}
else
{
Debug.LogWarning("Can't play an empty Sequence!");
yield return null;
}
}
/// <summary>
/// Defines a YieldInstruction that returns when a "done" function is called.
/// </summary>
private class AsyncYieldInstruction : CustomYieldInstruction
{
public override bool keepWaiting
{
get
{
return !isDone;
}
}
private bool isDone;
public AsyncYieldInstruction(AsyncInvokeable invokeable)
{
invokeable(() => {
this.isDone = true;
});
}
}
#endregion
}
using UnityEditor;
using UnityEngine;
/// <summary>
/// An Editor Script to sort all direct children of a selected GameObject.
/// </summary>
public class SortChildren : ScriptableObject
{
[MenuItem("Utilities/Sort Children")]
static void Execute()
{
var selected = Selection.transforms;
if (selected.Length == 0)
{
Debug.LogError("No GameObjects were selected!");
return;
}
if (selected.Length > 1)
{
Debug.LogError("Only one GameObject at a time can be sorted!");
return;
}
var obj = selected[0];
var children = obj.childCount;
do
{
var n = 1;
for (int i = 0; i < children - 1; i++)
{
var child1 = obj.GetChild(i);
var child2 = obj.GetChild(i + 1);
if (child1.name.CompareTo(child2.name) > 0)
{
child1.SetSiblingIndex(i + 1);
child2.SetSiblingIndex(i);
n = i + 1;
}
}
children = n;
} while (children > 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment