├── .github └── workflows │ └── tagUPM.yml ├── .gitignore ├── ArduinoSerialCommunication.cs ├── ArduinoSerialCommunication.cs.meta ├── Audio.meta ├── Audio ├── AudioPool.cs ├── AudioPool.cs.meta ├── RandomizedSoundEffect.cs ├── RandomizedSoundEffect.cs.meta ├── RhythmTracker.cs └── RhythmTracker.cs.meta ├── ColorPalettes.cs ├── ColorPalettes.cs.meta ├── Editor.meta ├── Editor ├── BezierPathEditor.cs ├── BezierPathEditor.cs.meta ├── ExtendedGradientDrawer.cs ├── ExtendedGradientDrawer.cs.meta ├── HideFlagsUtility.cs ├── HideFlagsUtility.cs.meta ├── ImageSequenceRecorder.cs ├── ImageSequenceRecorder.cs.meta ├── MapToCurveInspectorGUI.cs ├── MapToCurveInspectorGUI.cs.meta ├── MultiRename.cs ├── MultiRename.cs.meta ├── NumberingUtility.cs ├── NumberingUtility.cs.meta ├── PaletteGenerator.cs ├── PaletteGenerator.cs.meta ├── PathGuideEditor.cs ├── PathGuideEditor.cs.meta ├── ScriptCreationUtils.meta ├── ScriptCreationUtils │ ├── NewScriptHandler.cs │ ├── NewScriptHandler.cs.meta │ ├── WrjSettings.cs │ ├── WrjSettings.cs.meta │ ├── WrjSettingsRegister.cs │ └── WrjSettingsRegister.cs.meta ├── wrj.utils.editor.asmdef └── wrj.utils.editor.asmdef.meta ├── ExtensionMethods.cs ├── ExtensionMethods.cs.meta ├── Keybindings.cs ├── Keybindings.cs.meta ├── LICENSE ├── LICENSE.meta ├── LayoutGroups.meta ├── LayoutGroups ├── CurvedGridLayout3d.cs ├── CurvedGridLayout3d.cs.meta ├── GridLayout3d.cs ├── GridLayout3d.cs.meta ├── LayoutGroup3d.cs └── LayoutGroup3d.cs.meta ├── PathFollowerExample.gif ├── PathFollowerExample.gif.meta ├── Paths.meta ├── Paths ├── BezierPath.cs ├── BezierPath.cs.meta ├── PathGuide.cs └── PathGuide.cs.meta ├── PoolManager.cs ├── PoolManager.cs.meta ├── Prefs.png ├── Prefs.png.meta ├── QueryStringParser.cs ├── QueryStringParser.cs.meta ├── README.md ├── README.md.meta ├── Resources.meta ├── Resources ├── WordList.txt ├── WordList.txt.meta ├── WordListTop1000.txt ├── WordListTop1000.txt.meta ├── WordListTop3000.txt ├── WordListTop3000.txt.meta ├── WordListTop6000.txt └── WordListTop6000.txt.meta ├── Samples~ ├── Example Scenes.meta ├── Example Scenes │ ├── Assets.meta │ ├── Assets │ │ ├── Scripts.meta │ │ ├── Scripts │ │ │ ├── CurvedWeightedTest.cs │ │ │ ├── CurvedWeightedTest.cs.meta │ │ │ ├── PathFollowTest.cs │ │ │ ├── PathFollowTest.cs.meta │ │ │ ├── Test.cs │ │ │ └── Test.cs.meta │ │ ├── Smile.mat │ │ ├── Smile.mat.meta │ │ ├── TrailMaterial.mat │ │ ├── TrailMaterial.mat.meta │ │ ├── click1.ogg │ │ ├── click1.ogg.meta │ │ ├── click2.ogg │ │ ├── click2.ogg.meta │ │ ├── click3.ogg │ │ ├── click3.ogg.meta │ │ ├── click4.ogg │ │ ├── click4.ogg.meta │ │ ├── click5.ogg │ │ ├── click5.ogg.meta │ │ ├── smile.jpg │ │ └── smile.jpg.meta │ ├── CurvePath.meta │ ├── CurvePath.unity │ ├── CurvePath.unity.meta │ ├── CurvePath │ │ ├── LightingData.asset │ │ ├── LightingData.asset.meta │ │ ├── ReflectionProbe-0.exr │ │ └── ReflectionProbe-0.exr.meta │ ├── ExampleScene.meta │ ├── ExampleScene.unity │ ├── ExampleScene.unity.meta │ └── ExampleScene │ │ ├── LightingData.asset │ │ ├── LightingData.asset.meta │ │ ├── ReflectionProbe-0.exr │ │ └── ReflectionProbe-0.exr.meta ├── Presets.meta └── Presets │ ├── Editor.meta │ └── Editor │ ├── EasingCurves.curves │ ├── EasingCurves.curves.meta │ ├── Modern.colors │ ├── Modern.colors.meta │ ├── UIColors.colors │ └── UIColors.colors.meta ├── ScreenBorders.cs ├── ScreenBorders.cs.meta ├── ScreenSizeNotifier.cs ├── ScreenSizeNotifier.cs.meta ├── ShowHideGroup.cs ├── ShowHideGroup.cs.meta ├── Smile.gif ├── Smile.gif.meta ├── SmoothFollow.cs ├── SmoothFollow.cs.meta ├── TweenExample.gif ├── TweenExample.gif.meta ├── WeightedElements.cs ├── WeightedElements.cs.meta ├── WordList.cs ├── WordList.cs.meta ├── WrjUtils.cs ├── WrjUtils.cs.meta ├── package.json ├── package.json.meta ├── wrj.utils.asmdef └── wrj.utils.asmdef.meta /.github/workflows/tagUPM.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - 'main' 5 | - 'master' 6 | env: 7 | GITHUB_TOKEN: ${{ github.token }} 8 | permissions: write-all 9 | 10 | jobs: 11 | version_tag: 12 | runs-on: ubuntu-latest 13 | name: Version Tag UPM 14 | steps: 15 | - name: Check out files 16 | uses: actions/checkout@v3 17 | with: 18 | sparse-checkout: | 19 | README.md 20 | package.json 21 | 22 | - name: Get version 23 | id: version 24 | uses: williamrjackson/upm_version_increment_action@v1.0.1 25 | with: 26 | path: package.json 27 | increment: none 28 | - name: tag-exists-action 29 | id: check-tag 30 | uses: mukunku/tag-exists-action@v1.2.0 31 | with: 32 | tag: 'v${{steps.version.outputs.version}}' 33 | - name: Get result 34 | run: echo "Tag ${{steps.check-tag.outputs.exists}}" 35 | - name: gitconfig 36 | run: | 37 | git config user.name "GitHub Actions Bot" 38 | git config user.email "<>" 39 | - name: Set version 40 | if: ${{ steps.check-tag.outputs.exists }} 41 | id: increment 42 | uses: williamrjackson/upm_version_increment_action@v1.0.1 43 | with: 44 | path: package.json 45 | increment: patch 46 | - name: UpdateReadmeA 47 | if: ${{ steps.check-tag.outputs.exists }} 48 | uses: williamrjackson/upm_readme_tag_link_action@v1.0.1 49 | with: 50 | path: README.md 51 | major: ${{ steps.increment.outputs.major }} 52 | minor: ${{ steps.increment.outputs.minor }} 53 | patch: ${{ steps.increment.outputs.patch }} 54 | - name: UpdateReadmeB 55 | if: ${{ !steps.check-tag.outputs.exists }} 56 | uses: williamrjackson/upm_readme_tag_link_action@v1.0.1 57 | with: 58 | path: README.md 59 | major: ${{ steps.version.outputs.major }} 60 | minor: ${{ steps.version.outputs.minor }} 61 | patch: ${{ steps.version.outputs.patch }} 62 | - name: commit changes 63 | run: | 64 | git add . 65 | git commit -m "automated version tagging Readme Update [skip ci]" 66 | - name: push 67 | run: git push 68 | - name: tagA 69 | if: ${{ steps.check-tag.outputs.exists }} 70 | run: | 71 | git tag -f v${{ steps.increment.outputs.major }}.${{ steps.increment.outputs.minor }} 72 | git tag -f v${{ steps.increment.outputs.major }}.${{ steps.increment.outputs.minor }}.${{ steps.increment.outputs.patch }} 73 | - name: tagB 74 | if: ${{ !steps.check-tag.outputs.exists }} 75 | run: | 76 | git tag -f v${{ steps.version.outputs.major }}.${{ steps.version.outputs.minor }} 77 | git tag -f v${{ steps.version.outputs.major }}.${{ steps.version.outputs.minor }}.${{ steps.version.outputs.patch }} 78 | - name: push tags 79 | run: git push -f --tags 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio cache directory 9 | .vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.opendb 26 | *.DS_Store 27 | 28 | # Unity3D generated meta files 29 | *.pidb.meta 30 | *.pdb.meta 31 | 32 | # Unity3D Generated File On Crash Reports 33 | sysinfo.txt 34 | 35 | # Builds 36 | *.apk 37 | *.unitypackage 38 | -------------------------------------------------------------------------------- /ArduinoSerialCommunication.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_STANDALONE_WIN && NET_4_6 2 | using System.IO.Ports; 3 | #endif 4 | using UnityEngine; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System; 8 | using System.Threading; 9 | using System.Collections; 10 | namespace Wrj 11 | { 12 | public class ArduinoSerialCommunication : MonoBehaviour 13 | { 14 | #if UNITY_STANDALONE_WIN && NET_4_6 15 | [SerializeField] 16 | private BaudRates BaudRate = BaudRates._9600; 17 | [SerializeField] 18 | private string deviceName = "Arduino"; 19 | [SerializeField] 20 | [Range(-1, 256)] 21 | private int portNumber = -1; 22 | 23 | private string _rawData = string.Empty; 24 | private uint _dataIndex = 0; 25 | public string RawData { get { return _rawData; } } 26 | public uint DataIndex { get { return _dataIndex; } } 27 | public delegate void SerialEvent(string data); 28 | public SerialEvent OnSerialEvent; 29 | 30 | private Dictionary portAssignments = new Dictionary(); 31 | private string comPort; 32 | 33 | SerialPort port; 34 | Thread serialPortListenerThread; 35 | private readonly Queue _delegateQueue = new Queue(); 36 | 37 | public enum BaudRates 38 | { 39 | _300 = 300, _600 = 600, _1200 = 1200, _2400 = 2400, _4800 = 4800, _9600 = 9600, 40 | _14400 = 14400, _19200 = 19200, _28800 = 28800, _38400 = 38400, _57600 = 57600, _115200 = 115200 41 | } 42 | 43 | /// Static Singleton behavior 44 | protected static ArduinoSerialCommunication _instance; 45 | public static ArduinoSerialCommunication Instance 46 | { 47 | get 48 | { 49 | if (_instance == null) 50 | { 51 | UnityEngine.Debug.LogError("ArduinoSerialCommunication not instantiated!"); 52 | } 53 | return _instance; 54 | } 55 | } 56 | void Awake() 57 | { 58 | if (_instance == null) 59 | { 60 | _instance = this; 61 | } 62 | else 63 | { 64 | Destroy(this); 65 | } 66 | } 67 | void Start() 68 | { 69 | PopulatePortList(); 70 | if (portNumber >= 0 && PortExists(portNumber)) 71 | { 72 | comPort = portNumber.ToString(); 73 | Connect(); 74 | } 75 | else if ((comPort = GetFirstPortMatchingName(deviceName)) != null) 76 | { 77 | Connect(); 78 | } 79 | else 80 | { 81 | UnityEngine.Debug.LogWarning("Arduino Not Found"); 82 | } 83 | } 84 | 85 | private void OnDestroy() 86 | { 87 | if (serialPortListenerThread != null) 88 | { 89 | serialPortListenerThread.Abort(); 90 | ClosePort(); 91 | } 92 | } 93 | private void OnDisable() 94 | { 95 | if (serialPortListenerThread != null) 96 | { 97 | serialPortListenerThread.Abort(); 98 | ClosePort(); 99 | } 100 | } 101 | 102 | void Connect() 103 | { 104 | if (serialPortListenerThread != null) 105 | { 106 | serialPortListenerThread.Abort(); 107 | ClosePort(); 108 | } 109 | 110 | Utils.SafeTry(() => InitializeArduino(comPort, (int)BaudRate)); 111 | 112 | serialPortListenerThread = new Thread(RecieveDataInHelperThread); 113 | serialPortListenerThread.Start(); 114 | } 115 | 116 | public void ClosePort() 117 | { 118 | UnityEngine.Debug.Log("Close port"); 119 | Utils.SafeTry(() => port.Close()); 120 | } 121 | 122 | void InitializeArduino(string listeningPort, int baudRate) 123 | { 124 | UnityEngine.Debug.LogFormat("Connecting to Arduino on port {0} with a baudrate of: {1}.", listeningPort, baudRate); 125 | Utils.SafeTry(() => 126 | { 127 | port = new SerialPort(listeningPort, baudRate); 128 | port.Parity = Parity.None; 129 | port.StopBits = StopBits.One; 130 | port.DataBits = 8; 131 | port.Handshake = Handshake.None; 132 | port.Open(); 133 | }); 134 | } 135 | 136 | void RecieveDataInHelperThread() 137 | { 138 | while (port.IsOpen) 139 | { 140 | String str = port.ReadLine(); 141 | if (!string.IsNullOrWhiteSpace(str)) 142 | { 143 | _rawData = str; 144 | _dataIndex++; 145 | if (OnSerialEvent != null) 146 | { 147 | // Notify on main thread... 148 | Enqueue(ActionWrapper(() => OnSerialEvent(str))); 149 | } 150 | } 151 | } 152 | } 153 | 154 | // Send text to the serial port. 155 | public void SendData(string str) 156 | { 157 | Utils.SafeTry(() => 158 | { 159 | port.Write(str); 160 | }); 161 | } 162 | public void SendDataAsLine(string str) 163 | { 164 | Utils.SafeTry(() => 165 | { 166 | port.WriteLine(str); 167 | }); 168 | } 169 | 170 | void Update() 171 | { 172 | lock (_delegateQueue) 173 | { 174 | while (_delegateQueue.Count > 0) 175 | { 176 | _delegateQueue.Dequeue().Invoke(); 177 | } 178 | } 179 | } 180 | 181 | private void PopulatePortList() 182 | { 183 | // Remove existing port entries 184 | portAssignments.Clear(); 185 | // Run PowerShell process with Get-WMIObject Win32_SerialPort 186 | // Request DeviceID (port) and Description (device name) 187 | Process process = new Process(); 188 | process.StartInfo.UseShellExecute = false; 189 | process.StartInfo.RedirectStandardOutput = true; 190 | process.StartInfo.CreateNoWindow = true; 191 | process.StartInfo.FileName = "powershell.exe"; 192 | process.StartInfo.Arguments = "Get-WMIObject Win32_SerialPort | Select-Object DeviceID,Description"; 193 | process.Start(); 194 | // Read each line of the output 195 | string lineOut; 196 | while ((lineOut = process.StandardOutput.ReadLine()) != null) 197 | { 198 | // If it contains "COM" parse out the int for the port number 199 | // and save the remainder of the line as the description 200 | if (lineOut.Contains("COM")) 201 | { 202 | int firstSpacePos = lineOut.IndexOf(' '); 203 | string port = lineOut.Substring(0, firstSpacePos).Trim(); 204 | string desc = lineOut.Substring(firstSpacePos).Trim(); 205 | // Add to the port list 206 | portAssignments.Add(desc, port); 207 | } 208 | } 209 | } 210 | 211 | // Return the first port found with a name that matches a 212 | // specified substring. 213 | private string GetFirstPortMatchingName(string contains) 214 | { 215 | foreach (KeyValuePair entry in portAssignments) 216 | { 217 | if (entry.Key.Contains(contains)) 218 | { 219 | return entry.Value; 220 | } 221 | } 222 | return null; 223 | } 224 | private bool PortExists(int portNum) 225 | { 226 | return (portAssignments.ContainsValue(portNum.ToString())); 227 | } 228 | void Enqueue(IEnumerator action) 229 | { 230 | lock (_delegateQueue) 231 | { 232 | _delegateQueue.Enqueue(() => 233 | { 234 | StartCoroutine(action); 235 | }); 236 | } 237 | } 238 | IEnumerator ActionWrapper(Action action) 239 | { 240 | action(); 241 | yield return null; 242 | } 243 | #endif 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /ArduinoSerialCommunication.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9909864b3e4b1457c90a659c04091694 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Audio.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f76db7f9afdc4faa92b47b0a0c459c3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Audio/AudioPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEngine.Audio; 4 | 5 | namespace Wrj 6 | { 7 | /// 8 | /// Play audio clips without managing AudioSources and without the clicks and pops of interruptions. 9 | /// 10 | public class AudioPool : MonoBehaviour 11 | { 12 | public AudioMixerGroup audioMixerGroup; 13 | 14 | private int poolCount = 1; 15 | private List sources = new List(); 16 | 17 | void Start() 18 | { 19 | for (int i = 0; i < poolCount; i++) 20 | { 21 | CreatePoolAux(); 22 | } 23 | } 24 | 25 | // Play oneshot. 26 | public void PlayOneShot(AudioClip clip) 27 | { 28 | PlayPitchOneShot(clip, 1f); 29 | } 30 | 31 | // Play oneshot. Allows setting a pitch, as well as prevents interrupted playback. 32 | public void PlayPitchOneShot(AudioClip clip, float pitch, float volume = 1f) 33 | { 34 | // print("PitchOneShot at pitch: " + pitch); 35 | // Get next available audio source 36 | AudioSource source = FirstNotPlaying(); 37 | // Set it's pitch 38 | source.pitch = pitch; 39 | // Set it's volume 40 | source.volume = volume; 41 | // Play oneshot 42 | source.PlayOneShot(clip); 43 | } 44 | 45 | // This should allow for more "musical" pitch adjustments. Up/Down 1 octave. 46 | public void PlayPitchOneShot(AudioClip clip, int pitch, float volume = 1f) 47 | { 48 | float fAppliedPitchScale = 1; 49 | if (pitch > 0) 50 | { 51 | fAppliedPitchScale = Utils.Remap((float)pitch, 0, 12f, 1f, 2f); 52 | } 53 | else 54 | { 55 | fAppliedPitchScale = Utils.Remap((float)pitch, 0, -12f, 1f, .5f); 56 | } 57 | PlayPitchOneShot(clip, fAppliedPitchScale, volume); 58 | } 59 | 60 | private AudioSource FirstNotPlaying() 61 | { 62 | foreach (AudioSource source in sources) 63 | { 64 | if (!source.isPlaying) 65 | { 66 | return source; 67 | } 68 | } 69 | return CreatePoolAux(); 70 | } 71 | 72 | private AudioSource CreatePoolAux() 73 | { 74 | // Creat object 75 | GameObject newGO = new GameObject(); 76 | // Name it 77 | newGO.name = "AudioPoolObjectAux"; 78 | // Child it 79 | newGO.transform.parent = transform; 80 | // Add AudioSource 81 | AudioSource newSource = newGO.AddComponent(); 82 | // Set output 83 | newSource.outputAudioMixerGroup = audioMixerGroup; 84 | // Add to pool 85 | sources.Add(newSource); 86 | return newSource; 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Audio/AudioPool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa9ddf601c6ca4dac882222eca25dfcd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Audio/RandomizedSoundEffect.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Wrj 6 | { 7 | [RequireComponent(typeof(AudioPool))] 8 | public class RandomizedSoundEffect : MonoBehaviour 9 | { 10 | [SerializeField] 11 | private List audioClips = new List(); 12 | private AudioPool m_AudioPool; 13 | 14 | void Start() 15 | { 16 | m_AudioPool = gameObject.EnsureComponent(); 17 | } 18 | 19 | public void PlayRandom(float pitchMin = 1f, float pitchMax = 1f, float volumeMin = 1f, float volumeMax = 1f) 20 | { 21 | if (audioClips.Count == 0 || audioClips == null) 22 | return; 23 | m_AudioPool.PlayPitchOneShot(audioClips.GetRandom(), Random.Range(pitchMin, pitchMax), Random.Range(volumeMin, volumeMax)); 24 | } 25 | public void PlayRandom() 26 | { 27 | if (audioClips.Count == 0 || audioClips == null) 28 | return; 29 | m_AudioPool.PlayOneShot(audioClips.GetRandom()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Audio/RandomizedSoundEffect.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2853c87e381d4eaa9d6792c31a76985 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Audio/RhythmTracker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Events; 5 | 6 | public class RhythmTracker : MonoBehaviour { 7 | public static RhythmTracker instance; 8 | [SerializeField] 9 | [Tooltip("Desired tempo in bpm")] 10 | private float m_InitialTempo = 120; 11 | [SerializeField] 12 | [Tooltip("Sends notification of beats by this much time in advance.")] 13 | private float m_AdvancedNotificationOffset = 0; 14 | [SerializeField] 15 | [Tooltip("Start Playing right away. Not actually on Awake, but on the first frame.")] 16 | private bool m_PlayOnAwake = true; 17 | [SerializeField] 18 | [Tooltip("AudioSource for the music you're playing along to. Optional")] 19 | private AudioSource m_PlaybackAudioSource = null; 20 | [SerializeField] 21 | [Tooltip("Useful for lead-ins and intros")] 22 | private float m_PrerollTime = 0; 23 | private AudioSource m_LoopAudioSource; 24 | private AudioSource m_OffsetAudioSource; 25 | private int m_SubDivisions = 64; 26 | private List m_HitList; 27 | private int m_NextHitIndex = 0; 28 | private int m_NextAdvancedHitIndex = 0; 29 | private bool m_IsPaused; 30 | 31 | public enum TriggerTiming { Thirtyseconds, Sixteenths, Eighths, Quarters, Halves, Wholes }; 32 | 33 | public delegate void OnBeatDelegate(int beatIndex); 34 | public OnBeatDelegate On32nd; 35 | public OnBeatDelegate On16th; 36 | public OnBeatDelegate On8th; 37 | public OnBeatDelegate OnQuarter; 38 | public OnBeatDelegate OnHalf; 39 | public OnBeatDelegate OnWhole; 40 | 41 | public OnBeatDelegate OnAdvanced32nd; 42 | public OnBeatDelegate OnAdvanced16th; 43 | public OnBeatDelegate OnAdvanced8th; 44 | public OnBeatDelegate OnAdvancedQuarter; 45 | public OnBeatDelegate OnAdvancedHalf; 46 | public OnBeatDelegate OnAdvancedWhole; 47 | 48 | void Awake() 49 | { 50 | // Singleton behavior 51 | if (instance != null) 52 | { 53 | Destroy(this); 54 | } 55 | else 56 | { 57 | instance = this; 58 | DontDestroyOnLoad(this); 59 | } 60 | 61 | // Set the main audio loop 62 | m_LoopAudioSource = new GameObject().AddComponent(); 63 | m_LoopAudioSource.gameObject.name = "MainTracking"; 64 | m_LoopAudioSource.transform.parent = transform; 65 | m_LoopAudioSource.loop = true; 66 | m_LoopAudioSource.playOnAwake = false; 67 | m_LoopAudioSource.volume = 0; 68 | AudioClip silentClip = AudioClip.Create("100bpm-Silent", 423360, 1, 44100, false); 69 | m_LoopAudioSource.clip = silentClip; 70 | 71 | // If we're providing forewarnings on an offset, create a new child object with a 72 | // similarly set up audio source. This one will start right away, while the other will 73 | // start on after the offset time has passed. 74 | if (m_AdvancedNotificationOffset > 0) 75 | { 76 | m_OffsetAudioSource = new GameObject().AddComponent(); 77 | m_OffsetAudioSource.gameObject.name = "OffsetTracking"; 78 | m_OffsetAudioSource.transform.parent = transform; 79 | m_OffsetAudioSource.loop = true; 80 | m_OffsetAudioSource.playOnAwake = false; 81 | m_OffsetAudioSource.clip = m_LoopAudioSource.clip; 82 | m_OffsetAudioSource.volume = 0; 83 | } 84 | 85 | // Initialize list of target samples 86 | m_HitList = new List(); 87 | // Fill list with the the samples that represent target downbeats. 88 | for (int i = 0; i < m_SubDivisions; i++) 89 | { 90 | m_HitList.Add(m_LoopAudioSource.clip.samples / m_SubDivisions * i); 91 | } 92 | 93 | // Apply the tempo specified in the inspector. 94 | SetTempo(m_InitialTempo); 95 | 96 | // If PlayOnAwake is enabled, queue it up so Play() actually happens on the first frame. After everything's initialized and all subscriptions in 97 | // Start() and Awake() functions have been made. Otherwise, first beats will be intermittently skipped, depending on the order of initialization. 98 | if (m_PlayOnAwake) 99 | { 100 | StartCoroutine(PlayDelayedByFrame()); 101 | } 102 | 103 | } 104 | 105 | void Update () 106 | { 107 | CheckForHit(); 108 | CheckForAdvancedHit(); 109 | } 110 | 111 | private void CheckForHit() 112 | { 113 | if (m_LoopAudioSource.timeSamples > m_HitList[m_NextHitIndex]) 114 | { 115 | // Special check to not fire on the condition where the hit we're waiting for is at 0, but we're greater than 0 only because 116 | // we're at the end of the loop. 117 | if (m_NextHitIndex == 0 && m_LoopAudioSource.timeSamples > m_HitList[1]) 118 | return; 119 | // Call notifier 120 | Hit(m_NextHitIndex); 121 | // Increment hit index (looping back to 0 once out of range) 122 | m_NextHitIndex = (m_NextHitIndex + 1) % m_HitList.Count; 123 | } 124 | } 125 | private void CheckForAdvancedHit() 126 | { 127 | if (m_AdvancedNotificationOffset > 0 && m_OffsetAudioSource.timeSamples > m_HitList[m_NextAdvancedHitIndex]) 128 | { 129 | if (m_NextAdvancedHitIndex == 0 && m_OffsetAudioSource.timeSamples > m_HitList[1]) 130 | return; 131 | // Call notifier 132 | AdvancedHit(m_NextAdvancedHitIndex); 133 | // Increment hit index (looping back to 0 once out of range) 134 | m_NextAdvancedHitIndex = (m_NextAdvancedHitIndex + 1) % m_HitList.Count; 135 | } 136 | } 137 | 138 | // Alert subscribers that it's note time 139 | private void Hit(int index) 140 | { 141 | if (On32nd != null) 142 | On32nd(index); 143 | if (index % 2 == 0 && On16th != null) 144 | On16th(index); 145 | if (index % 4 == 0 && On8th != null) 146 | On8th(index); 147 | if (index % 8 == 0 && OnQuarter != null) 148 | OnQuarter(index); 149 | if (index % 16 == 0 && OnHalf != null) 150 | OnHalf(index); 151 | if (index % 32 == 0 && OnWhole != null) 152 | OnWhole(index); 153 | } 154 | private void AdvancedHit(int index) 155 | { 156 | if (OnAdvanced32nd != null) 157 | OnAdvanced32nd(index); 158 | if (index % 2 == 0 && OnAdvanced16th != null) 159 | OnAdvanced16th(index); 160 | if (index % 4 == 0 && OnAdvanced8th != null) 161 | OnAdvanced8th(index); 162 | if (index % 8 == 0 && OnAdvancedQuarter != null) 163 | OnAdvancedQuarter(index); 164 | if (index % 16 == 0 && OnAdvancedHalf != null) 165 | OnAdvancedHalf(index); 166 | if (index % 32 == 0 && OnAdvancedWhole != null) 167 | OnAdvancedWhole(index); 168 | } 169 | 170 | public float GetOffset() 171 | { 172 | return m_AdvancedNotificationOffset; 173 | } 174 | 175 | public float GetPreRoll() 176 | { 177 | return m_PrerollTime; 178 | } 179 | 180 | public void SetPreRoll(float preRoll) 181 | { 182 | m_PrerollTime = preRoll; 183 | } 184 | 185 | public AudioSource GetPlaybackAudioSource() 186 | { 187 | return m_PlaybackAudioSource; 188 | } 189 | 190 | // Set and get tempo 191 | public float GetTempo() 192 | { 193 | return m_LoopAudioSource.pitch * 100; 194 | } 195 | 196 | public void SetTempo(float tempo) 197 | { 198 | m_LoopAudioSource.pitch = tempo / 100; 199 | if (m_OffsetAudioSource != null) 200 | m_OffsetAudioSource.pitch = tempo / 100; 201 | if (m_PlaybackAudioSource != null && m_PlaybackAudioSource.isPlaying) 202 | Debug.LogWarning("Warning: Changing the tempo of the RhythmSystem does NOT change the tempo of the playback audio clip."); 203 | } 204 | 205 | // Composite transport controls 206 | public void Play() 207 | { 208 | if (!m_IsPaused) 209 | { 210 | StartCoroutine(PlayDelayedByFrame()); 211 | } 212 | else 213 | { 214 | UnPause(); 215 | } 216 | } 217 | public void Stop() 218 | { 219 | m_IsPaused = false; 220 | if (m_OffsetAudioSource != null) 221 | m_OffsetAudioSource.Stop(); 222 | if (m_PlaybackAudioSource != null) 223 | m_PlaybackAudioSource.Stop(); 224 | if (m_LoopAudioSource != null) 225 | m_LoopAudioSource.Stop(); 226 | } 227 | public void Pause() 228 | { 229 | StartCoroutine(PauseAsSoonAsPossible()); 230 | } 231 | public void UnPause() 232 | { 233 | if (!m_IsPaused) 234 | return; 235 | 236 | m_IsPaused = false; 237 | if (m_OffsetAudioSource != null) 238 | m_OffsetAudioSource.UnPause(); 239 | if (m_PlaybackAudioSource != null) 240 | m_PlaybackAudioSource.UnPause(); 241 | if (m_LoopAudioSource != null) 242 | m_LoopAudioSource.UnPause(); 243 | } 244 | 245 | public bool IsPaused() 246 | { 247 | return m_IsPaused; 248 | } 249 | 250 | // Wait til everything is fully initialized before playback begins... We don't want samples running before we have a chance to see them. 251 | private IEnumerator PlayDelayedByFrame() 252 | { 253 | yield return new WaitForEndOfFrame(); 254 | StartPlayback(); 255 | } 256 | 257 | private IEnumerator PauseAsSoonAsPossible() 258 | { 259 | m_IsPaused = true; 260 | if (m_AdvancedNotificationOffset > 0 && !m_LoopAudioSource.isPlaying) 261 | { 262 | // Wait until the advanced notification offset has elapsed. 263 | while (!m_LoopAudioSource.isPlaying) 264 | { 265 | // If playback is stopped (or something else happens to the state) while we're waiting, break. 266 | if (!m_IsPaused) 267 | yield break; 268 | yield return new WaitForEndOfFrame(); 269 | } 270 | } 271 | // Pause all relevant audio sources. 272 | if (m_OffsetAudioSource != null && m_OffsetAudioSource.isPlaying) 273 | m_OffsetAudioSource.Pause(); 274 | if (m_PlaybackAudioSource != null && m_PlaybackAudioSource.isPlaying) 275 | m_PlaybackAudioSource.Pause(); 276 | if (m_LoopAudioSource.isPlaying) 277 | m_LoopAudioSource.Pause(); 278 | } 279 | 280 | private void StartPlayback() 281 | { 282 | m_IsPaused = false; 283 | m_NextHitIndex = 0; 284 | m_NextAdvancedHitIndex = 0; 285 | 286 | // If an offset is desired, start the pre-roll audiosource's playback and delay main playback by that offset. 287 | if (m_OffsetAudioSource != null) 288 | { 289 | m_OffsetAudioSource.PlayDelayed(m_PrerollTime); 290 | } 291 | if (m_PlaybackAudioSource != null) 292 | { 293 | m_PlaybackAudioSource.PlayDelayed(m_AdvancedNotificationOffset); 294 | } 295 | // Play main loop audiosource 296 | m_LoopAudioSource.PlayDelayed(m_AdvancedNotificationOffset + m_PrerollTime); 297 | } 298 | 299 | 300 | // Public Subscription methods for convenience 301 | public void Subscribe(OnBeatDelegate subscriber, TriggerTiming triggerTiming, bool advanced = false) 302 | { 303 | if (advanced) 304 | { 305 | switch (triggerTiming) 306 | { 307 | case TriggerTiming.Thirtyseconds: 308 | { 309 | OnAdvanced32nd += subscriber; 310 | return; 311 | } 312 | case TriggerTiming.Sixteenths: 313 | { 314 | OnAdvanced16th += subscriber; 315 | return; 316 | } 317 | case TriggerTiming.Eighths: 318 | { 319 | OnAdvanced8th += subscriber; 320 | return; 321 | } 322 | case TriggerTiming.Quarters: 323 | { 324 | OnAdvancedQuarter += subscriber; 325 | return; 326 | } 327 | case TriggerTiming.Halves: 328 | { 329 | OnAdvancedHalf += subscriber; 330 | return; 331 | } 332 | case TriggerTiming.Wholes: 333 | { 334 | OnAdvancedWhole += subscriber; 335 | return; 336 | } 337 | } 338 | } 339 | else 340 | { 341 | switch (triggerTiming) 342 | { 343 | case TriggerTiming.Thirtyseconds: 344 | { 345 | On32nd += subscriber; 346 | return; 347 | } 348 | case TriggerTiming.Sixteenths: 349 | { 350 | On16th += subscriber; 351 | return; 352 | } 353 | case TriggerTiming.Eighths: 354 | { 355 | On8th += subscriber; 356 | return; 357 | } 358 | case TriggerTiming.Quarters: 359 | { 360 | OnQuarter += subscriber; 361 | return; 362 | } 363 | case TriggerTiming.Halves: 364 | { 365 | OnHalf += subscriber; 366 | return; 367 | } 368 | case TriggerTiming.Wholes: 369 | { 370 | OnWhole += subscriber; 371 | return; 372 | } 373 | } 374 | } 375 | } 376 | public void Unsubscribe(OnBeatDelegate subscriber, TriggerTiming triggerTiming, bool advanced = false) 377 | { 378 | if (advanced) 379 | { 380 | switch (triggerTiming) 381 | { 382 | case TriggerTiming.Thirtyseconds: 383 | { 384 | OnAdvanced32nd -= subscriber; 385 | return; 386 | } 387 | case TriggerTiming.Sixteenths: 388 | { 389 | OnAdvanced16th -= subscriber; 390 | return; 391 | } 392 | case TriggerTiming.Eighths: 393 | { 394 | OnAdvanced8th -= subscriber; 395 | return; 396 | } 397 | case TriggerTiming.Quarters: 398 | { 399 | OnAdvancedQuarter -= subscriber; 400 | return; 401 | } 402 | case TriggerTiming.Halves: 403 | { 404 | OnAdvancedHalf -= subscriber; 405 | return; 406 | } 407 | case TriggerTiming.Wholes: 408 | { 409 | OnAdvancedWhole -= subscriber; 410 | return; 411 | } 412 | } 413 | } 414 | else 415 | { 416 | switch (triggerTiming) 417 | { 418 | case TriggerTiming.Thirtyseconds: 419 | { 420 | On32nd -= subscriber; 421 | return; 422 | } 423 | case TriggerTiming.Sixteenths: 424 | { 425 | On16th -= subscriber; 426 | return; 427 | } 428 | case TriggerTiming.Eighths: 429 | { 430 | On8th -= subscriber; 431 | return; 432 | } 433 | case TriggerTiming.Quarters: 434 | { 435 | OnQuarter -= subscriber; 436 | return; 437 | } 438 | case TriggerTiming.Halves: 439 | { 440 | OnHalf -= subscriber; 441 | return; 442 | } 443 | case TriggerTiming.Wholes: 444 | { 445 | OnWhole -= subscriber; 446 | return; 447 | } 448 | } 449 | } 450 | } 451 | // Unsubscribes method from unknown. 452 | public void Unsubscribe(OnBeatDelegate subscriber) 453 | { 454 | OnAdvanced32nd -= subscriber; 455 | OnAdvanced16th -= subscriber; 456 | OnAdvanced8th -= subscriber; 457 | OnAdvancedQuarter -= subscriber; 458 | OnAdvancedHalf -= subscriber; 459 | OnAdvancedWhole -= subscriber; 460 | On32nd -= subscriber; 461 | On16th -= subscriber; 462 | On8th -= subscriber; 463 | OnQuarter -= subscriber; 464 | OnHalf -= subscriber; 465 | OnWhole -= subscriber; 466 | } 467 | } 468 | -------------------------------------------------------------------------------- /Audio/RhythmTracker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e087341cf158e430daf97d9edf2c3ad8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /ColorPalettes.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e56d39b503674e6ba5e8ca03a8f698b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 818e58854bcc147118e2083f389c318c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/BezierPathEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System; 6 | 7 | namespace Wrj 8 | { 9 | [CustomEditor(typeof(BezierPath))] 10 | [InitializeOnLoad] 11 | public class BezierPathEditor : Editor 12 | { 13 | BezierPath connectedObject; 14 | 15 | static BezierPathEditor() 16 | { 17 | Undo.undoRedoPerformed += UndoRedoPerformed; 18 | } 19 | 20 | private static void UndoRedoPerformed() 21 | { 22 | foreach ( BezierPath path in FindObjectsByType(typeof(BezierPath), FindObjectsSortMode.None)) 23 | { 24 | path.RefreshChildIndices(); 25 | } 26 | } 27 | 28 | void OnEnable() 29 | { 30 | connectedObject = target as BezierPath; 31 | if (connectedObject == null) 32 | return; 33 | 34 | if (connectedObject.gameObject.GetComponentsInChildren().Length == 0) 35 | { 36 | GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); 37 | go.transform.localScale = Vector3.one * .1f; 38 | go.transform.position = connectedObject.transform.position; 39 | go.transform.parent = connectedObject.transform; 40 | Wrj.Utils.EnsureComponent(go); 41 | go.name = "Node_0"; 42 | go = Instantiate(go); 43 | go.transform.position = connectedObject.transform.position + Vector3.right; 44 | go.transform.parent = connectedObject.transform; 45 | go.name = "Node_1"; 46 | go = Instantiate(go); 47 | go.transform.position = connectedObject.transform.position + Vector3.right + Vector3.down; 48 | go.transform.parent = connectedObject.transform; 49 | go.name = "Node_2"; 50 | } 51 | SceneView.duringSceneGui += CurveEditor; 52 | } 53 | void CurveEditor(SceneView scene) 54 | { 55 | if (connectedObject == null) 56 | return; 57 | 58 | PathGuide[] points = connectedObject.gameObject.GetComponentsInChildren(); 59 | Vector3[] curve = connectedObject.CurvePath(connectedObject.res); 60 | if (curve != null) 61 | { 62 | 63 | Handles.color = Color.green; 64 | Handles.DrawAAPolyLine(2f, curve); 65 | 66 | Vector3[] pointsPos = new Vector3[points.Length]; 67 | Handles.color = Color.yellow; 68 | for (int i = 0; i < points.Length; i++) 69 | { 70 | pointsPos[i] = points[i].transform.position; 71 | Handles.CubeHandleCap(i, points[i].transform.position, Quaternion.identity, .1f, EventType.Repaint); 72 | } 73 | Handles.color = Color.white; 74 | Handles.DrawAAPolyLine(1f, pointsPos); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Editor/BezierPathEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e91394803d645477dac55b355fa1d3b1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ExtendedGradientDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace Wrj 5 | { 6 | [CustomPropertyDrawer(typeof(ExtendedGradient))] 7 | public class ExtendedGradientDrawer : PropertyDrawer 8 | { 9 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 10 | { 11 | ExtendedGradient gradient = fieldInfo.GetValue(property.serializedObject.targetObject) as ExtendedGradient; 12 | if (gradient == null) 13 | { 14 | return; 15 | } 16 | 17 | Event guiEvent = Event.current; 18 | position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); 19 | EditorGUI.BeginProperty(position, label, property); 20 | Rect textureRect = new Rect(position.x, position.y, position.width, position.height); 21 | 22 | if (guiEvent.type == EventType.Repaint) 23 | { 24 | Texture2D texture = gradient.CreateTexture(Mathf.RoundToInt(textureRect.width)); 25 | EditorGUI.DrawPreviewTexture(textureRect, texture); 26 | } 27 | EditorGUI.EndProperty(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Editor/ExtendedGradientDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba955d6bacc424ca587704e1ee2b5e92 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/HideFlagsUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections.Generic; 4 | 5 | public static class HideFlagsUtility 6 | { 7 | [MenuItem("Edit/Hide Flags/Show All In Hierarchy")] 8 | private static void ShowAll() 9 | { 10 | var allGameObjects = Editor.FindObjectsByType(typeof(GameObject), FindObjectsSortMode.None); 11 | List newSelection = new List(); 12 | int shown = 0; 13 | foreach (var go in allGameObjects) 14 | { 15 | if (go.hideFlags.HasFlag(HideFlags.HideInHierarchy)) 16 | { 17 | go.hideFlags &= ~HideFlags.HideInHierarchy; 18 | newSelection.Add(go); 19 | shown++; 20 | } 21 | } 22 | if (shown == 0) 23 | { 24 | Debug.Log("No hidden objects found in hierarchy."); 25 | return; 26 | } 27 | Selection.objects = newSelection.ToArray(); 28 | } 29 | 30 | [MenuItem("Edit/Hide Flags/Hide Selected Objects")] 31 | private static void HideSelected() 32 | { 33 | foreach (var go in Selection.gameObjects) 34 | { 35 | go.hideFlags |= HideFlags.HideInHierarchy; 36 | } 37 | } 38 | 39 | [MenuItem("Edit/Hide Flags/Log Hidden Objects")] 40 | private static void LogHidden() 41 | { 42 | var allGameObjects = Editor.FindObjectsByType(typeof(GameObject), FindObjectsSortMode.None); 43 | int hiddenFound = 0; 44 | 45 | foreach (var go in allGameObjects) 46 | { 47 | if (go.hideFlags.HasFlag(HideFlags.HideInHierarchy)) 48 | { 49 | Debug.Log($"Hidden Object {++hiddenFound}: {go.name}"); 50 | } 51 | } 52 | if (hiddenFound == 0) 53 | { 54 | Debug.Log("No hidden objects found in hierarchy."); 55 | return; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Editor/HideFlagsUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1075c0b11c0b9b149b05b0e8d2b0318b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ImageSequenceRecorder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using UnityEngine; 5 | #if UNITY_EDITOR && RECORDER_AVAILABLE 6 | using UnityEditor.Recorder; 7 | using UnityEditor.Recorder.Input; 8 | #endif 9 | 10 | namespace Wrj 11 | { 12 | public class ImageSequenceRecorder 13 | { 14 | #if UNITY_EDITOR && RECORDER_AVAILABLE 15 | static RecorderController m_RecorderController; 16 | static RecorderController recorderController 17 | { 18 | get 19 | { 20 | if (m_RecorderController == null) 21 | { 22 | var controllerSettings = ScriptableObject.CreateInstance(); 23 | m_RecorderController = new RecorderController(controllerSettings); 24 | } 25 | return m_RecorderController; 26 | } 27 | } 28 | #endif 29 | static public void StartRecording(string recordingName, int framerate = 30) 30 | { 31 | #if UNITY_EDITOR && RECORDER_AVAILABLE 32 | if (m_RecorderController != null && m_RecorderController.IsRecording()) 33 | { 34 | Debug.Log($"Stopping {m_RecorderController.Settings.name}."); 35 | StopRecording(); 36 | } 37 | 38 | var mediaOutputFolder = Path.Combine(Application.dataPath, "..", "Recordings"); 39 | mediaOutputFolder = Path.GetFullPath(Path.Combine(mediaOutputFolder, recordingName)); 40 | // Image Sequence 41 | var imageRecorder = ScriptableObject.CreateInstance(); 42 | imageRecorder.name = recordingName; 43 | imageRecorder.Enabled = true; 44 | 45 | imageRecorder.OutputFormat = ImageRecorderSettings.ImageRecorderOutputFormat.PNG; 46 | imageRecorder.CaptureAlpha = false; 47 | imageRecorder.FrameRate = framerate; 48 | imageRecorder.FrameRatePlayback = FrameRatePlayback.Constant; 49 | imageRecorder.CapFrameRate = true; 50 | 51 | imageRecorder.OutputFile = Path.Combine(mediaOutputFolder, recordingName) + "_" + DefaultWildcard.Frame; 52 | 53 | imageRecorder.imageInputSettings = new GameViewInputSettings 54 | { 55 | OutputWidth = Screen.width, 56 | OutputHeight = Screen.height 57 | }; 58 | 59 | // Setup Recording 60 | recorderController.Settings.name = recordingName; 61 | recorderController.Settings.FrameRate = framerate; 62 | recorderController.Settings.FrameRatePlayback = FrameRatePlayback.Constant; 63 | recorderController.Settings.CapFrameRate = true; 64 | recorderController.Settings.AddRecorderSettings(imageRecorder); 65 | recorderController.Settings.SetRecordModeToManual(); 66 | RecorderOptions.VerboseMode = false; 67 | 68 | Debug.Log($"Starting Recording: {mediaOutputFolder}"); 69 | 70 | try 71 | { 72 | recorderController.PrepareRecording(); 73 | recorderController.StartRecording(); 74 | } 75 | catch (System.Exception e) 76 | { 77 | Debug.LogError(e); 78 | } 79 | #else 80 | Debug.LogError("Recorder package not found. Install it via Package Manager."); 81 | #endif 82 | } 83 | 84 | static public void StopRecording() 85 | { 86 | #if UNITY_EDITOR && RECORDER_AVAILABLE 87 | if (m_RecorderController != null && m_RecorderController.IsRecording()) 88 | { 89 | m_RecorderController.StopRecording(); 90 | m_RecorderController = null; 91 | } 92 | #endif 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Editor/ImageSequenceRecorder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ddd7b07dd493ed4fb1d8fe18820a2b0 -------------------------------------------------------------------------------- /Editor/MapToCurveInspectorGUI.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace Wrj 5 | { 6 | [CustomPropertyDrawer(typeof(Utils.MapToCurve))] 7 | public class MapToCurveInspectorGUI : PropertyDrawer 8 | { 9 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 10 | { 11 | return base.GetPropertyHeight(property, label) + 35; 12 | } 13 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 14 | { 15 | // Using BeginProperty / EndProperty on the parent property means that 16 | // prefab override logic works on the entire property. 17 | EditorGUI.BeginProperty(position, label, property); 18 | 19 | // Draw label 20 | position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); 21 | 22 | // Don't make child fields be indented 23 | var indent = EditorGUI.indentLevel; 24 | EditorGUI.indentLevel = 0; 25 | 26 | var bMinMax = property.FindPropertyRelative("_isMinMaxCurveMode"); 27 | // Calculate rects 28 | var toggleLabel = new GUIContent("Use Min/Max"); 29 | var toggleRect = new Rect(position.x, position.y, position.width, 20); 30 | var curveRect = new Rect(position.x, position.y + 25, position.width, 30); 31 | 32 | // Draw fields 33 | EditorGUI.PropertyField(toggleRect, bMinMax, toggleLabel); 34 | if (bMinMax.boolValue) 35 | { 36 | var minMaxCurve = property.FindPropertyRelative("_minMaxCurve"); 37 | EditorGUI.PropertyField(curveRect, minMaxCurve, GUIContent.none); 38 | var mode = minMaxCurve.FindPropertyRelative("m_Mode"); 39 | var curveMin = minMaxCurve.FindPropertyRelative("m_CurveMin"); 40 | var curveMax = minMaxCurve.FindPropertyRelative("m_CurveMax"); 41 | mode.enumValueIndex = 2; 42 | if (curveMin.animationCurveValue.keys.Length == 0) 43 | { 44 | curveMax.animationCurveValue = Utils.MapToCurve.EaseInCurve; 45 | curveMin.animationCurveValue = Utils.MapToCurve.EaseOutCurve; 46 | } 47 | } 48 | else 49 | { 50 | EditorGUI.PropertyField(curveRect, property.FindPropertyRelative("_curve"), GUIContent.none); 51 | } 52 | EditorGUI.indentLevel = indent; 53 | 54 | EditorGUI.EndProperty(); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /Editor/MapToCurveInspectorGUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d90e8b976b8f44ead89d1034ad14d21b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiRename.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | public class MultiRename : ScriptableWizard 5 | { 6 | public string oldToken; 7 | public string newToken; 8 | 9 | [MenuItem("Edit/Multi Rename")] 10 | [MenuItem("GameObject/Multi Rename", false, 0)] 11 | public static void CreateWindow() 12 | { 13 | FocusWindowIfItsOpen(typeof(MultiRename)); 14 | if (focusedWindow is not MultiRename) 15 | { 16 | var wizard = DisplayWizard("Multi Rename", typeof(MultiRename), "Okay", "Apply"); 17 | wizard.minSize = new Vector2(300f, 150f); 18 | } 19 | } 20 | 21 | [MenuItem("Edit/Multi Rename", true)] 22 | [MenuItem("GameObject/Multi Rename", true)] 23 | private static bool MultiSelectValidate() => Selection.gameObjects.Length > 1; 24 | 25 | private void OnWizardCreate() 26 | { 27 | Rename(); 28 | Close(); 29 | } 30 | private void OnWizardOtherButton() 31 | { 32 | Rename(); 33 | } 34 | private void Rename() 35 | { 36 | foreach (var selectedObject in Selection.gameObjects) 37 | { 38 | string objName = selectedObject.name; 39 | if (objName.Contains(oldToken)) 40 | { 41 | Undo.RecordObject(selectedObject, "Multi Rename"); 42 | selectedObject.name = objName.Replace(oldToken, newToken); 43 | } 44 | } 45 | } 46 | 47 | bool _hasPrePopulated = false; 48 | bool _hasChangeListener = false; 49 | void OnWizardUpdate() 50 | { 51 | // Only try to do this once or if selection has changed 52 | if (!_hasPrePopulated) 53 | { 54 | _hasPrePopulated = true; 55 | PrePopulateOld(); 56 | } 57 | if (!_hasChangeListener) 58 | { 59 | Selection.selectionChanged += () => 60 | { 61 | _hasChangeListener = true; 62 | PrePopulateOld(); 63 | }; 64 | } 65 | if (string.IsNullOrEmpty(oldToken)) isValid = false; 66 | else isValid = true; 67 | } 68 | 69 | void PrePopulateOld() 70 | { 71 | if (Selection.gameObjects.Length < 2) return; 72 | 73 | string subStr = Selection.gameObjects[0].name; 74 | 75 | for (int i = 1; i < Selection.gameObjects.Length; i++) 76 | { 77 | subStr = CommonSubstring(subStr, Selection.gameObjects[i].name); 78 | } 79 | if (!string.IsNullOrEmpty(subStr)) 80 | { 81 | oldToken = subStr; 82 | Repaint(); 83 | } 84 | } 85 | 86 | // Stolen from https://www.geeksforgeeks.org/print-longest-common-substring/ 87 | string CommonSubstring(string X, string Y) 88 | { 89 | // Create a table to store lengths of longest common 90 | // suffixes of substrings. Note that LCSuff[i][j] 91 | // contains length of longest common suffix of X[0..i-1] 92 | // and Y[0..j-1]. The first row and first column entries 93 | // have no logical meaning, they are used only for 94 | // simplicity of program 95 | int m = X.Length; 96 | int n = Y.Length; 97 | int[, ] LCSuff = new int[m + 1, n + 1]; 98 | 99 | // To store length of the longest common substring 100 | int len = 0; 101 | 102 | // To store the index of the cell which contains the 103 | // maximum value. This cell's index helps in building 104 | // up the longest common substring from right to left. 105 | int row = 0, col = 0; 106 | 107 | /* Following steps build LCSuff[m+1][n+1] in bottom 108 | up fashion. */ 109 | for (int i = 0; i <= m; i++) { 110 | for (int j = 0; j <= n; j++) { 111 | if (i == 0 || j == 0) 112 | LCSuff[i, j] = 0; 113 | 114 | else if (X[i - 1] == Y[j - 1]) { 115 | LCSuff[i, j] = LCSuff[i - 1, j - 1] + 1; 116 | if (len < LCSuff[i, j]) { 117 | len = LCSuff[i, j]; 118 | row = i; 119 | col = j; 120 | } 121 | } 122 | else 123 | LCSuff[i, j] = 0; 124 | } 125 | } 126 | 127 | // if true, then no common substring exists 128 | if (len == 0) { 129 | return string.Empty; 130 | } 131 | 132 | // allocate space for the longest common substring 133 | string resultStr = string.Empty; 134 | 135 | // traverse up diagonally form the (row, col) cell 136 | // until LCSuff[row][col] != 0 137 | while (LCSuff[row, col] != 0) { 138 | resultStr = X[row - 1] + resultStr; // or Y[col-1] 139 | --len; 140 | 141 | // move diagonally up to previous cell 142 | row--; 143 | col--; 144 | } 145 | 146 | // longest common substring. 147 | // Fail on 1 or 2 character substrings. 148 | return (resultStr.Length > 2) ? resultStr : string.Empty; 149 | } 150 | } -------------------------------------------------------------------------------- /Editor/MultiRename.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d99cc93695216d40b0da31d2ee18949 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/NumberingUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Text.RegularExpressions; 4 | using System.Linq; 5 | 6 | public static class NumberingUtility 7 | { 8 | [MenuItem("Edit/Renumber")] 9 | [MenuItem("GameObject/Renumber", false, 0)] 10 | private static void Renumber() 11 | { 12 | var selection = Selection.objects.OfType().ToArray(); 13 | for (int i = 0; i < selection.Length; i++) 14 | { 15 | GameObject go = selection[i]; 16 | string output = Regex.Replace(go.name, @"[_([.\s]*?\d+[)\]\s]*[^\S]*", string.Empty); 17 | 18 | string format = new string('0', EditorSettings.gameObjectNamingDigits); 19 | string digit = i.ToString(format); 20 | switch (EditorSettings.gameObjectNamingScheme) 21 | { 22 | case EditorSettings.NamingScheme.Dot: 23 | go.name = $"{output}.{digit}"; 24 | break; 25 | case EditorSettings.NamingScheme.Underscore: 26 | go.name = $"{output}_{digit}"; 27 | break; 28 | default: // spaceParenthesis 29 | go.name = $"{output} ({digit})"; 30 | break; 31 | } 32 | } 33 | } 34 | [MenuItem("Edit/Renumber", true)] 35 | [MenuItem("GameObject/Renumber", true)] 36 | private static bool MultiSelectValidate() => Selection.gameObjects.Length > 1; 37 | } -------------------------------------------------------------------------------- /Editor/NumberingUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e29027738ac1194ebb544432b352423 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/PaletteGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6dc7afd6f3afc42fd9a7f026692f9ca0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/PathGuideEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System; 6 | 7 | namespace Wrj 8 | { 9 | #if UNITY_EDITOR 10 | [CustomEditor(typeof(PathGuide))] 11 | public class PathGuideEditor : Editor { 12 | public override void OnInspectorGUI() 13 | { 14 | PathGuide connectedObjects = target as PathGuide; 15 | if (connectedObjects == null) 16 | return; 17 | if (GUILayout.Button("Duplicate Node (D)", GUILayout.Width(255))) 18 | { 19 | connectedObjects.Duplicate(connectedObjects); 20 | } 21 | } 22 | void OnSceneGUI() 23 | { 24 | Event e = Event.current; 25 | if (e.type == EventType.KeyDown && e.keyCode == KeyCode.D) 26 | { 27 | PathGuide connectedObjects = target as PathGuide; 28 | if (connectedObjects == null) 29 | return; 30 | 31 | connectedObjects.Duplicate(connectedObjects); 32 | Debug.Log("Dupe"); 33 | } 34 | } 35 | } 36 | #endif 37 | } -------------------------------------------------------------------------------- /Editor/PathGuideEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e427b8aef152a4fb39a11ea3005c7035 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 946b302eeb9b14c52b3da97750e48262 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/NewScriptHandler.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.IO; 4 | 5 | namespace Wrj 6 | { 7 | public class NewScriptHandler : AssetPostprocessor 8 | { 9 | [UnityEditor.Callbacks.DidReloadScripts] 10 | private static void OnScriptsReloaded() 11 | { 12 | var settings = WrjSettings.GetSerializedSettings(); 13 | //Debug.Log($"Settings: {settings.ToString()}"); 14 | SerializedProperty customPathProp = settings.FindProperty("_customScriptPath"); 15 | string customPath = customPathProp.stringValue; 16 | //Debug.Log($"Custom Script Path: {customPath}"); 17 | if (string.IsNullOrWhiteSpace(customPath)) return; 18 | 19 | // Check for the saved path string 20 | string asset = EditorPrefs.GetString("temp_scriptPath"); 21 | if (!string.IsNullOrEmpty(asset)) 22 | { 23 | // If it's found, delete it and move the asset 24 | EditorPrefs.DeleteKey("temp_scriptPath"); 25 | MoveAsset(asset, customPath); 26 | } 27 | } 28 | 29 | void OnPreprocessAsset() 30 | { 31 | //Debug.Log($"New Script: {assetImporter.assetPath}"); 32 | // Bail if it's not in the Assets root dir. 33 | if (assetImporter.assetPath.Split('/').Length > 2) 34 | return; 35 | if (Path.GetExtension(assetImporter.assetPath).ToLower() == ".cs") 36 | { 37 | //Debug.Log("Saving"); 38 | EditorPrefs.SetString("temp_scriptPath", assetImporter.assetPath); 39 | } 40 | } 41 | 42 | static void MoveAsset(string assetPath, string subDir) 43 | { 44 | string filename = Path.GetFileName(assetPath); 45 | string filePath = Path.Combine("Assets", subDir, filename).ToString(); 46 | //Debug.Log($"New path: {filePath}"); 47 | // Create the folder if necessary 48 | (new FileInfo(filePath)).Directory.Create(); 49 | 50 | // Move the asset. 51 | string error = AssetDatabase.MoveAsset(assetPath, filePath); 52 | if (!string.IsNullOrEmpty(error)) Debug.Log(error); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/NewScriptHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9907f9ab302034d4087aa7c41081c9c4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/WrjSettings.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | using System.IO; 4 | 5 | namespace Wrj 6 | { 7 | public class WrjSettings : ScriptableObject 8 | { 9 | [SerializeField] 10 | string _customScriptPath = string.Empty; 11 | 12 | internal static WrjSettings GetOrCreateSettings() 13 | { 14 | var settings = AssetDatabase.LoadAssetAtPath(WrjSettingsProvider.k_WrjSettingsPath); 15 | if (settings == null) 16 | { 17 | (new FileInfo(WrjSettingsProvider.k_WrjSettingsPath)).Directory.Create(); 18 | settings = ScriptableObject.CreateInstance(); 19 | settings._customScriptPath = ""; 20 | AssetDatabase.CreateAsset(settings, WrjSettingsProvider.k_WrjSettingsPath); 21 | AssetDatabase.SaveAssets(); 22 | } 23 | return settings; 24 | } 25 | 26 | internal static SerializedObject GetSerializedSettings() 27 | { 28 | return new SerializedObject(GetOrCreateSettings()); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/WrjSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72547a5f2822a47ecb94fad8158ff345 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/WrjSettingsRegister.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEditor; 4 | using UnityEngine.UIElements; 5 | using UnityEngine; 6 | using System.IO; 7 | 8 | namespace Wrj 9 | { 10 | class WrjSettingsProvider : SettingsProvider 11 | { 12 | public const string k_WrjSettingsPath = "Assets/Editor/Script Creation/Wrj.Settings.asset"; 13 | private SerializedObject m_WrjSettings; 14 | 15 | public static GUIContent CustomScriptPath = new GUIContent("Custom Script Path"); 16 | 17 | public WrjSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) 18 | : base(path, scope) { } 19 | 20 | 21 | public static bool IsSettingsAvailable() 22 | { 23 | return File.Exists(k_WrjSettingsPath); 24 | } 25 | 26 | public override void OnActivate(string searchContext, VisualElement rootElement) 27 | { 28 | m_WrjSettings = WrjSettings.GetSerializedSettings(); 29 | } 30 | 31 | public override void OnGUI(string searchContext) 32 | { 33 | m_WrjSettings.Update(); 34 | EditorGUILayout.HelpBox("New scripts created in the root assets folder will be automatically moved to the path specified here.", MessageType.None); 35 | EditorGUILayout.PropertyField(m_WrjSettings.FindProperty("_customScriptPath"), CustomScriptPath); 36 | m_WrjSettings.ApplyModifiedProperties(); 37 | } 38 | 39 | [SettingsProvider] 40 | public static SettingsProvider CreateWrjSettingsProvider() 41 | { 42 | if (IsSettingsAvailable()) 43 | { 44 | var provider = new WrjSettingsProvider("Project/Custom Script Utils Settings", SettingsScope.Project); 45 | provider.keywords = new HashSet(new[] { "Custom scripts path" }); 46 | return provider; 47 | } 48 | return null; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Editor/ScriptCreationUtils/WrjSettingsRegister.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15cf57ed5be59492baf61ce767d06fea 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/wrj.utils.editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wrj.utils.editor", 3 | "rootNamespace": "Wrj", 4 | "references": [ 5 | "wrj.utils", 6 | "Unity.Recorder.Editor" 7 | ], 8 | "includePlatforms": [ 9 | "Editor" 10 | ], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [ 18 | { 19 | "name": "com.unity.recorder", 20 | "expression": "", 21 | "define": "RECORDER_AVAILABLE" 22 | } 23 | ], 24 | "noEngineReferences": false 25 | } -------------------------------------------------------------------------------- /Editor/wrj.utils.editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f493a32aeed934012a6554a41a668db8 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /ExtensionMethods.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e39a0d8216f264a7684a029365a83d04 3 | timeCreated: 1546575837 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Keybindings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Events; 5 | 6 | namespace Wrj 7 | { 8 | public class Keybindings : MonoBehaviour 9 | { 10 | [SerializeField] 11 | private bool quitOnEsc = true; 12 | [SerializeField] 13 | private bool fullScreenOnF11 = true; 14 | [SerializeField] 15 | private ButtonKeyCommand[] buttonKeys; 16 | [SerializeField] 17 | private ToggleKeyCommand[] toggleKeys; 18 | [SerializeField] 19 | private ActionKeyCommand[] actionKeys; 20 | [SerializeField] 21 | private HierarchyToggles[] objectEnableKeys; 22 | 23 | public bool logKeys = false; 24 | 25 | private List _keyCommands; 26 | private List _keyUps; 27 | 28 | public void Add(KeyCommand keyCommand) 29 | { 30 | if (keyCommand is ActionKeyCommand && ((ActionKeyCommand)keyCommand).onKeyUp) 31 | { 32 | _keyUps.Add((ActionKeyCommand)keyCommand); 33 | } 34 | else 35 | { 36 | _keyCommands.Add(keyCommand); 37 | } 38 | Prioritize(); 39 | } 40 | 41 | private void Awake() 42 | { 43 | _keyCommands = new List(); 44 | _keyUps = new List(); 45 | foreach (var item in buttonKeys) 46 | { 47 | _keyCommands.Add(item); 48 | } 49 | foreach (var item in toggleKeys) 50 | { 51 | _keyCommands.Add(item); 52 | } 53 | foreach (var item in actionKeys) 54 | { 55 | if (item.onKeyUp) 56 | { 57 | _keyUps.Add(item); 58 | } 59 | else 60 | { 61 | _keyCommands.Add(item); 62 | } 63 | } 64 | foreach (var item in objectEnableKeys) 65 | { 66 | _keyCommands.Add(item); 67 | } 68 | Prioritize(); 69 | } 70 | 71 | private void Prioritize() 72 | { 73 | _keyCommands.Sort(); 74 | _keyUps.Sort(); 75 | } 76 | 77 | void Update() 78 | { 79 | KeyCommand.NewFrame(); 80 | 81 | foreach (ActionKeyCommand keyUp in _keyUps) 82 | { 83 | if (Input.GetKeyUp(keyUp.key)) 84 | { 85 | if (!keyUp.ModifierQualified()) continue; 86 | if (logKeys) 87 | { 88 | Debug.Log(keyUp.ToString()); 89 | } 90 | keyUp.Invoke(); 91 | } 92 | } 93 | 94 | if (!Input.anyKeyDown) return; 95 | 96 | if (quitOnEsc && Input.GetKeyDown(KeyCode.Escape)) 97 | { 98 | #if UNITY_EDITOR 99 | UnityEditor.EditorApplication.isPlaying = false; 100 | #endif 101 | Application.Quit(); 102 | } 103 | 104 | if (fullScreenOnF11 && Input.GetKeyDown(KeyCode.F11)) 105 | { 106 | Screen.fullScreen = !Screen.fullScreen; 107 | } 108 | 109 | foreach (KeyCommand keyCommand in _keyCommands) 110 | { 111 | if (Input.GetKeyDown(keyCommand.key)) 112 | { 113 | if (!keyCommand.ModifierQualified()) continue; 114 | if (logKeys) 115 | { 116 | Debug.Log(keyCommand.ToString()); 117 | } 118 | keyCommand.Invoke(); 119 | } 120 | } 121 | } 122 | 123 | [Serializable] 124 | public class KeyCommand : IComparable 125 | { 126 | public KeyCode key; 127 | [Header("Modifier Keys")] 128 | public bool ctrl; 129 | public bool shift; 130 | public bool alt; 131 | public bool win; 132 | 133 | private static List rejections = new List(); 134 | public bool ModifierQualified() 135 | { 136 | if (rejections.Contains(key)) return false; 137 | // If no modifiers are required, ignore all modifier states 138 | if (!ctrl && !shift && !alt && !win) return true; 139 | 140 | bool shiftState = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); 141 | bool ctrlState = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); 142 | bool altState = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt); 143 | bool winState = Input.GetKey(KeyCode.LeftWindows) || Input.GetKey(KeyCode.RightWindows) 144 | || Input.GetKey(KeyCode.LeftApple) || Input.GetKey(KeyCode.RightApple); 145 | 146 | // Return true if all states match requirements 147 | return shiftState == shift && 148 | ctrlState == ctrl && 149 | altState == alt && 150 | winState == win; 151 | } 152 | public static void NewFrame() 153 | { 154 | if (rejections == null) 155 | { 156 | rejections = new List(); 157 | } 158 | rejections.Clear(); 159 | } 160 | public virtual void Invoke() 161 | { 162 | rejections.Add(key); 163 | } 164 | public int ModifierCount() 165 | { 166 | int count = 0; 167 | if (ctrl) count++; 168 | if (shift) count++; 169 | if (alt) count++; 170 | if (win) count++; 171 | return count; 172 | } 173 | 174 | public int CompareTo(KeyCommand other) 175 | { 176 | if (ModifierCount() == other.ModifierCount()) return 0; 177 | return (ModifierCount() > other.ModifierCount()) ? -1 : 1; 178 | } 179 | public override string ToString() 180 | { 181 | string id = string.Empty; 182 | if (ctrl) id += "CTRL+"; 183 | if (shift) id += "SHIFT+"; 184 | if (alt) id += "ALT+"; 185 | if (win) id += "WIN+"; 186 | id += Enum.GetName(typeof(KeyCode), key); 187 | return id; 188 | } 189 | } 190 | 191 | [Serializable] 192 | public class ButtonKeyCommand : KeyCommand 193 | { 194 | [Header("Action")] 195 | public UnityEngine.UI.Button button; 196 | public override void Invoke() 197 | { 198 | if (button == null) return; 199 | base.Invoke(); 200 | if (button != null && button.interactable) 201 | { 202 | button.onClick.Invoke(); 203 | } 204 | } 205 | public override string ToString() 206 | { 207 | return $"{base.ToString()}: [Button] {button.name}"; 208 | } 209 | } 210 | [Serializable] 211 | public class ToggleKeyCommand : KeyCommand 212 | { 213 | [Header("Action")] 214 | public UnityEngine.UI.Toggle toggle; 215 | public override void Invoke() 216 | { 217 | if (toggle == null) return; 218 | base.Invoke(); 219 | if (toggle != null && toggle.interactable) 220 | { 221 | toggle.isOn = !toggle.isOn; 222 | } 223 | } 224 | public override string ToString() 225 | { 226 | return $"{base.ToString()}: [Toggle] {toggle.name}"; 227 | } 228 | } 229 | [Serializable] 230 | public class ActionKeyCommand : KeyCommand 231 | { 232 | public bool onKeyUp = false; 233 | [Header("Action")] 234 | public UnityEvent action; 235 | public override void Invoke() 236 | { 237 | if (action == null) return; 238 | base.Invoke(); 239 | action.Invoke(); 240 | } 241 | public override string ToString() 242 | { 243 | string result = $"{base.ToString()}: [Events"; 244 | if (onKeyUp) result += " (On Key Up)"; 245 | result += "]"; 246 | int eventCount = action.GetPersistentEventCount(); 247 | if (eventCount < 1) return result; 248 | result += $"\n"; 249 | 250 | for (int i = 0; i < eventCount; i++) 251 | { 252 | result += $"{action.GetPersistentTarget(i)}.{action.GetPersistentMethodName(i)}"; 253 | if (i < eventCount - 1) result += "\n"; 254 | } 255 | return result; 256 | } 257 | } 258 | [Serializable] 259 | public class HierarchyToggles : KeyCommand 260 | { 261 | [Header("Action")] 262 | public GameObject gameObject; 263 | public override void Invoke() 264 | { 265 | if (gameObject == null) return; 266 | base.Invoke(); 267 | gameObject.ToggleActive(); 268 | } 269 | public override string ToString() 270 | { 271 | return $"{base.ToString()}: [ToggleActive] {gameObject.name}"; 272 | } 273 | } 274 | } 275 | } -------------------------------------------------------------------------------- /Keybindings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06e9861d3c82a41bebe405a51a1abb35 3 | timeCreated: 1566032004 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 William Jackson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55da54ba41051436191032de33a981be 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LayoutGroups.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e6524f8e02ca4073a497e08270d01e5 3 | folderAsset: yes 4 | timeCreated: 1566028101 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /LayoutGroups/CurvedGridLayout3d.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | [ExecuteInEditMode] 6 | public class CurvedGridLayout3d : MonoBehaviour 7 | { 8 | public enum CurveAxis {Columns, Rows, Both} 9 | public CurveAxis curveAxis; 10 | private CurveAxis _cachedCurveAxis; 11 | public enum FaceDirection {Inward, Outward, Toward, Away} 12 | public FaceDirection faceDirection; 13 | private FaceDirection _cachedFaceDirection; 14 | public int columns = 5; 15 | public float radius = 5f; 16 | private float _cachedRadius; 17 | private int _cachedColumns; 18 | public float columnSpacing = 1f; 19 | private float _cachedColumnSpacing; 20 | public float rowSpacing = 1f; 21 | private float _cachedRowSpacing; 22 | private Transform[] _children; 23 | 24 | void Update () 25 | { 26 | if (columns < 1 || GetComponentsInChildren().Length <= 1) 27 | return; 28 | 29 | if ( columnSpacing != _cachedColumnSpacing 30 | || rowSpacing != _cachedRowSpacing 31 | || columns != _cachedColumns 32 | || radius != _cachedRadius 33 | || curveAxis != _cachedCurveAxis 34 | || faceDirection != _cachedFaceDirection 35 | || columns != _cachedColumns 36 | || _children != GetComponentsInChildren()) 37 | { 38 | _cachedColumnSpacing = columnSpacing; 39 | _cachedRowSpacing = rowSpacing; 40 | _cachedColumns = columns; 41 | _cachedRadius = radius; 42 | _cachedCurveAxis = curveAxis; 43 | _cachedFaceDirection = faceDirection; 44 | _children = GetComponentsInChildren(); 45 | 46 | // If there are fewer transforms than columns, pretend there are just that many columns. 47 | int appliedColumns = Mathf.Min(columns, _children.Length - 1); 48 | int rowCount = transform.childCount / appliedColumns; 49 | if (transform.childCount % appliedColumns != 0) 50 | { 51 | rowCount++; 52 | } 53 | 54 | // Offsets for centering 55 | float leftmostAngle = (curveAxis == CurveAxis.Rows) ? ((columnSpacing * (appliedColumns + 1)) * .5f) : -(columnSpacing * (appliedColumns - 1)) * .5f; 56 | float topmostAngle = (curveAxis != CurveAxis.Columns) ? -((rowSpacing * (rowCount - 1)) * .5f): (rowSpacing * (rowCount - 1)) * .5f; 57 | 58 | float appliedHorizontalSpacing = 0f; 59 | float appliedVerticalSpacing = 0f; 60 | int columnCount = 0; 61 | foreach (Transform element in transform) 62 | { 63 | columnCount++; 64 | 65 | // Project to a point on a sphere 66 | Quaternion rotation; 67 | if (curveAxis == CurveAxis.Columns) 68 | { 69 | rotation = Quaternion.AngleAxis(leftmostAngle + appliedHorizontalSpacing, transform.up); 70 | } 71 | if (curveAxis == CurveAxis.Rows) 72 | { 73 | rotation = Quaternion.AngleAxis(topmostAngle + appliedVerticalSpacing, transform.right); 74 | } 75 | else 76 | { 77 | rotation = Quaternion.AngleAxis(leftmostAngle + appliedHorizontalSpacing, transform.up); 78 | rotation *= Quaternion.AngleAxis(topmostAngle + appliedVerticalSpacing, transform.right); 79 | } 80 | Vector3 pos = rotation * transform.forward * radius; 81 | 82 | element.localPosition = pos; 83 | appliedHorizontalSpacing += columnSpacing; 84 | 85 | if (faceDirection == FaceDirection.Away) 86 | { 87 | element.LookAt(element.position - transform.forward); 88 | } 89 | else if (faceDirection == FaceDirection.Toward) 90 | { 91 | element.LookAt(element.position + transform.forward); 92 | } 93 | else 94 | { 95 | element.LookAt(transform.position); 96 | if (faceDirection == FaceDirection.Inward) 97 | { 98 | element.LookAt(element.position - element.forward); 99 | } 100 | } 101 | if (curveAxis == CurveAxis.Columns) 102 | { 103 | element.localPosition = element.localPosition.With(y: topmostAngle - appliedVerticalSpacing); 104 | } 105 | if (curveAxis == CurveAxis.Rows) 106 | { 107 | element.localPosition = element.localPosition.With(x: leftmostAngle - appliedHorizontalSpacing); 108 | } 109 | 110 | if (columnCount == appliedColumns) 111 | { 112 | columnCount = 0; 113 | appliedHorizontalSpacing = 0f; 114 | appliedVerticalSpacing += rowSpacing; 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /LayoutGroups/CurvedGridLayout3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc8dc868db4c34d76acff843cbbee60c 3 | timeCreated: 1566052481 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LayoutGroups/GridLayout3d.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | [ExecuteInEditMode] 6 | public class GridLayout3d : MonoBehaviour 7 | { 8 | public int columns = 5; 9 | private int _cachedColumns; 10 | public bool columnCentering = false; 11 | private bool _cachedColumnCentering = false; 12 | public float columnSpacing = 1f; 13 | private float _cachedColumnSpacing; 14 | public bool rowCentering = false; 15 | private bool _cachedRowCentering = false; 16 | public float rowSpacing = 1f; 17 | private float _cachedRowSpacing; 18 | private Transform[] _children; 19 | 20 | void Update () 21 | { 22 | if (columns < 1) 23 | return; 24 | 25 | if (columnSpacing != _cachedColumnSpacing || columnCentering != _cachedColumnCentering 26 | || rowSpacing != _cachedRowSpacing || rowCentering != _cachedRowCentering 27 | || columns != _cachedColumns || _children != GetComponentsInChildren()) 28 | { 29 | _cachedColumnSpacing = columnSpacing; 30 | _cachedColumnCentering = columnCentering; 31 | _cachedRowSpacing = rowSpacing; 32 | _cachedRowCentering = rowCentering; 33 | _cachedColumns = columns; 34 | _children = GetComponentsInChildren(); 35 | int rowCount = transform.childCount / columns; 36 | if (transform.childCount % columns != 0) 37 | { 38 | rowCount++; 39 | } 40 | Vector3 leftmostPos = (columnCentering) ? transform.localPosition.With(x: -(columnSpacing * (columns - 1)) * .5f) : Vector3.zero; 41 | Vector3 topmostPos = (rowCentering) ? transform.localPosition.With(y: (rowSpacing * (rowCount - 1)) * .5f) : Vector3.zero; 42 | 43 | float appliedHorizontalSpacing = 0f; 44 | float appliedVerticalSpacing = 0f; 45 | int columnCount = 0; 46 | foreach (Transform element in transform) 47 | { 48 | columnCount++; 49 | element.localPosition = transform.localPosition.With(x: leftmostPos.x + appliedHorizontalSpacing, y: topmostPos.y - appliedVerticalSpacing); 50 | appliedHorizontalSpacing += columnSpacing; 51 | if (columnCount == columns) 52 | { 53 | columnCount = 0; 54 | appliedHorizontalSpacing = 0f; 55 | appliedVerticalSpacing += rowSpacing; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /LayoutGroups/GridLayout3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2da50edf976b342e88d127ac2f28bae6 3 | timeCreated: 1566023695 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LayoutGroups/LayoutGroup3d.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace Wrj 5 | { 6 | [ExecuteInEditMode] 7 | public class LayoutGroup3d : MonoBehaviour { 8 | 9 | public bool horizontalCentering = true; 10 | private bool _cachedHorizontalCentering = true; 11 | public float horizontalSpacing = 1f; 12 | private float _cachedHorizontalSpacing; 13 | public bool verticalCentering = true; 14 | private bool _cachedVerticalCentering = true; 15 | public float verticalSpacing; 16 | private float _cachedVerticalSpacing; 17 | public bool depthCentering = true; 18 | private bool _cachedDepthCentering = true; 19 | public float depthSpacing; 20 | private float _cachedDepthSpacing; 21 | private List _children; 22 | 23 | void Update () 24 | { 25 | if (Application.isPlaying) return; 26 | Refresh(); 27 | } 28 | 29 | public void Refresh() 30 | { 31 | List children = new List(); 32 | foreach (Transform child in transform) 33 | { 34 | if (child.gameObject.activeInHierarchy) 35 | { 36 | children.Add(child); 37 | } 38 | } 39 | if (_children != children) 40 | { 41 | _children = children; 42 | _cachedHorizontalSpacing += 1f; 43 | _cachedVerticalSpacing += 1f; 44 | _cachedDepthSpacing += 1f; 45 | } 46 | 47 | if (horizontalSpacing != _cachedHorizontalSpacing || horizontalCentering != _cachedHorizontalCentering) 48 | { 49 | _cachedHorizontalSpacing = horizontalSpacing; 50 | _cachedHorizontalCentering = horizontalCentering; 51 | Vector3 leftmostPos = (horizontalCentering) ? transform.localPosition.With(x: -(horizontalSpacing * (children.Count - 1)) * .5f) : Vector3.zero; 52 | float appliedSpacing = 0f; 53 | foreach (Transform element in children) 54 | { 55 | element.localPosition = element.localPosition.With(x: leftmostPos.x + appliedSpacing); 56 | appliedSpacing += horizontalSpacing; 57 | } 58 | } 59 | 60 | if (verticalSpacing != _cachedVerticalSpacing || verticalCentering != _cachedVerticalCentering) 61 | { 62 | _cachedVerticalSpacing = verticalSpacing; 63 | _cachedVerticalCentering = verticalCentering; 64 | Vector3 topmostPos = (verticalCentering) ? transform.localPosition.With(y: -(verticalSpacing * (children.Count - 1)) * .5f) : Vector3.zero; 65 | float appliedSpacing = 0f; 66 | foreach (Transform element in children) 67 | { 68 | element.localPosition = element.localPosition.With(y: topmostPos.y + appliedSpacing); 69 | appliedSpacing += verticalSpacing; 70 | } 71 | } 72 | 73 | if (depthSpacing != _cachedDepthSpacing || depthCentering != _cachedDepthCentering) 74 | { 75 | _cachedDepthSpacing = depthSpacing; 76 | _cachedDepthCentering = depthCentering; 77 | Vector3 farmostPos = (depthCentering) ? transform.localPosition.With(z: -(depthSpacing * (children.Count - 1)) * .5f) : Vector3.zero; 78 | float appliedSpacing = 0f; 79 | foreach (Transform element in children) 80 | { 81 | element.localPosition = element.localPosition.With(z: farmostPos.z + appliedSpacing); 82 | appliedSpacing += depthSpacing; 83 | } 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /LayoutGroups/LayoutGroup3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68b020d8a75294d959f5e8d004dbe631 3 | timeCreated: 1566021181 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /PathFollowerExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/PathFollowerExample.gif -------------------------------------------------------------------------------- /PathFollowerExample.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e3c1b20149c5411ab1996c70e000915 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMasterTextureLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 1 67 | swizzle: 50462976 68 | cookieLightType: 1 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 1 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 1 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 1 106 | - serializedVersion: 3 107 | buildTarget: iPhone 108 | maxTextureSize: 2048 109 | resizeAlgorithm: 0 110 | textureFormat: -1 111 | textureCompression: 1 112 | compressionQuality: 50 113 | crunchedCompression: 0 114 | allowsAlphaSplitting: 0 115 | overridden: 0 116 | androidETC2FallbackOverride: 0 117 | forceMaximumCompressionQuality_BC6H_BC7: 1 118 | spriteSheet: 119 | serializedVersion: 2 120 | sprites: [] 121 | outline: [] 122 | physicsShape: [] 123 | bones: [] 124 | spriteID: af5659d0472ab69439c06d049fc13979 125 | internalID: 0 126 | vertices: [] 127 | indices: 128 | edges: [] 129 | weights: [] 130 | secondaryTextures: [] 131 | nameFileIdTable: {} 132 | spritePackingTag: 133 | pSDRemoveMatte: 0 134 | userData: 135 | assetBundleName: 136 | assetBundleVariant: 137 | -------------------------------------------------------------------------------- /Paths.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ef1e84392f009447ca54434ed9a9154e 3 | folderAsset: yes 4 | timeCreated: 1546576006 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Paths/BezierPath.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | public class BezierPath : MonoBehaviour 6 | { 7 | public Transform slider; 8 | [Range(0, 1)] 9 | public float percent = 0f; 10 | [Range(2, 50)] 11 | public int res = 15; 12 | 13 | private int m_cachedRes = -1; 14 | private PathGuide[] m_Points; 15 | private Vector3[] m_Curve; 16 | 17 | public Vector3[] Curve { get => m_Curve; } 18 | 19 | void Awake() 20 | { 21 | RefreshPath(); 22 | // Disable mesh renderers on PathGuides 23 | foreach (MeshRenderer rend in GetComponentsInChildren()) 24 | { 25 | if (rend.GetComponent()) 26 | rend.enabled = false; 27 | } 28 | } 29 | 30 | void Update() 31 | { 32 | if (res != m_cachedRes) 33 | { 34 | RefreshPath(); 35 | } 36 | if (slider != null) 37 | { 38 | Vector3 look = Vector3.zero; 39 | slider.position = GetPointOnCurve(m_Curve, percent, ref look); 40 | slider.LookAt(look); 41 | } 42 | } 43 | 44 | // Build up a new curve with latest curveguides 45 | public void RefreshPath() 46 | { 47 | m_cachedRes = res; 48 | m_Curve = CurvePath(res); 49 | } 50 | public Vector3 GetPointOnCurve(float t, ref Vector3 lookAt) 51 | { 52 | return GetPointOnCurve(m_Curve, t, ref lookAt); 53 | } 54 | 55 | public static Vector3 GetPointOnCurve(Vector3[] path, float t, ref Vector3 lookAt) 56 | { 57 | if (path.Length < 2) 58 | { 59 | return Vector3.zero; 60 | } 61 | 62 | // Get total length of path 63 | float posOnLine = GetCurveLength(path) * t; 64 | 65 | for (int i = 0; i < path.Length - 1; i++) 66 | { 67 | Vector3 p0 = path[i]; 68 | Vector3 p1 = path[i + 1]; 69 | float currentDistance = Vector3.Distance(p1, p0); 70 | 71 | // If the remaining distance is greater than the distance between these vectors, subtract the current distance and proceed 72 | if (currentDistance < posOnLine) 73 | { 74 | posOnLine -= currentDistance; 75 | continue; 76 | } 77 | 78 | lookAt = Vector3.Lerp(p0, p1, posOnLine / currentDistance + .1f); 79 | return Vector3.Lerp(p0, p1, posOnLine / currentDistance); 80 | } 81 | // made it to the end 82 | lookAt = Vector3.Lerp(path[path.Length - 2], path[path.Length - 1], 1f); 83 | return path[path.Length - 1]; 84 | } 85 | 86 | // Returns total length of the curve 87 | public float GetCurveLength() 88 | { 89 | return GetCurveLength(m_Curve); 90 | } 91 | 92 | public static float GetCurveLength(Vector3[] path) 93 | { 94 | if (path.Length < 1) 95 | return 0; 96 | 97 | float length = 0f; 98 | for (int i = 0; i < path.Length - 1; i++) 99 | { 100 | length += Vector3.Distance(path[i + 1], path[i]); 101 | } 102 | return length; 103 | } 104 | 105 | // Cunstruct a curve path. 106 | public Vector3[] CurvePath(int resolution = 15) 107 | { 108 | // Collect PathGuides 109 | m_Points = GetComponentsInChildren(); 110 | // Require at least 3, for start, influence, and end. 111 | if (m_Points.Length < 3) 112 | return null; 113 | 114 | // Create vector array to hold the results (-2 is to accommodate the first and last) 115 | Vector3[] finalPoints = new Vector3[(m_Points.Length - 2) * resolution]; 116 | 117 | // Start at the front of the path 118 | Vector3 currentPos = m_Points[0].transform.position; 119 | int finalPointIndex = 0; 120 | 121 | // Connect multiple quadratic curves from the mid-point between each PathGuide node 122 | for (int i = 1; i < m_Points.Length - 2; i += 1) 123 | { 124 | Vector3 p0 = m_Points[i].transform.position; 125 | Vector3 p1 = m_Points[i + 1].transform.position; 126 | // Get the midpoint between p0 & p1 127 | Vector3 mid = Vector3.Lerp(p0, p1, .5f); 128 | finalPointIndex = (i * resolution) - resolution; 129 | foreach (Vector3 p in Wrj.Utils.QuadraticBezierCurve(currentPos, p0, mid, resolution)) 130 | { 131 | finalPoints[finalPointIndex] = p; 132 | finalPointIndex++; 133 | } 134 | currentPos = mid; 135 | } 136 | finalPointIndex = (m_Points.Length - 2) * resolution - resolution; 137 | foreach (Vector3 p in Wrj.Utils.QuadraticBezierCurve(currentPos, m_Points[m_Points.Length - 2].transform.position, m_Points[m_Points.Length - 1].transform.position, resolution)) 138 | { 139 | finalPoints[finalPointIndex] = p; 140 | finalPointIndex++; 141 | } 142 | return finalPoints; 143 | } 144 | 145 | // Renumber curveguide children 146 | public void RefreshChildIndices() 147 | { 148 | foreach (PathGuide cg in transform.GetComponentsInChildren()) 149 | { 150 | cg.name = "Node_" + cg.transform.GetSiblingIndex(); 151 | } 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /Paths/BezierPath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f216e83e9dad4c6db9de64e4e053f6c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Paths/PathGuide.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using System; 5 | #if UNITY_EDITOR 6 | using UnityEditor; 7 | #endif 8 | 9 | namespace Wrj 10 | { 11 | public class PathGuide : MonoBehaviour 12 | { 13 | private BezierPath ownerPath; 14 | private Vector3 lastPos; 15 | void Awake() 16 | { 17 | ownerPath = GetOwnerPath(); 18 | if (ownerPath == null) 19 | { 20 | Destroy(this); 21 | } 22 | } 23 | void Update() 24 | { 25 | if (transform.position != lastPos) 26 | { 27 | ownerPath.RefreshPath(); 28 | lastPos = transform.position; 29 | } 30 | } 31 | 32 | public void Duplicate(PathGuide toDupe) 33 | { 34 | #if UNITY_EDITOR 35 | Undo.SetCurrentGroupName("Duplicate Curve Node"); 36 | GameObject dupe = Instantiate(toDupe.gameObject); 37 | Undo.RegisterCreatedObjectUndo(dupe, ""); 38 | dupe.transform.parent = toDupe.transform.parent; 39 | dupe.transform.position = toDupe.transform.position; 40 | int index = (toDupe.transform.GetSiblingIndex() == 0) ? 0 : toDupe.transform.GetSiblingIndex() + 1; 41 | dupe.transform.SetSiblingIndex(index); 42 | Undo.RegisterFullObjectHierarchyUndo(dupe.transform.parent.gameObject, ""); 43 | Undo.CollapseUndoOperations(Undo.GetCurrentGroup()); 44 | Selection.activeGameObject = dupe; 45 | GetOwnerPath().RefreshChildIndices(); 46 | #endif 47 | } 48 | 49 | public BezierPath GetOwnerPath() 50 | { 51 | return transform.parent.GetComponent(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Paths/PathGuide.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70301189724b842d1a45d54d7f2bc209 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /PoolManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Events; 5 | 6 | namespace Wrj 7 | { 8 | public class PoolManager : MonoBehaviour 9 | { 10 | [SerializeField] 11 | [Tooltip("Prototype disabled child object to duplicate in the pool")] 12 | private Component sourceObject = null; 13 | [Tooltip("If the object is not finished within this amount of time it will auto-disable. Set to 0 to for permanence.")] 14 | [SerializeField] 15 | private float defaultLifeSpan = 10f; 16 | 17 | public UnityAction OnObjectStashing; 18 | 19 | private List _GameObjects = new List(); 20 | private Dictionary _RunningTimeouts = new Dictionary(); 21 | 22 | private void Start() 23 | { 24 | sourceObject.gameObject.SetActive(false); 25 | } 26 | 27 | public GameObject Next(float lifeSpan) 28 | { 29 | if (sourceObject == null) 30 | { 31 | Debug.LogWarning($"No source object provided to PoolManager ({name}).", this); 32 | return null; 33 | } 34 | 35 | // Get the first available game object from the pool. 36 | // This will add a new one if necessary. 37 | GameObject go = FirstAvailable(); 38 | 39 | // Start the auto-disable timer, if needed. 40 | if (defaultLifeSpan > 0f) 41 | { 42 | Coroutine thisTimeout = StartCoroutine(LifeSpanRoutine(go, lifeSpan)); 43 | _RunningTimeouts.Add(go, thisTimeout); 44 | } 45 | 46 | // Position the object to match the source. 47 | go.transform.localPosition = sourceObject.transform.localPosition; 48 | go.transform.localRotation = sourceObject.transform.localRotation; 49 | 50 | // Enable in the hierarchy 51 | go.SetActive(true); 52 | 53 | return go; 54 | } 55 | public GameObject Next() 56 | { 57 | return Next(defaultLifeSpan); 58 | } 59 | public T Next(float lifeSpan) 60 | { 61 | GameObject go = Next(lifeSpan); 62 | T target = go.GetComponent(); 63 | if (target == null) Debug.LogWarning($"Pool element has no {typeof(T).Name}"); 64 | return target; 65 | } 66 | public T Next() 67 | { 68 | return Next(defaultLifeSpan); 69 | } 70 | public dynamic NextComponent(float lifeSpan) 71 | { 72 | return Next(lifeSpan).GetComponent(sourceObject.GetType().Name); 73 | } 74 | public dynamic NextComponent() 75 | { 76 | return Next(defaultLifeSpan).GetComponent(sourceObject.GetType().Name); 77 | } 78 | 79 | 80 | public void Finish(GameObject element) 81 | { 82 | // Find the object in the list 83 | foreach (GameObject go in _GameObjects) 84 | { 85 | if (go == element.gameObject) 86 | { 87 | OnObjectStashing(go); 88 | // Disable it in the hierarchy 89 | go.SetActive(false); 90 | // Kill the auto-disable timer 91 | if (_RunningTimeouts.ContainsKey(go)) 92 | { 93 | StopCoroutine(_RunningTimeouts[go]); 94 | _RunningTimeouts.Remove(go); 95 | } 96 | return; 97 | } 98 | } 99 | } 100 | public void Finish(Component element) 101 | { 102 | Finish(element.gameObject); 103 | } 104 | 105 | private GameObject FirstAvailable() 106 | { 107 | // Find the first object available 108 | foreach (GameObject go in _GameObjects) 109 | { 110 | if (!go.activeSelf) 111 | { 112 | return go; 113 | } 114 | } 115 | // If none available add a new one 116 | return InstantiateNewObject(); 117 | } 118 | 119 | private GameObject InstantiateNewObject() 120 | { 121 | // Creat object 122 | GameObject newGO = Instantiate(sourceObject.gameObject); 123 | // Name it 124 | newGO.name = sourceObject.name + "(PoolObject)"; 125 | // Child it 126 | newGO.transform.parent = transform; 127 | // Add to list 128 | _GameObjects.Add(newGO); 129 | return newGO; 130 | } 131 | 132 | // Auto-disable timer 133 | private IEnumerator LifeSpanRoutine(GameObject go, float lifeSpan) 134 | { 135 | yield return new WaitForSeconds(lifeSpan); 136 | Finish(go); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /PoolManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8edb6ed80c5a64884b82fae01a05fd2c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Prefs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Prefs.png -------------------------------------------------------------------------------- /Prefs.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43f45d5140dd643a8992bdbc99957e5e 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /QueryStringParser.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine.Events; 2 | using UnityEngine; 3 | 4 | namespace Wrj 5 | { 6 | public class QueryStringParser : MonoBehaviour 7 | { 8 | [SerializeField] 9 | private QueryStringCommand[] queryStrings; 10 | private static System.Collections.Specialized.NameValueCollection results; 11 | void Start() 12 | { 13 | #if UNITY_WEBGL 14 | string url = Application.absoluteURL; 15 | // Test string: 16 | // string url = "www.test.com/index.htm?EnableHints=true&WordList=Engagement,In,On,Oh&w=30&h=16&float=1.75"; 17 | var splitUrl = url.Split(new[] { '?' }, 2); 18 | if (splitUrl.Length > 1) 19 | { 20 | var querySubstring = splitUrl[1]; 21 | results = System.Web.HttpUtility.ParseQueryString(querySubstring); 22 | foreach (var qs in queryStrings) 23 | { 24 | foreach (var item in results) 25 | { 26 | if (item.ToString().ToLower() == qs.queryString.ToLower()) 27 | { 28 | if (qs.action.GetPersistentEventCount() > 0) 29 | { 30 | qs.action.Invoke(results[item.ToString()]); 31 | } 32 | if (qs.option.GetPersistentEventCount() > 0 && 33 | bool.TryParse(results[item.ToString()], out bool bResult)) 34 | { 35 | qs.option.Invoke(bResult); 36 | } 37 | if (qs.integer.GetPersistentEventCount() > 0 && 38 | int.TryParse(results[item.ToString()], out int iResult)) 39 | { 40 | qs.integer.Invoke(iResult); 41 | } 42 | if (qs.floatVal.GetPersistentEventCount() > 0 && 43 | float.TryParse(results[item.ToString()], out float fResult)) 44 | { 45 | qs.floatVal.Invoke(fResult); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | #endif 52 | } 53 | public static string GetQueryStringValue(string key) 54 | { 55 | if (results != null) 56 | { 57 | return results[key]; 58 | } 59 | return null; 60 | } 61 | 62 | [System.Serializable] 63 | public class QueryStringCommand 64 | { 65 | public string queryString; 66 | public UnityEvent action; 67 | public UnityEvent option; 68 | public UnityEvent integer; 69 | public UnityEvent floatVal; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /QueryStringParser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dee13f81425bb104c943fdd881ab8173 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity Scripting Utilities 2 | ![PathTrail](Smile.gif) 3 | Stuff I use a lot, and a simple AnimationCurve-based tweening interface. 4 | 5 | Add to projects using Package Manager git url: 6 | ``` 7 | https://github.com/williamrjackson/UnityScriptingUtilities.git#v1.6.16 8 | ``` 9 | OR 10 | ``` 11 | https://github.com/williamrjackson/UnityScriptingUtilities.git#v1.6 12 | ``` 13 | 14 | ## MapToCurve 15 | Provides values as plotted on an Animation Curve. Used a lot like Mathf.Lerp, except not linear. 16 | 17 | Includes a bunch of functions to manipulate transforms/audio over time. For example, the following will scale, move and rotate a transfrom into a position over 5 seconds. The target position is defined by a sibling transfrom. 18 | 19 | Presets for common ease curves from https://github.com/aureliendrouet/EasingCurvePresets are included 20 | ```C# 21 | Wrj.Utils.MapToCurve.Ease.MatchSibling(transform, targetTransform, 5f); 22 | // ^ ^ ^ ^ ^ 23 | // curve function affected destination duration 24 | ``` 25 | #### Manipulation Functions 26 | ``` 27 | Scale 28 | Move (local space) 29 | MoveWorld (world space) 30 | MoveAlongPath 31 | Rotate 32 | FadeAudio 33 | CrossfadeAudio (smoothly transitions between two audio sources) 34 | FadeAlpha 35 | ChangeColor 36 | MatchSibling 37 | ``` 38 | #### Arguments & Common Modifiers 39 | ``` 40 | tForm - Transform to affect 41 | to - Target destination/rotation/volume/etc. 42 | duration - Length of time in seconds for the manipulation to complete. 43 | Applies to a single loop/pingPong iteration. 44 | mirrorCurve - Swap the in/out curve shapes. 45 | Get EaseOut by combining the EaseIn curve with this flag. 46 | repeatStyle - Loop the manipulation. 47 | - PingPong: repeat the manipulation forward, then backward. 48 | - MirrorPingPong: pingPong, but inverts the curve when performing backward manipulations. 49 | repeatIterations - Repeat this many times. Use -1 for infinite. 50 | useTimeScale - Set this to false to ignore global time scaling 51 | shortestPath - In the case of manipulations that include rotation, this will cause minimal 52 | possible rotation to get to the target. Without this, a rotation difference > 360 53 | will result in a full positive rotation before reaching the target. 54 | onDone - Specify a function to call when the operation completes 55 | ``` 56 | There are simplified GameObject and Transform Extension Methods for linear and ease manipulations: 57 | ``` 58 | transform.Move(destination, duration); 59 | transform.EaseMove(destination, duration); 60 | transform.Rotate(targetRotation, duration); 61 | transform.EaseRotate(targetRotation, duration); 62 | transform.Scale(targetScale, duration); 63 | transform.EaseScale(TargetScale, duration); 64 | transform.SnapToSibling(targetSibling, duration); 65 | transform.EaseSnapToSibling(targetSibling, duration); 66 | transform.Color(desiredColor, duration); 67 | transform.Alpha(desiredAlpha, duration); 68 | ``` 69 | ![Tweening](TweenExample.gif) 70 | #### Test Bed Example 71 | ```C# 72 | float duration = 4.0f 73 | 74 | // Black Cube 75 | Vector3 blackTargetPos = blackTransform.localPosition + Vector3.up * 5 + Vector3.right * -1.5f; 76 | Vector3 blackTargetRot = Vector3.up * 135; 77 | 78 | Wrj.Utils.MapToCurve.Linear.Move(blackTransform, linTargetPos, duration, pingPong: 10); 79 | Wrj.Utils.MapToCurve.Linear.Rotate(blackTransform, blackTargetRot, duration, shortestPath: false, pingPong: 10); 80 | Wrj.Utils.MapToCurve.Ease.ChangeColor(blackTransform, Color.black, duration, pingPong: 10); 81 | 82 | // Red Cube 83 | Vector3 redTargetPos = redTransform.localPosition + Vector3.up * 5 + Vector3.right * .5f; 84 | Vector3 redTargetRot = Vector3.up * -360; 85 | 86 | Wrj.Utils.MapToCurve.EaseIn.Move(redTransform, redTargetPos, duration, mirrorCurve: false, pingPong: 10); 87 | Wrj.Utils.MapToCurve.EaseIn.Rotate(redTransform, redTargetRot, duration, shortestPath: false, pingPong: 10); 88 | Wrj.Utils.MapToCurve.Ease.ChangeColor(redTransform, Color.red, duration, pingPong: 10); 89 | 90 | // Blue Cube 91 | Vector3 blueTargetPos = blueTransform.localPosition + Vector3.up * 5 + Vector3.right * -.5f; 92 | Vector3 blueTargetRot = Vector3.forward * -720; 93 | 94 | Wrj.Utils.MapToCurve.EaseIn.Move(blueTransform, blueTargetPos, duration, mirrorCurve: true, pingPong: 10); 95 | Wrj.Utils.MapToCurve.EaseIn.Rotate(blueTransform, blueTargetRot, duration, shortestPath: false, mirrorPingPong: 10); 96 | Wrj.Utils.MapToCurve.Ease.ChangeColor(blueTransform, Color.blue, duration, pingPong: 10); 97 | 98 | // Purple Cube 99 | Wrj.Utils.MapToCurve.Ease.MatchSibling(purpleTransform, targetTransform, duration, pingPong: 10); 100 | Wrj.Utils.MapToCurve.Ease.ChangeColor(purpleTransform, Color.magenta, duration, pingPong: 10); 101 | 102 | // Purple Cube's Target 103 | Wrj.Utils.MapToCurve.Ease.FadeAlpha(targetTransform, 0, duration, pingPong: 10); 104 | 105 | ``` 106 | ## WeightedElements 107 | Also includes a Weighted Random Object class (demonstrated on the right in the gif above). 108 | 109 | Contains a collection of objects with an int representing its weight. Higher weights are more likely for selection When `weightedElements.GetRandom()` is called. 110 | 111 | Can also be initialized with a source `List` and an `AnimationCurve` representing the desired weights. 112 | 113 | ```C# 114 | public Transform weight10; 115 | public Transform weight5; 116 | public Transform weight3; 117 | public Transform weight1; 118 | WeightedElements randomBumpObjects = new WeightedElements(); 119 | 120 | randomBumpObjects.Add(weight10, 10); 121 | randomBumpObjects.Add(weight5, 5); 122 | randomBumpObjects.Add(weight3, 3); 123 | randomBumpObjects.Add(weight1, 1); 124 | 125 | // This is most likely to scale object weight10. But it's fairly unlikely to scale weight1 126 | randomBumpObjects.GetRandom().localScale = Vector3.one * 1.5f; 127 | ``` 128 | 129 | ## Utility Functions 130 | - `EnsureComponent(GameObject)` 131 | - Returns a component instance by finding the one on the game object, or by adding one if not found. 132 | - `DeferredExecution(delayTime, () => Method(withParams))` 133 | - Issues a command after the specified delayTime elapses. 134 | - `Switcheroo(ref T a, ref T b)` 135 | - Swap items 136 | - `AffectGORecursively(GameObject, AnyFunctionThatTakesAGameObj)` 137 | - Call AnyFunctionThatTakesAGameObj for GameObject and all of it's children. 138 | - `GetPositiveAngle(float OR Vector3)` 139 | - Ensure an angle in degrees is within 0 - 360 140 | - `Remap(value, sourceMin, sourceMax, destMin, destMax)` 141 | - Linearly remaps a value from a source range to a desired range 142 | - `QuadraticBezierCurve(origin, influence, destination, pointCount)` 143 | - Get an array of points representing a quadratic bezier curve. 144 | - `CubicBezierCurve(origin, influenceA, influnceB, destination, pointCount)` 145 | - Get an array of points representing a cubic bezier curve. 146 | - `FromFeet(feet)` 147 | - Convert feet into Unity Units. Because I'm a silly American that can only visualise space in US standard units. 148 | - `FromInches(inches)` 149 | - Convert inches into Unity Units. 150 | - `String.PrependAn(capitalize)` 151 | - Prepends either "A" or "An" depending on the word. 152 | - `String.Pluralize(capitalize)` 153 | - Appends "s" or "es" based on common rules. Uses dictionary of common outliers. "Puma" -> "Pumas"; "Fox" -> "Foxes"; "Index" -> "Indices" 154 | - `List.GetRandom()` and `Array.GetRandom()` 155 | - Returns a random element from an array or list. 156 | - `CoinFlip` 157 | - Returns true or false at random. 158 | 159 | ## Bezier Path Editor 160 | Editor scripts to create paths. `MapToCurve` includes a tween to follow paths over a duration using a speed curve. 161 | 162 | ![Path](PathFollowerExample.gif) 163 | 164 | ## 3D Layout Groups 165 | Basic object distribution scripts that run in edit mode, dynamically adapting to changes in the child hierarchy. Similar to UI Layout Groups, but for 3D transforms. Offers flat grid distribution and curved grid distribution. 166 | 167 | ## ObjectPool 168 | Creates and enables game objects, recycling whenever possible. 169 | 170 | ## AudioPool 171 | Plays an AudioClip by cycling through multiple audio sources, preventing clicks and pops. Also includes RandomizedSoundEffect component that picks a random sample from a list, randomizing pitch and volume within a specified range. 172 | 173 | ## CustomLog 174 | UnityEngine.Debug.Log wrapper allowing you to subscribe to log updates, to change in-game Text for example. Inspired by the need to see the Debug.Log entries within a VR experience, without ruining the ability to doubleclick the item in the Unity Console. Also provides the ability to colorize in the Console. Usage: `Wrj.CustomLog.Log("Test", Color.cyan)`. Add `CustomLogTextUpdate` component to an object containing a `TMPro.TextMeshProUGUI`, `UnityEngine.UI.Text` or `TextMesh` to update text each time `CustomLog.Log()` is called. 175 | 176 | ## Custom Script Creation Options 177 | ![CustomCreationPrefs](Prefs.png) 178 | 179 | - Custom Script Path 180 | - New scripts created directly on GameObjects or in Assets root will automatically move to the Custom Script Path. Leave blank to disable. 181 | - Default Namespace 182 | - Automatically adds a default namespace to newly created scripts. Requires a custom monobehavior script in `%EDITOR_PATH%\\Data\\Resources\\ScriptTemplates` containing the variable `#NAMESPACE#`. 183 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a806fd4b96a04a6189e04eab634bf40 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3203721b23f68464fab8aef1f139f55e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Resources/WordList.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e7d1644668e642eeb5eacaef801c837 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Resources/WordListTop1000.txt: -------------------------------------------------------------------------------- 1 | a 2 | ability 3 | able 4 | about 5 | above 6 | accept 7 | according 8 | account 9 | across 10 | act 11 | action 12 | activity 13 | actually 14 | add 15 | address 16 | administration 17 | admit 18 | adult 19 | affect 20 | after 21 | again 22 | against 23 | age 24 | agency 25 | agent 26 | ago 27 | agree 28 | agreement 29 | ahead 30 | air 31 | all 32 | allow 33 | almost 34 | alone 35 | along 36 | already 37 | also 38 | although 39 | always 40 | american 41 | among 42 | amount 43 | analysis 44 | and 45 | animal 46 | another 47 | answer 48 | any 49 | anyone 50 | anything 51 | appear 52 | apply 53 | approach 54 | area 55 | argue 56 | arm 57 | around 58 | arrive 59 | art 60 | article 61 | artist 62 | as 63 | ask 64 | assume 65 | at 66 | attack 67 | attention 68 | attorney 69 | audience 70 | author 71 | authority 72 | available 73 | avoid 74 | away 75 | baby 76 | back 77 | bad 78 | bag 79 | ball 80 | bank 81 | bar 82 | base 83 | be 84 | beat 85 | beautiful 86 | because 87 | become 88 | bed 89 | before 90 | begin 91 | behavior 92 | behind 93 | believe 94 | benefit 95 | best 96 | better 97 | between 98 | beyond 99 | big 100 | bill 101 | billion 102 | bit 103 | black 104 | blood 105 | blue 106 | board 107 | body 108 | book 109 | born 110 | both 111 | box 112 | boy 113 | break 114 | bring 115 | brother 116 | budget 117 | build 118 | building 119 | business 120 | but 121 | buy 122 | by 123 | call 124 | camera 125 | campaign 126 | can 127 | cancer 128 | candidate 129 | capital 130 | car 131 | card 132 | care 133 | career 134 | carry 135 | case 136 | catch 137 | cause 138 | cell 139 | center 140 | central 141 | century 142 | certain 143 | certainly 144 | chair 145 | challenge 146 | chance 147 | change 148 | character 149 | charge 150 | check 151 | child 152 | choice 153 | choose 154 | church 155 | citizen 156 | city 157 | civil 158 | claim 159 | class 160 | clear 161 | clearly 162 | close 163 | coach 164 | cold 165 | collection 166 | college 167 | color 168 | come 169 | commercial 170 | common 171 | community 172 | company 173 | compare 174 | computer 175 | concern 176 | condition 177 | conference 178 | congress 179 | consider 180 | consumer 181 | contain 182 | continue 183 | control 184 | cost 185 | could 186 | country 187 | couple 188 | course 189 | court 190 | cover 191 | create 192 | crime 193 | cultural 194 | culture 195 | cup 196 | current 197 | customer 198 | cut 199 | dark 200 | data 201 | daughter 202 | day 203 | dead 204 | deal 205 | death 206 | debate 207 | decade 208 | decide 209 | decision 210 | deep 211 | defense 212 | degree 213 | democrat 214 | democratic 215 | describe 216 | design 217 | despite 218 | detail 219 | determine 220 | develop 221 | development 222 | die 223 | difference 224 | different 225 | difficult 226 | dinner 227 | direction 228 | director 229 | discover 230 | discuss 231 | discussion 232 | disease 233 | do 234 | doctor 235 | dog 236 | door 237 | down 238 | draw 239 | dream 240 | drive 241 | drop 242 | drug 243 | during 244 | each 245 | early 246 | east 247 | easy 248 | eat 249 | economic 250 | economy 251 | edge 252 | education 253 | effect 254 | effort 255 | eight 256 | either 257 | election 258 | else 259 | employee 260 | end 261 | energy 262 | enjoy 263 | enough 264 | enter 265 | entire 266 | environment 267 | environmental 268 | especially 269 | establish 270 | even 271 | evening 272 | event 273 | ever 274 | every 275 | everybody 276 | everyone 277 | everything 278 | evidence 279 | exactly 280 | example 281 | executive 282 | exist 283 | expect 284 | experience 285 | expert 286 | explain 287 | eye 288 | face 289 | fact 290 | factor 291 | fail 292 | fall 293 | family 294 | far 295 | fast 296 | father 297 | fear 298 | federal 299 | feel 300 | feeling 301 | few 302 | field 303 | fight 304 | figure 305 | fill 306 | film 307 | final 308 | finally 309 | financial 310 | find 311 | fine 312 | finger 313 | finish 314 | fire 315 | firm 316 | first 317 | fish 318 | five 319 | floor 320 | fly 321 | focus 322 | follow 323 | food 324 | foot 325 | for 326 | force 327 | foreign 328 | forget 329 | form 330 | former 331 | forward 332 | four 333 | free 334 | friend 335 | from 336 | front 337 | full 338 | fund 339 | future 340 | game 341 | garden 342 | gas 343 | general 344 | generation 345 | get 346 | girl 347 | give 348 | glass 349 | go 350 | goal 351 | good 352 | government 353 | great 354 | green 355 | ground 356 | group 357 | grow 358 | growth 359 | guess 360 | gun 361 | guy 362 | hair 363 | half 364 | hand 365 | hang 366 | happen 367 | happy 368 | hard 369 | have 370 | he 371 | head 372 | health 373 | hear 374 | heart 375 | heat 376 | heavy 377 | help 378 | her 379 | here 380 | herself 381 | high 382 | him 383 | himself 384 | his 385 | history 386 | hit 387 | hold 388 | home 389 | hope 390 | hospital 391 | hot 392 | hotel 393 | hour 394 | house 395 | how 396 | however 397 | huge 398 | human 399 | hundred 400 | husband 401 | i 402 | idea 403 | identify 404 | if 405 | image 406 | imagine 407 | impact 408 | important 409 | improve 410 | in 411 | include 412 | including 413 | increase 414 | indeed 415 | indicate 416 | individual 417 | industry 418 | information 419 | inside 420 | instead 421 | institution 422 | interest 423 | interesting 424 | international 425 | interview 426 | into 427 | investment 428 | involve 429 | issue 430 | it 431 | item 432 | its 433 | itself 434 | job 435 | join 436 | just 437 | keep 438 | key 439 | kid 440 | kill 441 | kind 442 | kitchen 443 | know 444 | knowledge 445 | land 446 | language 447 | large 448 | last 449 | late 450 | later 451 | laugh 452 | law 453 | lawyer 454 | lay 455 | lead 456 | leader 457 | learn 458 | least 459 | leave 460 | left 461 | leg 462 | legal 463 | less 464 | let 465 | letter 466 | level 467 | lie 468 | life 469 | light 470 | like 471 | likely 472 | line 473 | list 474 | listen 475 | little 476 | live 477 | local 478 | long 479 | look 480 | lose 481 | loss 482 | lot 483 | love 484 | low 485 | machine 486 | magazine 487 | main 488 | maintain 489 | major 490 | majority 491 | make 492 | man 493 | manage 494 | management 495 | manager 496 | many 497 | market 498 | marriage 499 | material 500 | matter 501 | may 502 | maybe 503 | me 504 | mean 505 | measure 506 | media 507 | medical 508 | meet 509 | meeting 510 | member 511 | memory 512 | mention 513 | message 514 | method 515 | middle 516 | might 517 | military 518 | million 519 | mind 520 | minute 521 | miss 522 | mission 523 | model 524 | modern 525 | moment 526 | money 527 | month 528 | more 529 | morning 530 | most 531 | mother 532 | mouth 533 | move 534 | movement 535 | movie 536 | mr 537 | mrs 538 | much 539 | music 540 | must 541 | my 542 | myself 543 | name 544 | nation 545 | national 546 | natural 547 | nature 548 | near 549 | nearly 550 | necessary 551 | need 552 | network 553 | never 554 | new 555 | news 556 | newspaper 557 | next 558 | nice 559 | night 560 | no 561 | none 562 | nor 563 | north 564 | not 565 | note 566 | nothing 567 | notice 568 | now 569 | n't 570 | number 571 | occur 572 | of 573 | off 574 | offer 575 | office 576 | officer 577 | official 578 | often 579 | oh 580 | oil 581 | ok 582 | old 583 | on 584 | once 585 | one 586 | only 587 | onto 588 | open 589 | operation 590 | opportunity 591 | option 592 | or 593 | order 594 | organization 595 | other 596 | others 597 | our 598 | out 599 | outside 600 | over 601 | own 602 | owner 603 | page 604 | pain 605 | painting 606 | paper 607 | parent 608 | part 609 | participant 610 | particular 611 | particularly 612 | partner 613 | party 614 | pass 615 | past 616 | patient 617 | pattern 618 | pay 619 | peace 620 | people 621 | per 622 | perform 623 | performance 624 | perhaps 625 | period 626 | person 627 | personal 628 | phone 629 | physical 630 | pick 631 | picture 632 | piece 633 | place 634 | plan 635 | plant 636 | play 637 | player 638 | pm 639 | point 640 | police 641 | policy 642 | political 643 | politics 644 | poor 645 | popular 646 | population 647 | position 648 | positive 649 | possible 650 | power 651 | practice 652 | prepare 653 | present 654 | president 655 | pressure 656 | pretty 657 | prevent 658 | price 659 | private 660 | probably 661 | problem 662 | process 663 | produce 664 | product 665 | production 666 | professional 667 | professor 668 | program 669 | project 670 | property 671 | protect 672 | prove 673 | provide 674 | public 675 | pull 676 | purpose 677 | push 678 | put 679 | quality 680 | question 681 | quickly 682 | quite 683 | race 684 | radio 685 | raise 686 | range 687 | rate 688 | rather 689 | reach 690 | read 691 | ready 692 | real 693 | reality 694 | realize 695 | really 696 | reason 697 | receive 698 | recent 699 | recently 700 | recognize 701 | record 702 | red 703 | reduce 704 | reflect 705 | region 706 | relate 707 | relationship 708 | religious 709 | remain 710 | remember 711 | remove 712 | report 713 | represent 714 | republican 715 | require 716 | research 717 | resource 718 | respond 719 | response 720 | responsibility 721 | rest 722 | result 723 | return 724 | reveal 725 | rich 726 | right 727 | rise 728 | risk 729 | road 730 | rock 731 | role 732 | room 733 | rule 734 | run 735 | safe 736 | same 737 | save 738 | say 739 | scene 740 | school 741 | science 742 | scientist 743 | score 744 | sea 745 | season 746 | seat 747 | second 748 | section 749 | security 750 | see 751 | seek 752 | seem 753 | sell 754 | send 755 | senior 756 | sense 757 | series 758 | serious 759 | serve 760 | service 761 | set 762 | seven 763 | several 764 | sex 765 | sexual 766 | shake 767 | share 768 | she 769 | shoot 770 | short 771 | shot 772 | should 773 | shoulder 774 | show 775 | side 776 | sign 777 | significant 778 | similar 779 | simple 780 | simply 781 | since 782 | sing 783 | single 784 | sister 785 | sit 786 | site 787 | situation 788 | six 789 | size 790 | skill 791 | skin 792 | small 793 | smile 794 | so 795 | social 796 | society 797 | soldier 798 | some 799 | somebody 800 | someone 801 | something 802 | sometimes 803 | son 804 | song 805 | soon 806 | sort 807 | sound 808 | source 809 | south 810 | southern 811 | space 812 | speak 813 | special 814 | specific 815 | speech 816 | spend 817 | sport 818 | spring 819 | staff 820 | stage 821 | stand 822 | standard 823 | star 824 | start 825 | state 826 | statement 827 | station 828 | stay 829 | step 830 | still 831 | stock 832 | stop 833 | store 834 | story 835 | strategy 836 | street 837 | strong 838 | structure 839 | student 840 | study 841 | stuff 842 | style 843 | subject 844 | success 845 | successful 846 | such 847 | suddenly 848 | suffer 849 | suggest 850 | summer 851 | support 852 | sure 853 | surface 854 | system 855 | table 856 | take 857 | talk 858 | task 859 | tax 860 | teach 861 | teacher 862 | team 863 | technology 864 | television 865 | tell 866 | ten 867 | tend 868 | term 869 | test 870 | than 871 | thank 872 | that 873 | the 874 | their 875 | them 876 | themselves 877 | then 878 | theory 879 | there 880 | these 881 | they 882 | thing 883 | think 884 | third 885 | this 886 | those 887 | though 888 | thought 889 | thousand 890 | threat 891 | three 892 | through 893 | throughout 894 | throw 895 | thus 896 | time 897 | to 898 | today 899 | together 900 | tonight 901 | too 902 | top 903 | total 904 | tough 905 | toward 906 | town 907 | trade 908 | traditional 909 | training 910 | travel 911 | treat 912 | treatment 913 | tree 914 | trial 915 | trip 916 | trouble 917 | true 918 | truth 919 | try 920 | turn 921 | tv 922 | two 923 | type 924 | under 925 | understand 926 | unit 927 | until 928 | up 929 | upon 930 | us 931 | use 932 | usually 933 | value 934 | various 935 | very 936 | victim 937 | view 938 | violence 939 | visit 940 | voice 941 | vote 942 | wait 943 | walk 944 | wall 945 | want 946 | war 947 | watch 948 | water 949 | way 950 | we 951 | weapon 952 | wear 953 | week 954 | weight 955 | well 956 | west 957 | western 958 | what 959 | whatever 960 | when 961 | where 962 | whether 963 | which 964 | while 965 | white 966 | who 967 | whole 968 | whom 969 | whose 970 | why 971 | wide 972 | wife 973 | will 974 | win 975 | wind 976 | window 977 | wish 978 | with 979 | within 980 | without 981 | woman 982 | wonder 983 | word 984 | work 985 | worker 986 | world 987 | worry 988 | would 989 | write 990 | writer 991 | wrong 992 | yard 993 | yeah 994 | year 995 | yes 996 | yet 997 | you 998 | young 999 | your 1000 | yourself -------------------------------------------------------------------------------- /Resources/WordListTop1000.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9af0a6ab951af49adb88cce244eb9cfe 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Resources/WordListTop3000.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: beee24b5617e54d8887d41ef4a87c8d8 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Resources/WordListTop6000.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 396deed7b240a4c43ae096f974fcf35a 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Example Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d1ce3a6bf2a84b39aff4c58931a2f33 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9d117154805d484fa51ef452c21c3d2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 490eb966a3e8e074daaa45a67337a792 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/CurvedWeightedTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class CurvedWeightedTest : MonoBehaviour 6 | { 7 | public List weightedTransforms; 8 | public AnimationCurve weightCurve; 9 | 10 | private Wrj.WeightedElements weightedElements; 11 | // Start is called before the first frame update 12 | void Start() 13 | { 14 | weightedElements = new Wrj.WeightedElements(weightedTransforms, weightCurve); 15 | StartCoroutine(testRandomLoop()); 16 | } 17 | 18 | // Update is called once per frame 19 | void Update() 20 | { 21 | 22 | } 23 | IEnumerator testRandomLoop() 24 | { 25 | while (true) 26 | { 27 | Transform affected = weightedElements.GetRandom(true); 28 | float initY = affected.localScale.y; 29 | Vector3 targetScale = affected.localScale.With(y: initY + .1f); 30 | Wrj.Utils.MapToCurve.Ease.Scale(affected, targetScale, .1f); 31 | Wrj.Utils.MapToCurve.Ease.Move(affected, affected.LocalPosInDir(up: .05f), .1f); 32 | Wrj.Utils.MapToCurve.Ease.ChangeColor(affected, Color.Lerp(Color.white, Color.black, (initY - 1) / 10), .1f); 33 | yield return new WaitForSecondsRealtime(.1f); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/CurvedWeightedTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e67bf557f0d98b4b9e60b90e27ca003 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/PathFollowTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class PathFollowTest : MonoBehaviour { 6 | public float speed = 5; 7 | public Wrj.BezierPath[] paths; 8 | public TrailRenderer trail; 9 | private int pathIndex = 0; 10 | // Use this for initialization 11 | void Start () { 12 | StartCoroutine(RunPathDelayed(1f)); 13 | } 14 | void RunPath() 15 | { 16 | if (pathIndex < paths.Length) 17 | { 18 | trail.transform.parent = null; 19 | Vector3 look = Vector3.zero; 20 | transform.position = paths[pathIndex].GetPointOnCurve(0, ref look); 21 | trail = Instantiate(trail.gameObject, transform).GetComponent(); 22 | trail.transform.localPosition = Vector3.zero; 23 | Wrj.Utils.MapToCurve.Ease.MoveAlongPath(transform, paths[pathIndex], speed * paths[pathIndex].GetCurveLength(), onDone: RunPath); 24 | pathIndex++; 25 | } 26 | } 27 | 28 | IEnumerator RunPathDelayed(float delay) 29 | { 30 | yield return new WaitForSecondsRealtime(delay); 31 | RunPath(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/PathFollowTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88b6051295e961240a00d06f1d9a95f9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Wrj 7 | { 8 | public class Test : MonoBehaviour 9 | { 10 | public float duration = 3; 11 | public bool testStop; 12 | public Transform linTransform; 13 | public Transform easeOutTransform; 14 | public Transform easeInTransform; 15 | public Transform easeTransform; 16 | public Transform targetTransform; 17 | public AnimationCurve scaleCurve; 18 | public Transform curveScaleTransform; 19 | public GameObject recursiveTestGO; 20 | public Transform weight10; 21 | public Transform weight5; 22 | public Transform weight3; 23 | public Transform weight1; 24 | public AudioPool audioPool; 25 | public AudioClip[] audioClips; 26 | private WeightedElements randomBumpObjects = new WeightedElements(); 27 | void Start() 28 | { 29 | randomBumpObjects.Add(weight10, 10); 30 | randomBumpObjects.Add(weight5, 5); 31 | randomBumpObjects.Add(weight3, 3); 32 | randomBumpObjects.Add(weight1, 1); 33 | 34 | Utils.MapToCurve.Linear.MoveWorld(linTransform, linTransform.PosInWorldDir(up: 5f, right: -1.5f), duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 35 | Utils.MapToCurve.EaseIn.MoveWorld(easeInTransform, easeInTransform.PosInWorldDir(up: 5f, right: .5f), duration, mirrorCurve: false, repeatStyle: RepeatStyle.PingPong, iterations: -1); 36 | Utils.MapToCurve.EaseIn.MoveWorld(easeOutTransform, easeOutTransform.PosInWorldDir(up: 5f, right: -.5f), duration, mirrorCurve: true, repeatStyle: RepeatStyle.PingPong, iterations: -1); 37 | Utils.MapToCurve.Ease.MatchSibling(easeTransform, targetTransform, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 38 | 39 | Utils.MapToCurve.Linear.Rotate(linTransform, Vector3.up * 135, duration, shortestPath: false, repeatStyle: RepeatStyle.PingPong, iterations: -1); 40 | Utils.MapToCurve.EaseIn.Rotate(easeInTransform, Vector3.up * -360, duration, shortestPath: false, repeatStyle: RepeatStyle.PingPong, iterations: -1); 41 | Utils.MapToCurve.EaseIn.Rotate(easeOutTransform, Vector3.forward * -720, duration, shortestPath: false, repeatStyle: RepeatStyle.PingPong, iterations: 10); 42 | 43 | Utils.MapToCurve.Ease.ChangeColor(linTransform, Color.black, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 44 | Utils.MapToCurve.Ease.ChangeColor(easeInTransform, Color.red, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 45 | Utils.MapToCurve.Ease.ChangeColor(easeOutTransform, Color.blue, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 46 | Utils.MapToCurve.Ease.ChangeColor(easeTransform, Color.magenta, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 47 | 48 | Utils.MapToCurve.Ease.FadeAlpha(targetTransform, 0, duration, repeatStyle: RepeatStyle.PingPong, iterations: -1); 49 | 50 | Utils.MapToCurve myCurve = new Utils.MapToCurve(scaleCurve); 51 | myCurve.Scale(curveScaleTransform, curveScaleTransform.localScale * .5f, duration * .5f, repeatStyle: RepeatStyle.PingPong, iterations: 5); 52 | 53 | StartCoroutine(testRandomLoop()); 54 | recursiveTestGO.PerChild(SetLayer); 55 | 56 | if (testStop) 57 | StartCoroutine(StopTest()); 58 | 59 | } 60 | 61 | private void SetLayer(GameObject go) 62 | { 63 | go.layer = LayerMask.NameToLayer("TransparentFX"); 64 | } 65 | 66 | IEnumerator testRandomLoop() 67 | { 68 | while (true) 69 | { 70 | Transform affected = randomBumpObjects.GetRandom(true); 71 | float initY = affected.localScale.y; 72 | Vector3 targetScale = new Vector3(1, initY + .1f, 1); 73 | Utils.MapToCurve.Ease.Scale(affected, targetScale, .1f); 74 | Utils.MapToCurve.Ease.Move(affected, affected.LocalPosInDir(up: .05f), .1f); 75 | Utils.MapToCurve.Ease.ChangeColor(affected, Color.Lerp(Color.white, Color.black, (initY - 1) / 10), .1f); 76 | yield return new WaitForSecondsRealtime(.25f); 77 | } 78 | } 79 | IEnumerator StopTest() 80 | { 81 | yield return new WaitForSecondsRealtime(1); 82 | Utils.MapToCurve.StopAllOnTransform(curveScaleTransform); 83 | yield return new WaitForSecondsRealtime(2); 84 | Utils.MapToCurve.StopAll(); 85 | } 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Scripts/Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1284394bf3ae87a43a21640db502e284 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Smile.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Smile 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 2800000, guid: 3c1c48f3c7b97ac49b818149b7a17639, type: 3} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/Smile.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91c98125e660a644fa05b6a0fb092e22 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/TrailMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: TrailMaterial 10 | m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _InvFade: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} 79 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/TrailMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66702453f57b35e478f8654eabcd37a2 3 | timeCreated: 1546576458 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/click1.ogg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click1.ogg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92d77a0f003d76847993d99052f00e14 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/click2.ogg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click2.ogg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf3d0076c7eaf754dbb9f397e681211b 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/click3.ogg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click3.ogg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e3207bcac53c3f40a9e99de0653b5c6 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/click4.ogg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click4.ogg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d049c2c313a92847a9086dcb2d6816f 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/click5.ogg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/click5.ogg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90ada717f6dd2714e99837901550435c 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/smile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/Assets/smile.jpg -------------------------------------------------------------------------------- /Samples~/Example Scenes/Assets/smile.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c1c48f3c7b97ac49b818149b7a17639 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c8b17a957952e1488405769a4481e05 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10641a886892b0a4cac6f2bbd3f69074 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath/LightingData.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/CurvePath/LightingData.asset -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath/LightingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72b656d58f6e1d441bca5e74b938a23a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 112000000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath/ReflectionProbe-0.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/CurvePath/ReflectionProbe-0.exr -------------------------------------------------------------------------------- /Samples~/Example Scenes/CurvePath/ReflectionProbe-0.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a35b162f011530b44b52854eeb62f007 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 13 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 1 32 | seamlessCubemap: 1 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 2 38 | aniso: 0 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 1 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 0 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 0 56 | spriteTessellationDetail: -1 57 | textureType: 0 58 | textureShape: 2 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 4 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 100 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 4 84 | buildTarget: Standalone 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | spriteSheet: 97 | serializedVersion: 2 98 | sprites: [] 99 | outline: [] 100 | customData: 101 | physicsShape: [] 102 | bones: [] 103 | spriteID: 104 | internalID: 0 105 | vertices: [] 106 | indices: 107 | edges: [] 108 | weights: [] 109 | secondaryTextures: [] 110 | spriteCustomMetadata: 111 | entries: [] 112 | nameFileIdTable: {} 113 | mipmapLimitGroupName: 114 | pSDRemoveMatte: 0 115 | userData: 116 | assetBundleName: 117 | assetBundleVariant: 118 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fdf730cc7a1fde4a9a6811e5ccd47d0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51386c4e2162a304dba2e5a24e64edbc 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene/LightingData.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/ExampleScene/LightingData.asset -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene/LightingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98c1fa14d9dd97641bc9538cb3ed146b 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 112000000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene/ReflectionProbe-0.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Samples~/Example Scenes/ExampleScene/ReflectionProbe-0.exr -------------------------------------------------------------------------------- /Samples~/Example Scenes/ExampleScene/ReflectionProbe-0.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f638e393a2206c4ca24577ff66943b8 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 13 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 1 32 | seamlessCubemap: 1 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 2 38 | aniso: 0 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 1 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 0 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 0 56 | spriteTessellationDetail: -1 57 | textureType: 0 58 | textureShape: 2 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 4 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 100 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 4 84 | buildTarget: Standalone 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | spriteSheet: 97 | serializedVersion: 2 98 | sprites: [] 99 | outline: [] 100 | customData: 101 | physicsShape: [] 102 | bones: [] 103 | spriteID: 104 | internalID: 0 105 | vertices: [] 106 | indices: 107 | edges: [] 108 | weights: [] 109 | secondaryTextures: [] 110 | spriteCustomMetadata: 111 | entries: [] 112 | nameFileIdTable: {} 113 | mipmapLimitGroupName: 114 | pSDRemoveMatte: 0 115 | userData: 116 | assetBundleName: 117 | assetBundleVariant: 118 | -------------------------------------------------------------------------------- /Samples~/Presets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3601c2a6eec9401469ab2bac244327fa 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5c7f76428ee27a24c88bd69468f1cf9a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor/EasingCurves.curves.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28c61fb172892154d86112266d130bf1 3 | timeCreated: 1566031707 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: -1 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor/Modern.colors: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 52 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 12323, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: Modern 14 | m_EditorClassIdentifier: 15 | m_Presets: 16 | - m_Name: Red 17 | m_Color: {r: 0.8470589, g: 0.1137255, b: 0.15686275, a: 1} 18 | - m_Name: Green 19 | m_Color: {r: 0.2392157, g: 0.5647059, b: 0.23529413, a: 1} 20 | - m_Name: Black 21 | m_Color: {r: 0.1764706, g: 0.1764706, b: 0.1764706, a: 1} 22 | - m_Name: BlackBlue 23 | m_Color: {r: 0.058823533, g: 0.16862746, b: 0.21568629, a: 1} 24 | - m_Name: BlackPurple 25 | m_Color: {r: 0.20000002, g: 0.07058824, b: 0.1764706, a: 1} 26 | - m_Name: White 27 | m_Color: {r: 0.9921569, g: 0.98823535, b: 0.98823535, a: 1} 28 | - m_Name: Gray 29 | m_Color: {r: 0.5882353, g: 0.5882353, b: 0.5882353, a: 1} 30 | - m_Name: GrayDark 31 | m_Color: {r: 0.34117648, g: 0.34117648, b: 0.34117648, a: 1} 32 | - m_Name: Orange 33 | m_Color: {r: 0.8431373, g: 0.70980394, b: 0.36862746, a: 1} 34 | - m_Name: OrangeDark 35 | m_Color: {r: 0.9490197, g: 0.5803922, b: 0, a: 1} 36 | - m_Name: Sky 37 | m_Color: {r: 0, g: 0.6431373, b: 0.9215687, a: 1} 38 | - m_Name: Cyan 39 | m_Color: {r: 0.06666667, g: 0.63529414, b: 0.627451, a: 1} 40 | - m_Name: CyanDark 41 | m_Color: {r: 0.24705884, g: 0.3254902, b: 0.3647059, a: 1} 42 | - m_Name: Purple 43 | m_Color: {r: 0.62352943, g: 0.3254902, b: 0.48627454, a: 1} 44 | - m_Name: PurpleDark 45 | m_Color: {r: 0.3372549, g: 0.19215688, b: 0.32156864, a: 1} 46 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor/Modern.colors.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b49bbb322e3bbe4da1dc0ee4daf8d7a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor/UIColors.colors: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 52 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 12323, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: UIColors 14 | m_EditorClassIdentifier: 15 | m_Presets: 16 | - m_Name: Turquoise 17 | m_Color: {r: 0.101960786, g: 0.7372549, b: 0.6117647, a: 1} 18 | - m_Name: GreenSea 19 | m_Color: {r: 0.08627451, g: 0.627451, b: 0.52156866, a: 1} 20 | - m_Name: Emerald 21 | m_Color: {r: 0.18039216, g: 0.8, b: 0.44313726, a: 1} 22 | - m_Name: Nephritis 23 | m_Color: {r: 0.15294118, g: 0.68235296, b: 0.3764706, a: 1} 24 | - m_Name: PeterRiver 25 | m_Color: {r: 0.20392157, g: 0.59607846, b: 0.85882354, a: 1} 26 | - m_Name: BelizeHole 27 | m_Color: {r: 0.16078432, g: 0.5019608, b: 0.7254902, a: 1} 28 | - m_Name: WetAsphalt 29 | m_Color: {r: 0.20392157, g: 0.28627452, b: 0.36862746, a: 1} 30 | - m_Name: MidnightBlue 31 | m_Color: {r: 0.17254902, g: 0.24313726, b: 0.3137255, a: 1} 32 | - m_Name: SoftPink 33 | m_Color: {r: 0.9176471, g: 0.29803923, b: 0.53333336, a: 1} 34 | - m_Name: StrongPink 35 | m_Color: {r: 0.79215693, g: 0.17254902, b: 0.40784317, a: 1} 36 | - m_Name: Amethyst 37 | m_Color: {r: 0.60784316, g: 0.34901962, b: 0.7137255, a: 1} 38 | - m_Name: Wisteria 39 | m_Color: {r: 0.5568628, g: 0.26666668, b: 0.6784314, a: 1} 40 | - m_Name: SunFlower 41 | m_Color: {r: 0.94509804, g: 0.76862746, b: 0.05882353, a: 1} 42 | - m_Name: Orange 43 | m_Color: {r: 0.9529412, g: 0.6117647, b: 0.07058824, a: 1} 44 | - m_Name: Carrot 45 | m_Color: {r: 0.9019608, g: 0.49411765, b: 0.13333334, a: 1} 46 | - m_Name: Alizarin 47 | m_Color: {r: 0.90588236, g: 0.29803923, b: 0.23529412, a: 1} 48 | - m_Name: Pomegranate 49 | m_Color: {r: 0.7529412, g: 0.22352941, b: 0.16862746, a: 1} 50 | - m_Name: Clouds 51 | m_Color: {r: 0.9254902, g: 0.9411765, b: 0.94509804, a: 1} 52 | - m_Name: Silver 53 | m_Color: {r: 0.7411765, g: 0.7647059, b: 0.78039217, a: 1} 54 | - m_Name: Concrete 55 | m_Color: {r: 0.58431375, g: 0.64705884, b: 0.6509804, a: 1} 56 | - m_Name: Asbestos 57 | m_Color: {r: 0.49803922, g: 0.54901963, b: 0.5529412, a: 1} 58 | -------------------------------------------------------------------------------- /Samples~/Presets/Editor/UIColors.colors.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c12f81d48f319f04aa03c636b9737c65 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /ScreenBorders.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | [ExecuteInEditMode] 6 | public class ScreenBorders : MonoBehaviour 7 | { 8 | [SerializeField] private ScreenBorder leftBorder; 9 | [SerializeField] private ScreenBorder rightBorder; 10 | [SerializeField] private ScreenBorder ground; 11 | [SerializeField] private ScreenBorder ceiling; 12 | 13 | void Start() 14 | { 15 | if (Application.isPlaying) 16 | { 17 | Wrj.ScreenSizeNotifier.Instance.OnScreenChangeWorld += SetBorders; 18 | } 19 | } 20 | #if UNITY_EDITOR 21 | void Update() 22 | { 23 | SetBorders(ScreenSizeNotifier.WorldDimensions); 24 | } 25 | #endif 26 | void SetBorders(Vector3 worldDimensions) 27 | { 28 | if (leftBorder.transform != null) 29 | { 30 | leftBorder.transform.localScale = transform.localScale.With(y: worldDimensions.y * 2f); 31 | leftBorder.transform.position = Vector3.zero.With(x: (-worldDimensions.x - (leftBorder.transform.lossyScale.x * .5f)) + leftBorder.offset); 32 | } 33 | 34 | if (rightBorder.transform != null) 35 | { 36 | rightBorder.transform.localScale = transform.localScale.With(y: worldDimensions.y * 2f); 37 | rightBorder.transform.position = Vector3.zero.With(x: (worldDimensions.x + (rightBorder.transform.lossyScale.x * .5f)) + rightBorder.offset); 38 | } 39 | 40 | if (ground.transform != null) 41 | { 42 | ground.transform.localScale = transform.localScale.With(x: worldDimensions.x * 2f); 43 | ground.transform.position = Vector3.zero.With(y: (-worldDimensions.y - (ground.transform.lossyScale.y * .5f)) + ground.offset); 44 | } 45 | 46 | if (ceiling.transform != null) 47 | { 48 | ceiling.transform.localScale = transform.localScale.With(x: worldDimensions.x * 2f); 49 | ceiling.transform.position = Vector3.zero.With(y: (worldDimensions.y + (ceiling.transform.lossyScale.y * .5f)) + ceiling.offset); 50 | } 51 | } 52 | 53 | [System.Serializable] 54 | protected class ScreenBorder 55 | { 56 | public Transform transform; 57 | public float offset; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ScreenBorders.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b88cf25294e2245a787fa5473fb94769 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /ScreenSizeNotifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | public class ScreenSizeNotifier : MonoBehaviour 6 | { 7 | public delegate void ScreenChangeWorldDelegate(Vector3 worldDimensions); 8 | public delegate void ScreenChangeDelegate(Vector2 screenDimensions); 9 | public delegate void ChangeDelegate(); 10 | public ScreenChangeWorldDelegate OnScreenChangeWorld; 11 | public ScreenChangeDelegate OnScreenChange; 12 | public ChangeDelegate OnChange; 13 | 14 | private int initialWidth; 15 | private int initialHeight; 16 | private int updatedWidth; 17 | private int updatedHeight; 18 | private Camera mainCamera; 19 | public static Vector3 ScreenDimensions => new Vector2(Screen.width, Screen.height); 20 | public static Vector3 WorldDimensions 21 | { 22 | get 23 | { 24 | if (!Application.isPlaying) 25 | { 26 | return Camera.main.ScreenToWorldPoint(ScreenDimensions); 27 | } 28 | else 29 | { 30 | return Instance.mainCamera.ScreenToWorldPoint(ScreenDimensions); 31 | } 32 | } 33 | } 34 | 35 | /// Static Singleton behavior 36 | protected static ScreenSizeNotifier _instance; 37 | public static ScreenSizeNotifier Instance 38 | { 39 | get 40 | { 41 | return _instance; 42 | } 43 | } 44 | void Awake () 45 | { 46 | if (_instance == null) 47 | { 48 | mainCamera = Camera.main; 49 | _instance = this; 50 | DontDestroyOnLoad(gameObject); 51 | } 52 | else 53 | { 54 | Destroy(this); 55 | } 56 | } 57 | 58 | void Start() 59 | { 60 | updatedHeight = Screen.height; 61 | updatedWidth = Screen.width; 62 | } 63 | 64 | void Update() 65 | { 66 | updatedHeight = Screen.height; 67 | updatedWidth = Screen.width; 68 | 69 | if ((initialHeight != updatedHeight) || (initialWidth != updatedWidth)) 70 | { 71 | initialHeight = updatedHeight; 72 | initialWidth = updatedWidth; 73 | Notify(); 74 | } 75 | } 76 | 77 | void Notify() 78 | { 79 | if (OnScreenChangeWorld != null) 80 | { 81 | OnScreenChangeWorld(WorldDimensions); 82 | } 83 | if (OnScreenChange != null) 84 | { 85 | OnScreenChange(ScreenDimensions); 86 | } 87 | if (OnChange != null) 88 | { 89 | OnChange(); 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /ScreenSizeNotifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62f2c994a209c4fbeada3c2d12e69dd0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /ShowHideGroup.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | [RequireComponent(typeof(CanvasGroup))] 4 | public class ShowHideGroup : MonoBehaviour 5 | { 6 | [SerializeField] 7 | private float fadeTime = 1f; 8 | [SerializeField] 9 | private bool stateOnAwake; 10 | private CanvasGroup _group; 11 | private bool _isVisible; 12 | 13 | private void Awake() 14 | { 15 | _group = GetComponent(); 16 | _isVisible = stateOnAwake; 17 | _group.alpha = stateOnAwake ? 1f : 0f; 18 | } 19 | 20 | public void On() 21 | { 22 | if (_isVisible) return; 23 | _isVisible = true; 24 | _group.interactable = true; 25 | _group.blocksRaycasts = true; 26 | Wrj.Utils.MapToCurve.Linear.FadeAlpha(_group, 1f, fadeTime); 27 | } 28 | public void Off() 29 | { 30 | if (!_isVisible) return; 31 | _isVisible = false; 32 | _group.interactable = false; 33 | _group.blocksRaycasts = false; 34 | Wrj.Utils.MapToCurve.Linear.FadeAlpha(_group, 0f, fadeTime); 35 | } 36 | public void Toggle() 37 | { 38 | if (_isVisible) 39 | { 40 | Off(); 41 | } 42 | else 43 | { 44 | On(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ShowHideGroup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d599b38e5bbb4094a3d865c47f54c9c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/Smile.gif -------------------------------------------------------------------------------- /Smile.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 445be6c49356f4079ab2404e368af38b 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMasterTextureLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 1 67 | swizzle: 50462976 68 | cookieLightType: 1 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 1 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 1 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 1 106 | - serializedVersion: 3 107 | buildTarget: iPhone 108 | maxTextureSize: 2048 109 | resizeAlgorithm: 0 110 | textureFormat: -1 111 | textureCompression: 1 112 | compressionQuality: 50 113 | crunchedCompression: 0 114 | allowsAlphaSplitting: 0 115 | overridden: 0 116 | androidETC2FallbackOverride: 0 117 | forceMaximumCompressionQuality_BC6H_BC7: 1 118 | spriteSheet: 119 | serializedVersion: 2 120 | sprites: [] 121 | outline: [] 122 | physicsShape: [] 123 | bones: [] 124 | spriteID: 25e9e6c43edcfca4db4deaeb4684ec87 125 | internalID: 0 126 | vertices: [] 127 | indices: 128 | edges: [] 129 | weights: [] 130 | secondaryTextures: [] 131 | nameFileIdTable: {} 132 | spritePackingTag: 133 | pSDRemoveMatte: 0 134 | userData: 135 | assetBundleName: 136 | assetBundleVariant: 137 | -------------------------------------------------------------------------------- /SmoothFollow.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Wrj 4 | { 5 | public class SmoothFollow : MonoBehaviour 6 | { 7 | [SerializeField] 8 | private Transform followTarget = null; 9 | [SerializeField] 10 | private float smoothTime = 0.3F; 11 | [SerializeField] 12 | [Range(0f, 1f)] 13 | private float distanceThreshold = .1f; 14 | 15 | private Vector3 offset; 16 | private Vector3 velocity = Vector3.zero; 17 | 18 | public Transform Target => followTarget; 19 | 20 | void Start() 21 | { 22 | offset = transform.position - followTarget.position; 23 | } 24 | 25 | void LateUpdate() 26 | { 27 | Vector3 targetPosition = followTarget.position + offset; 28 | if (Vector3.Distance(transform.position, targetPosition) > distanceThreshold) 29 | { 30 | transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /SmoothFollow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da6c099a7332b48ed8f1fba402df825b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /TweenExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamrjackson/UnityScriptingUtilities/a5df860e6ada7c2379cd35fcaa2a9d7fb8e57d6b/TweenExample.gif -------------------------------------------------------------------------------- /TweenExample.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd22117d5375a4fd0bc3238e1729aae6 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMasterTextureLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 1 67 | swizzle: 50462976 68 | cookieLightType: 1 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 1 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 1 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 1 106 | - serializedVersion: 3 107 | buildTarget: iPhone 108 | maxTextureSize: 2048 109 | resizeAlgorithm: 0 110 | textureFormat: -1 111 | textureCompression: 1 112 | compressionQuality: 50 113 | crunchedCompression: 0 114 | allowsAlphaSplitting: 0 115 | overridden: 0 116 | androidETC2FallbackOverride: 0 117 | forceMaximumCompressionQuality_BC6H_BC7: 1 118 | spriteSheet: 119 | serializedVersion: 2 120 | sprites: [] 121 | outline: [] 122 | physicsShape: [] 123 | bones: [] 124 | spriteID: 487162274816a26478c6fc867f0c91e3 125 | internalID: 0 126 | vertices: [] 127 | indices: 128 | edges: [] 129 | weights: [] 130 | secondaryTextures: [] 131 | nameFileIdTable: {} 132 | spritePackingTag: 133 | pSDRemoveMatte: 0 134 | userData: 135 | assetBundleName: 136 | assetBundleVariant: 137 | -------------------------------------------------------------------------------- /WeightedElements.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Wrj 5 | { 6 | [System.Serializable] 7 | public class WeightedElements 8 | { 9 | private List objectList = new List(); 10 | private List availableIndices = new List(); 11 | 12 | private int m_LastSelectedIndex = -1; 13 | 14 | /// 15 | /// Returns a random element from the list where objects with higher weights are more likely 16 | /// 17 | public T GetRandom(bool preventImmediateRepeat = false) 18 | { 19 | if (objectList == null || objectList.Count == 0) return default(T); 20 | if (objectList.Count < 2) return objectList[0].element; 21 | 22 | int weightedRandomIndex = m_LastSelectedIndex; 23 | int iterationCount = 0; 24 | while (weightedRandomIndex == m_LastSelectedIndex && iterationCount < (availableIndices.Count * 2)) 25 | { 26 | weightedRandomIndex = availableIndices[Random.Range(0, availableIndices.Count)]; 27 | if (!preventImmediateRepeat) break; 28 | } 29 | 30 | m_LastSelectedIndex = weightedRandomIndex; 31 | 32 | return objectList[weightedRandomIndex].element; 33 | } 34 | public void Add(T element, int weight) 35 | { 36 | WeightedElement newElement = new WeightedElement(element, weight); 37 | objectList.Add(newElement); 38 | int index = objectList.IndexOf(newElement); 39 | for (int i = 0; i < weight; i++) 40 | { 41 | availableIndices.Add(index); 42 | } 43 | } 44 | public void Remove(T element) 45 | { 46 | foreach (var item in objectList) 47 | { 48 | if (EqualityComparer.Default.Equals(item.element, element)) 49 | { 50 | objectList.Remove(item); 51 | return; 52 | } 53 | } 54 | availableIndices.Clear(); 55 | for (int i = 0; i < objectList.Count; i++) 56 | { 57 | for (int j = 0; j < objectList[i].weight; j++) 58 | { 59 | availableIndices.Add(i); 60 | } 61 | } 62 | } 63 | public void Clear() 64 | { 65 | objectList.Clear(); 66 | availableIndices.Clear(); 67 | } 68 | public int Count 69 | { 70 | get 71 | { 72 | return objectList.Count; 73 | } 74 | } 75 | 76 | public void ApplyLinearWeights(List source, bool invert = false) 77 | { 78 | for (int i = 0; i < source.Count; i++) 79 | { 80 | if (invert) 81 | { 82 | Add(source[i], source.Count - i); 83 | } 84 | else 85 | { 86 | Add(source[i], i + 1); 87 | } 88 | } 89 | } 90 | public void ApplyCurveWeights(List source, AnimationCurve curve, bool invert = false) 91 | { 92 | for (int i = 0; i < source.Count; i++) 93 | { 94 | float curveVal = 0f; 95 | if (invert) 96 | { 97 | curveVal = curve.Evaluate(Utils.Remap((float)i, 0f, (float)source.Count, 1f, 0f)); 98 | } 99 | else 100 | { 101 | curveVal = curve.Evaluate(Utils.Remap((float)i, 0f, (float)source.Count, 0f, 1f)); 102 | } 103 | 104 | int weight = Mathf.RoundToInt(curveVal * 100f); 105 | 106 | Add(source[i], Mathf.Max(1, weight)); 107 | } 108 | } 109 | 110 | public WeightedElements() { } 111 | public WeightedElements (List source, AnimationCurve curve, bool invert=false) 112 | { 113 | Clear(); 114 | ApplyCurveWeights(source, curve, invert); 115 | } 116 | public WeightedElements (List source, bool invert=false) 117 | { 118 | Clear(); 119 | ApplyLinearWeights(source, invert); 120 | } 121 | 122 | [System.Serializable] 123 | private class WeightedElement 124 | { 125 | public T element; 126 | public int weight; 127 | 128 | public WeightedElement(T element, int weight) 129 | { 130 | this.element = element; 131 | this.weight = weight; 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /WeightedElements.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0af5e367cb2b4c1c85d91ebd0af0772 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WordList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEngine; 6 | 7 | namespace Wrj 8 | { 9 | public class WordList : MonoBehaviour 10 | { 11 | private HashSet wordSet; 12 | private HashSet fullWordSet; 13 | public enum WordSource { Full, Common6000, Common3000, Common1000 } 14 | private WordSource wordSource = WordSource.Full; 15 | 16 | private static WordList _instance; 17 | public static WordList Instance 18 | { 19 | get 20 | { 21 | if (_instance == null) 22 | { 23 | GameObject go = new GameObject(); 24 | go.name = "WordList"; 25 | _instance = go.AddComponent(); 26 | } 27 | return _instance; 28 | } 29 | } 30 | public HashSet WordSet 31 | { 32 | get 33 | { 34 | if (wordSource == WordSource.Full) 35 | { 36 | return fullWordSet; 37 | } 38 | return wordSet; 39 | } 40 | } 41 | private void Awake() 42 | { 43 | if (_instance == null) 44 | { 45 | _instance = this; 46 | Init(wordSource); 47 | } 48 | } 49 | 50 | public void Init(TextAsset wordListTextAsset) 51 | { 52 | wordSet = new HashSet(wordListTextAsset.text.Split("\n"[0])); 53 | TextAsset fullDictionaryTextAsset = Resources.Load("WordList", typeof(TextAsset)) as TextAsset; 54 | fullWordSet = new HashSet(fullDictionaryTextAsset.text.Split("\n"[0])); 55 | } 56 | public void Init(TextAsset wordListTextAsset, TextAsset fullDictionaryTextAsset) 57 | { 58 | wordSet = new HashSet(wordListTextAsset.text.Split("\n"[0])); 59 | fullWordSet = new HashSet(fullDictionaryTextAsset.text.Split("\n"[0])); 60 | } 61 | public void Init(WordSource wordSource) 62 | { 63 | string strWordResourceName = "WordList"; 64 | switch (wordSource) 65 | { 66 | case WordSource.Common6000: 67 | strWordResourceName = "WordListTop6000"; 68 | break; 69 | case WordSource.Common3000: 70 | strWordResourceName = "WordListTop3000"; 71 | break; 72 | case WordSource.Common1000: 73 | strWordResourceName = "WordListTop1000"; 74 | break; 75 | default: 76 | strWordResourceName = "WordList"; 77 | break; 78 | } 79 | TextAsset fullDictionaryTextAsset = Resources.Load("WordList", typeof(TextAsset)) as TextAsset; 80 | fullWordSet = new HashSet(fullDictionaryTextAsset.text.Split("\n"[0])); 81 | if (wordSource != WordSource.Full) 82 | { 83 | TextAsset wordListTextAsset = Resources.Load(strWordResourceName, typeof(TextAsset)) as TextAsset; 84 | wordSet = new HashSet(wordListTextAsset.text.Split("\n"[0])); 85 | } 86 | } 87 | 88 | public static bool CheckWord(string word, bool fullDict = true) 89 | { 90 | if (fullDict) 91 | { 92 | return Instance.fullWordSet.Contains(word.ToLower()); 93 | } 94 | return Instance.WordSet.Contains(word.ToLower()); 95 | } 96 | public static List GetPossibleWords(string chars, int minLength = 3, int maxLength = 7, bool fullDict = false) 97 | { 98 | chars = chars.ToLower(); 99 | List combinations = CharCombinations(chars.ToLower()); 100 | HashSet results = new HashSet(); 101 | foreach (string item in combinations) 102 | { 103 | if (item.Length >= minLength && item.Length <= maxLength && CheckWord(item, fullDict)) 104 | { 105 | results.Add(item.ToUpper()); 106 | } 107 | } 108 | return results.ToList(); 109 | } 110 | public static string RandomWord(bool fullDict = false) 111 | { 112 | List commonList = (fullDict) ? Instance.fullWordSet.ToList() : Instance.WordSet.ToList(); 113 | return commonList.GetRandom(); 114 | } 115 | public static List GetRandomWords(int count, int minLength = 3, int maxLength = 7, bool fullDict = false) 116 | { 117 | List wordSetList = (fullDict) ? Instance.fullWordSet.ToList() : Instance.WordSet.ToList(); 118 | List results = new List(); 119 | 120 | for (int i = 0; i < count; i++) 121 | { 122 | string word = ""; 123 | while (word.Length > maxLength || word.Length < minLength || results.Contains(word)) 124 | { 125 | word = wordSetList.GetRandom(); 126 | } 127 | results.Add(word); 128 | } 129 | return results; 130 | } 131 | public static string WordOfTheDay(bool fullDict = false) 132 | { 133 | List words = (fullDict) ? Instance.fullWordSet.ToList() : Instance.WordSet.ToList(); 134 | DateTime today = DateTime.UtcNow.Date; 135 | Int64 todayInt = today.ToBinary(); 136 | Int64 wordIndex = todayInt % (Int64)words.Count; 137 | int nWordIndex = Mathf.Abs((int)wordIndex); 138 | string wordOtD = words[(int)nWordIndex]; 139 | return wordOtD; 140 | } 141 | 142 | /// http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values 143 | public static List CharCombinations(char[] inputCharArray, int minimumItems = 1, 144 | int maximumItems = int.MaxValue) 145 | { 146 | int nonEmptyCombinations = (int)Mathf.Pow(2, inputCharArray.Length) - 1; 147 | List listOfLists = new List(nonEmptyCombinations + 1); 148 | 149 | // Optimize generation of empty combination, if empty combination is wanted 150 | if (minimumItems == 0) 151 | listOfLists.Add(""); 152 | 153 | if (minimumItems <= 1 && maximumItems >= inputCharArray.Length) 154 | { 155 | // Simple case, generate all possible non-empty combinations 156 | for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++) 157 | listOfLists.Add(GenerateCombination(inputCharArray, bitPattern)); 158 | } 159 | else 160 | { 161 | // Not-so-simple case, avoid generating the unwanted combinations 162 | for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++) 163 | { 164 | int bitCount = CountBits(bitPattern); 165 | if (bitCount >= minimumItems && bitCount <= maximumItems) 166 | listOfLists.Add(GenerateCombination(inputCharArray, bitPattern)); 167 | } 168 | } 169 | 170 | return listOfLists; 171 | } 172 | public static List CharCombinations(string input, int minItems = 1, int maxItems = int.MaxValue) 173 | { 174 | return CharCombinations(input.ToCharArray(), minItems, maxItems); 175 | } 176 | 177 | private static string GenerateCombination(char[] inputList, int bitPattern) 178 | { 179 | string thisCombination = string.Empty;// new List(inputList.Length); 180 | for (int j = 0; j < inputList.Length; j++) 181 | { 182 | if ((bitPattern >> j & 1) == 1) 183 | thisCombination += inputList[j]; 184 | } 185 | return thisCombination; 186 | } 187 | 188 | /// 189 | /// Sub-method of CharCombinations() method to count the bits in a bit pattern. Based on this: 190 | /// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan 191 | /// 192 | private static int CountBits(int bitPattern) 193 | { 194 | int numberBits = 0; 195 | while (bitPattern != 0) 196 | { 197 | numberBits++; 198 | bitPattern &= bitPattern - 1; 199 | } 200 | return numberBits; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /WordList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30f3aa43e8ecc44f5b03349a7b2b48b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WrjUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39b2a75a45fa44550a60e916bc1b9a53 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | {"name":"com.wrj.utils","version":"1.6.16","displayName":"WRJ Utilities","description":"Convenient utils and a simple AnimationCurve-based tweening interface.","unity":"2022.3","unityRelease":"4f1","documentationUrl":"https://github.com/williamrjackson/UnityScriptingUtilities/blob/master/README.md","changelogUrl":"https://github.com/williamrjackson/UnityScriptingUtilities/releases","licensesUrl":"https://github.com/williamrjackson/UnityScriptingUtilities/blob/master/LICENSE","samples":[{"displayName":"Color and Curve Presets","description":"Contains color and curve preset libraries","path":"Samples~/Presets"},{"displayName":"Example Scenes","description":"Contains example scenes demonstrating useage","path":"Samples~/Example Scenes"}],"keywords":["tween","easing","utilities","color"],"author":{"name":"William Jackson","email":"williamrjackson@gmail.com","url":"https://github.com/williamrjackson"}} -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f6fc8f76bdf74d15bcdef9816969f2d 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /wrj.utils.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wrj.utils", 3 | "rootNamespace": "Wrj", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /wrj.utils.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12945d5e37cc9400a9ee189567203346 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------