Skip to content

Instantly share code, notes, and snippets.

View tomkail's full-sized avatar

Tom Kail tomkail

View GitHub Profile
@tomkail
tomkail / OnOpenUnityEditorExample.cs
Created May 4, 2018 10:03
Example of how to get a callback that only runs when Unity opens (not on script recompile)
[InitializeOnLoad]
public static class OnOpenUnityEditorExample {
const string lastCompileTimeKey = "InkIntegrationLastCompileTime";
static InkEditorUtils () {
float lastCompileTime = LoadAndSaveLastCompileTime();
if(EditorApplication.timeSinceStartup < lastCompileTime)
OnOpenUnityEditor();
}
static void OnOpenUnityEditor () {
@tomkail
tomkail / MultitouchDraggable.cs
Last active July 26, 2022 21:49
Multitouch UI Draggable
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
// Handles moving, scaling and rotating UI objects using multitouch.
// Should be just about 1-1, as you'd expect on a touch screen, although because it applies deltas there's a bit of "slippage" if you manipulate the same object for a while/rapidly.
// To test multitouch with a mouse editor you can comment out the marked line in OnEndDrag.
public class MultitouchDraggable : Selectable, IBeginDragHandler, IEndDragHandler, IDragHandler {
@tomkail
tomkail / LoadableSprite.cs
Last active August 9, 2022 07:48
Loads a Sprite, instantly or asynchronously, using Resources.
// Example usage -
// LoadableSprite loadableSprite = new LoadableSprite ("texture");
// loadableSprite.LoadAsync (loadedSprite => {
// Do stuff on load here!
// })
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// You'll need to put this in your scene somewhere so the LoadableSprite class can use coroutines.
@tomkail
tomkail / Better TextMeshPro GetRenderedValues
Created September 7, 2022 09:02
Better GetRenderedValues for TextMeshPro that doesn't return NaN/other invalid values and allows you to test with custom text
// Gets the tightest bounds for the text by updating the text and using GetRenderedValues
// Note this uses sizeDelta for sizing so won't work when using anchors.
// This is wayyyy more reliable than the actual GetRenderedValues because it won't return stupid values, as GetRenderedValues is prone to doing.
public static Vector2 GetRenderedValues (this TMP_Text textMeshPro, string text, float maxWidth = Mathf.Infinity, float maxHeight = Mathf.Infinity, bool onlyVisibleCharacters = true) {
if(string.IsNullOrEmpty(text)) return Vector2.zero;
var originalRenderMode = textMeshPro.renderMode;
var originalText = textMeshPro.text;
var originalDeltaSize = textMeshPro.rectTransform.sizeDelta;
@tomkail
tomkail / ColorDescriptor.cs
Last active September 14, 2022 17:29
Describes a color in english. Crude implementation, but handy for scanning colors when shown in text fields.
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public static class ColorDescriptor {
public static string GetNameForColor (Color color) {
var bestDist = float.MaxValue;
string best = null;
foreach(var colorName in colorNames) {
@tomkail
tomkail / DefaultAssetEditor.cs
Last active September 16, 2022 15:02
Draws inspectors for any file type Unity doesn't draw by default
/// Used to draw custom inspectors for unrecognised file types, which Unity imports as "DefaultAsset"
/// To do this, create a new editor class extending DefaultAssetInspector
/// Return true in the IsValid function if the file extension of the file matches the type you'd like to draw.
/// The DefaultAssetEditor class will then hold a reference to the new instance of your editor class and call the appropriate methods for drawing.
/// An example can be found at the bottom of the file.
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
@tomkail
tomkail / Trim Ends.txt
Created November 3, 2022 13:10
Audacity macro to trim 5 seconds from the start and end of a track
Select:End="5" RelativeTo="ProjectStart" Start="0" Track="0" TrackCount="1"
Delete:
Select:End="5" RelativeTo="ProjectEnd" Start="0" Track="0" TrackCount="1"
Delete:
@tomkail
tomkail / Seamless Loop.txt
Last active November 3, 2022 16:33
Audacity macro to create seamless loops from audio tracks
Select:End="100000" RelativeTo="Project" Start="40" Track="0" TrackCount="1"
Delete:
Select:End="2" RelativeTo="ProjectEnd" Start="0"
Copy:
SelectNone:
Paste:
SelectTracks:Mode="Set" Track="0" TrackCount="2"
CrossfadeTracks:curve="0" direction="Automatic" type="ConstantGain"
MixAndRender:
SelectNone:
@tomkail
tomkail / GetLocalToAnchoredPositionOffset.cs
Created December 20, 2022 14:47
Converts between localPosition and anchoredPosition for a RectTransform.
// Add this to convert a local position to an anchored position
public static Vector2 GetLocalToAnchoredPositionOffset(this RectTransform rectTransform) {
var parentRT = (RectTransform) rectTransform.parent;
var pivotAnchor = new Vector2(Mathf.LerpUnclamped(rectTransform.anchorMin.x, rectTransform.anchorMax.x, rectTransform.pivot.x), Mathf.LerpUnclamped(rectTransform.anchorMin.y, rectTransform.anchorMax.y, rectTransform.pivot.y));
return -parentRT.rect.size * (pivotAnchor - parentRT.pivot);
}
// Add this to convert a local position to an anchored position
public static Vector2 GetAnchoredToLocalPositionOffset(this RectTransform rectTransform) {
return -rectTransform.GetLocalToAnchoredPositionOffset();
@tomkail
tomkail / CreateEditorScriptMenuItem.cs
Last active July 13, 2023 12:39
Adds "Create > Editor Script" menu to scripts a right click that automatically creates editor scripts.
using System;
using System.Globalization;
using System.Text;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
public static class CreateEditorScriptMenuItem {