Last active
August 24, 2020 07:57
-
-
Save DuncanF/81510835a44d767df79551ad9b1907c9 to your computer and use it in GitHub Desktop.
Unity preset handling for use with editor MIDI control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Presets and some editor functionality (screencap that works when not in play mode) in PresetHandling.cs file. | |
MidiControl script utilises Keijiro's MidiJack: https://github.com/keijiro/MidiJack | |
Midi controller (Korg NanoKontrol2) transport buttons mapped to creating new presets, cycling through existing presets and editor play mode handling by the below: | |
void HandleMidi(MidiChannel channel, int knobOrNoteNum, float value) | |
{ | |
foreach (MidiMapping mapping in mappings) | |
{ | |
MidiLearn(mapping, channel, knobOrNoteNum); | |
if ((mapping.channel != channel && mapping.channel != MidiChannel.All) | |
|| mapping.ccNum != knobOrNoteNum) | |
{ | |
continue; | |
} | |
float mappedValue = Mathf.Lerp(mapping.min, mapping.max, value); | |
if (mapping.field.FieldType == typeof(float)) | |
{ | |
mapping.field.SetValue(target, mappedValue); | |
} | |
else if (mapping.field.FieldType == typeof(int)) | |
{ | |
mapping.field.SetValue(target, (int)mappedValue); | |
} | |
else if (mapping.field.FieldType == typeof(bool)) | |
{ | |
// Toggle bool value on button down | |
if (mappedValue > 0.5) | |
{ | |
bool currentVal = (bool)mapping.field.GetValue(target); | |
mapping.field.SetValue(target, !currentVal); | |
} | |
} | |
else | |
{ | |
DebugLog($"Unhandled field type [{mapping.field.FieldType}]"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
using UnityEditor.Presets; | |
using UnityEditor.SceneManagement; | |
public static class PresetHandling | |
{ | |
const string presetExtension = ".preset"; | |
public static int CreatePresetInDatabase(UnityEngine.Object source) | |
{ | |
Preset preset = new Preset(source); | |
string presetPath = FindNextPresetPath(source, out int num); | |
AssetDatabase.CreateAsset(preset, presetPath); | |
SaveScreenshotToPictures(Path.GetFileName(presetPath), true); | |
return num; | |
} | |
public static void SaveScreenshot(string filePath) | |
{ | |
// NB, below doesn't work when not in play mode, and we want to ensure we use screen res as set in display 1 | |
//ScreenCapture.CaptureScreenshot(filename + ".png"); | |
var cam = Camera.main; | |
var renderTexture = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 24); | |
cam.targetTexture = renderTexture; | |
cam.Render(); | |
cam.targetTexture = null; | |
RenderTexture.active = renderTexture; | |
Texture2D screenshot = new Texture2D(cam.pixelWidth, cam.pixelHeight, TextureFormat.RGB24, false); | |
screenshot.ReadPixels(new Rect(0, 0, cam.pixelWidth, cam.pixelHeight), 0, 0); | |
screenshot.Apply(); | |
RenderTexture.active = null; | |
//Encode screenshot to PNG | |
byte[] bytes = screenshot.EncodeToPNG(); | |
UnityEngine.Object.DestroyImmediate(screenshot); | |
string folder = Path.GetDirectoryName(filePath); | |
if (!Directory.Exists(folder)) | |
{ | |
Directory.CreateDirectory(folder); | |
} | |
File.WriteAllBytes(filePath, bytes); | |
} | |
public static void SaveScreenshotToPictures(string filenameNoExtension, bool overwrite = false) | |
{ | |
string targetFolder = Path.Combine( | |
Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), | |
PlayerSettings.productName); | |
string targetFileName = Path.Combine(targetFolder, filenameNoExtension + ".png"); | |
if (!overwrite) | |
{ | |
int screenCapNum = 0; | |
do | |
{ | |
targetFileName = Path.Combine(targetFolder, | |
filenameNoExtension + $"{screenCapNum:000}" + ".png"); | |
++screenCapNum; | |
} | |
while (File.Exists(targetFileName) && screenCapNum < 1000); | |
Debug.Assert(screenCapNum != 1000); | |
} | |
PresetHandling.SaveScreenshot(targetFileName); | |
} | |
[MenuItem("Screencap/TakeScreencap")] | |
static void TakeScreencap() | |
{ | |
string capName = $"Screencap_{EditorSceneManager.GetActiveScene().name}_{DateTime.Now.ToLongTimeString().Replace(':', '_')}"; | |
Debug.Log($"Saving {capName}"); | |
SaveScreenshotToPictures(capName); | |
} | |
private static string FindNextPresetPath(UnityEngine.Object source, out int num) | |
{ | |
string currentScenePath = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().path; | |
string folder = Path.GetDirectoryName(currentScenePath); | |
num = 0; | |
string newPath = PresetPath(source, folder, num); | |
while (File.Exists(newPath)) | |
{ | |
++num; | |
newPath = PresetPath(source, folder, num); | |
} | |
return newPath; | |
} | |
private static string PresetPath(UnityEngine.Object source, string folder, int num) | |
{ | |
string presetsFolder = Path.Combine(folder, "Presets"); | |
if (!Directory.Exists(presetsFolder)) | |
{ | |
Directory.CreateDirectory(presetsFolder); | |
} | |
return Path.Combine(presetsFolder, source.name + $"{num:000}" + presetExtension); | |
} | |
public static bool LoadPreset(UnityEngine.Object target, int presetNumber) | |
{ | |
string currentScenePath = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().path; | |
string folder = Path.GetDirectoryName(currentScenePath); | |
string nextPresetPath = PresetPath(target, folder, presetNumber); | |
if (File.Exists(nextPresetPath)) | |
{ | |
Preset preset = AssetDatabase.LoadAssetAtPath<Preset>(nextPresetPath); | |
if (preset != null && preset.CanBeAppliedTo(target)) | |
{ | |
Debug.Log("Loaded preset " + Path.GetFileName(nextPresetPath)); | |
preset.ApplyTo(target); | |
return true; | |
} | |
else | |
{ | |
Debug.Log("Could not load or apply preset " + nextPresetPath); | |
} | |
} | |
else | |
{ | |
Debug.Log("Could not find " + nextPresetPath); | |
} | |
return false; | |
} | |
public static bool LoadLastPreset(UnityEngine.Object target, out int foundPresetID) | |
{ | |
string nextPath = FindNextPresetPath(target, out int num); | |
foundPresetID = num-1; | |
return LoadPreset(target, foundPresetID); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment