Skip to content

Instantly share code, notes, and snippets.

@yuiwong
Created July 31, 2018 15:19
Show Gist options
  • Save yuiwong/1cd02f69515240ab02152890194549e6 to your computer and use it in GitHub Desktop.
Save yuiwong/1cd02f69515240ab02152890194549e6 to your computer and use it in GitHub Desktop.
random editor scripts, @note: my advise is don't use editor scriptings, garbage shithole in design.
using UnityEditor;
using UnityEngine;
// allow do something before/after playmode
[InitializeOnLoad]
public static class PrePlayOptions
{
static PrePlayOptions()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChange;
EditorApplication.playModeStateChanged += OnPlayModeStateChange;
}
private static void OnPlayModeStateChange(PlayModeStateChange state)
{
if(state == PlayModeStateChange.EnteredPlayMode)
{
UpdateAreaDatas();
}
if (state == PlayModeStateChange.ExitingPlayMode)
{
//if (Tween.isLogCountInfo)
// Debug.Log("Tween max reach to " + Tween.cachedMaxTweenCount);
}
}
private static void UpdateAreaDatas()
{
string path = ResourcePath.assetPath + ResourcePath.resourcesPath + ResourcePath.configPath + ScriptableDataName.AreaConfig;
path += ".asset";
var areaConfig = AssetDatabase.LoadAssetAtPath<ConfigArea>(path);
if (areaConfig == null)
{
Debug.Log("area scriptable obejct is null!");
return;
}
areaConfig.areas = DatabaseManagement.ScanDictionaryFilesForDrunkWalk(false);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.SetDirty(areaConfig);
}
/*
result is ordere as below:
- isPlayingOrWillChangePlaymode = True, isPaused = False, isPlaying = False
when there is error:
- isPlayingOrWillChangePlaymode = True, isPaused = False, isPlaying = True
When exiting
- isPlayingOrWillChangePlaymode = False, isPaused = False, isPlaying = True
- isPlayingOrWillChangePlaymode = False, isPaused = False, isPlaying = False
*/
// @ToDelete: in later version of unity(after 2017.2) use enum "PlayModeStateChange"
private static void TestContent(PlayModeStateChange state)
{
var mode = EditorApplication.isPlayingOrWillChangePlaymode;
var isPaused = EditorApplication.isPaused;
var playing = EditorApplication.isPlaying;
string s = "isPlayingOrWillChangePlaymode = " + mode;
s += ", isPaused = " + isPaused;
s += ", isPlaying = " + playing;
Debug.Log(s);
}
}
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public delegate void LibrarySelectionChanged();
// a library window to select prefabs to use.
[InitializeOnLoad]
public class PropLibrary : EditorWindow
{
private bool isPreviewLoading = true;
public static PropLibrary instance;
private static Vector2 scrollPos;
private static int currentSelectedItemIndex;
private static List<PropCategoryInfo> categorys = new List<PropCategoryInfo>();
private static bool cachedDisplayAllCategory = true;
private static bool currentDisplayAllCategory = true;
private static List<string> levelPropFolderNames = new List<string>();
private static List<string> currentDisplayingItemlist = new List<string>();
private static List<GUIContent> prefabGUIs = new List<GUIContent>();
public static Funv<string> onSelectProp;
/// <summary>
/// only prop name, no path/relative path or .prefab ending.
/// </summary>
public static string selectedPrefabFullDirectoryPath
{
get { return EditorPrefs.GetString("SelectedLevelPrefabPath", "None"); }
set { EditorPrefs.SetString("SelectedLevelPrefabPath", value);}
}
public static string selectedLevelPropName
{
get
{
string name = StringUtils.GetStringAterCharsReversive(selectedPrefabFullDirectoryPath, "/");
name = StringUtils.CutString(name, ".prefab");
return name;
}
}
public static List<string> folderFilterOptionNames
{
get
{
if(levelPropFolderNames == null)
levelPropFolderNames = new List<string>();
if(levelPropFolderNames.Count == 0)
RefreshCategory();
return levelPropFolderNames;
}
}
private static float gridFixedWidth
{
get { return EditorPrefs.GetFloat("LevelPrefabElementWidth", 50f); }
set { EditorPrefs.SetFloat("LevelPrefabElementWidth", value); }
}
private static bool closeWindowWhenSelect
{
get { return EditorPrefs.GetBool("LevelPrefabLibCloseWindowWhenSelect", true); }
set { EditorPrefs.SetBool("LevelPrefabLibCloseWindowWhenSelect", value); }
}
public static void OpenPropLibrary()
{
//RefreshLibraryContent();
instance = EditorWindow.GetWindow<PropLibrary>();
instance.titleContent = new GUIContent("PropLibrary");
instance.Show();
if (ElementSceneViewToolBox.IsCurrentSceneMatch())
{
onSelectProp -= ElementSceneViewToolBox.OnLibrarySelectPrefabPath;
onSelectProp += ElementSceneViewToolBox.OnLibrarySelectPrefabPath;
}
if (AreaSceneTools.IsCurrentSceneMatch())
{
onSelectProp -= AreaSceneTools.OnLibrarySelectPrefabPath;
onSelectProp += AreaSceneTools.OnLibrarySelectPrefabPath;
}
}
public static void CloseLibrary()
{
onSelectProp = null;
if(instance != null)
instance.Close();
}
public static int GetFilterIndexOfGivenPrefabDirectoryPath(string directoryPathOfPrefab)
{
string belongToFolder = ResourceDataHelper.GetFolderNameThatContainsThisFile(directoryPathOfPrefab);
for (int i = 0; i < categorys.Count; i++)
{
if (belongToFolder == categorys[i].categoryName)
{
return i;
}
}
Debug.Log(string.Format("Can't find '{0}' in filter options", belongToFolder));
return 0;
}
public static string GetFolderRelativePathToPropLib(string filterName, string prefabName)
{
return DataPathEditor.propsPath + filterName + "/" + prefabName + DataPathEditor.prefabEnding;
}
private void OnEnable()
{
RefreshCategory();
UpdateCategoryOption();
GatherItemInfosAndCachGUIElements();
}
private void Update()
{
if (isPreviewLoading != AssetPreview.IsLoadingAssetPreviews())
{
isPreviewLoading = AssetPreview.IsLoadingAssetPreviews();
Repaint();
}
}
private void OnGUI()
{
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
GUILayoutOption[] optionsforToggle = new[]
{
GUILayout.MaxWidth(60f),
GUILayout.ExpandWidth(false)
};
currentDisplayAllCategory = EditorGUILayout.ToggleLeft(
new GUIContent("All"), currentDisplayAllCategory, optionsforToggle);
foreach (var filter in categorys)
{
filter.isChecked = EditorGUILayout.ToggleLeft(
new GUIContent(filter.categoryName), filter.isChecked, optionsforToggle);
}
if (EditorGUI.EndChangeCheck())
{
UpdateCategoryOption();
GatherItemInfosAndCachGUIElements();
}
closeWindowWhenSelect = EditorGUILayout.ToggleLeft(new GUIContent("AutoClose"), closeWindowWhenSelect);
gridFixedWidth = GUILayout.HorizontalSlider(gridFixedWidth, 50f, 200f, optionsforToggle);
GUILayout.EndHorizontal();
GUILayoutOption[] options = new GUILayoutOption[] {};
scrollPos = GUILayout.BeginScrollView(scrollPos, options);
GUIStyle style = new GUIStyle(GUI.skin.GetStyle("Button"));
style.imagePosition = ImagePosition.ImageAbove;
style.fixedWidth = gridFixedWidth;
style.fixedHeight = gridFixedWidth + 10f;
int elementCount = Convert.ToInt16(Mathf.Floor(position.width/gridFixedWidth));
GUILayoutOption[] gridButtonOptions =
{
GUILayout.MaxWidth(gridFixedWidth +10f),
GUILayout.MinWidth(gridFixedWidth +5f),
GUILayout.MaxHeight(gridFixedWidth +20f),
GUILayout.MinHeight(gridFixedWidth +10f),
};
EditorGUI.BeginChangeCheck();
currentSelectedItemIndex = GUILayout.SelectionGrid(
currentSelectedItemIndex,
prefabGUIs.ToArray(),
elementCount,
style,
gridButtonOptions
);
selectedPrefabFullDirectoryPath = currentDisplayingItemlist[currentSelectedItemIndex];
// @Note: endChangeCheck will detect correctly even selection grid return the same index. also like GUI.changed.
if (EditorGUI.EndChangeCheck())
{
if (onSelectProp != null)
onSelectProp(selectedPrefabFullDirectoryPath);
if (closeWindowWhenSelect)
CloseLibrary();
}
EditorGUILayout.EndScrollView();
}
private static void RefreshCategory()
{
List<DirectoryInfo> subFolderNames = ResourceDataHelper.GetFolderInfoAtPath(DataPathEditor.propsPath, false);
levelPropFolderNames.Clear();
categorys.Clear();
foreach (var folderDirectoryInfo in subFolderNames)
{
levelPropFolderNames.Add(folderDirectoryInfo.Name);
categorys.Add(new PropCategoryInfo(folderDirectoryInfo.Name, true, folderDirectoryInfo.FullName));
}
}
private static void UpdateCategoryOption()
{
if (cachedDisplayAllCategory != currentDisplayAllCategory)
{
cachedDisplayAllCategory = currentDisplayAllCategory;
foreach (var category in categorys)
{
category.isChecked = cachedDisplayAllCategory;
}
}
if (categorys.Any(filter => filter.isChecked == false) && cachedDisplayAllCategory)
{
cachedDisplayAllCategory = false;
currentDisplayAllCategory = false;
}
if (categorys.All(filter => filter.isChecked) && !cachedDisplayAllCategory)
{
cachedDisplayAllCategory = true;
currentDisplayAllCategory = true;
}
}
private static void GatherItemInfosAndCachGUIElements()
{
currentDisplayingItemlist.Clear();
prefabGUIs.Clear();
foreach (var filter in categorys)
{
if(!filter.isChecked)
continue;
var list = ResourceDataHelper.GetFilesAtPath(filter.directoryPath, filter.filterExtension, true);
foreach (var prefabFileInfo in list)
{
currentDisplayingItemlist.Add(prefabFileInfo.FullNameForwardSlash());
}
}
for (int index = 0; index < currentDisplayingItemlist.Count; index++)
{
var prefabName = currentDisplayingItemlist[index];
prefabGUIs.Add(DrawPrefab(prefabName));
}
}
private static GUIContent DrawPrefab(string prefabDirectoryName)
{
GameObject prefab = LimboPrefabUtility.LoadPrefabAtDirectoryPath(prefabDirectoryName, true);
string text = prefab.name;
return new GUIContent(text, AssetPreview.GetAssetPreview(prefab), text);
}
}
public class PropCategoryInfo
{
public string categoryName;
public string directoryPath;
public bool isChecked = false;
public string filterExtension;
public PropCategoryInfo(string categoryName, bool isChecked, string directoryPath, string filterExtension = ".prefab")
{
this.categoryName = categoryName;
this.isChecked = isChecked;
this.directoryPath = directoryPath;
this.filterExtension = filterExtension;
}
}
using System;
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(TweenParams))]
public class TweenParamsDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
float totalWidth = position.width;
SerializedProperty targetObj = property.FindPropertyRelative("targetObj");
SerializedProperty animType = property.FindPropertyRelative("animType");
SerializedProperty easeType = property.FindPropertyRelative("easeType");
SerializedProperty loopCount = property.FindPropertyRelative("loopCount");
SerializedProperty beginValue = property.FindPropertyRelative("beginValue");
SerializedProperty endValue = property.FindPropertyRelative("endValue");
SerializedProperty duration = property.FindPropertyRelative("duration");
SerializedProperty delay = property.FindPropertyRelative("delay");
SerializedProperty isParallelInSeq = property.FindPropertyRelative("isParallelInSeq");
SerializedProperty colorName = property.FindPropertyRelative("colorName");
SerializedProperty colorIndex = property.FindPropertyRelative("colorIndex");
int indent = EditorGUI.indentLevel;
Rect shape = new Rect(position.x + (EditorUtils.IndentWidth * indent), position.y, 160f, EditorUtils.ListRowHeight);
shape.y += EditorUtils.ListRowHeight * 0.5f;
// begin horizontal
// draw object or tween self label
var percentWidth = 0.18f;
shape.width = percentWidth * totalWidth;
EditorGUI.PropertyField(shape, targetObj, GUIContent.none);
shape.x += shape.width;
// anim type color scale....
percentWidth = 0.15f;
shape.width = percentWidth * totalWidth;
EditorGUI.PropertyField(shape, animType, GUIContent.none);
shape.x += shape.width;
// easetype
percentWidth = 0.16f;
shape.width = percentWidth * totalWidth;
EditorGUI.PropertyField(shape, easeType, GUIContent.none);
shape.x += shape.width;
// delay
percentWidth = 0.18f;
shape.width = percentWidth * totalWidth;
delay.floatValue = EditorUtils.DrawFloatField(shape, delay.floatValue, "delay", 50f, 0f);
shape.x += shape.width;
// duration
percentWidth = 0.15f;
shape.width = percentWidth * totalWidth;
duration.floatValue = EditorUtils.DrawFloatField(shape, duration.floatValue, "dura", 50f, 0f);
shape.x += shape.width;
// loop count
percentWidth = 0.15f;
shape.width = percentWidth * totalWidth;
loopCount.intValue = EditorUtils.DrawIntField(shape, loopCount.intValue, "loop", 50f, 0);
shape.x += shape.width;
// isParallelInseq
percentWidth = 0.1f;
shape.width = percentWidth * totalWidth;
isParallelInSeq.boolValue = EditorGUI.Toggle(shape, GUIContent.none, isParallelInSeq.boolValue);
bool isColor = false;
string animTypeName = animType.enumNames[animType.enumValueIndex];
if (animTypeName == TweenType.lightColor.ToString() ||
animTypeName == TweenType.matColor.ToString())
isColor = true;
// next line
// begin Value line
// init button colum width;
var buttonColumWidthPercent = 0.2f;
shape.x = position.x + (EditorUtils.IndentWidth * indent);
shape.y += EditorUtils.ListRowHeight * 1.25f;
shape.width = (totalWidth - shape.x) * buttonColumWidthPercent;
GameObject o;
if (targetObj.objectReferenceValue == null)
{
o = EditorUtils.GetPropertyMountGameObject(property);
targetObj.objectReferenceValue = o;
}
else
o = targetObj.objectReferenceValue as GameObject;
Func<Vector4> grabValue = () =>
{
Vector4 currentValue;
if (o != null)
{
if (animTypeName == TweenType.scaleTo.ToString())
currentValue = o.transform.localScale;
else if (animTypeName == TweenType.positionTo.ToString())
currentValue = o.transform.position;
else if (animTypeName == TweenType.rotationTo.ToString())
currentValue = o.transform.rotation.eulerAngles;
else if (animTypeName == TweenType.matColor.ToString())
currentValue = MaterialHelper.GrabMaterialV4(o.transform, colorName.enumNames[colorName.enumValueIndex], colorIndex.intValue, true);
else if (animTypeName == TweenType.lightColor.ToString())
currentValue = MaterialHelper.GrabLightColor(o.transform, colorIndex.intValue);
else
{
Debug.Log("AnimType = " + animTypeName + ", Button will not working.");
currentValue = Vector4.zero;
}
}
else
{
Debug.LogWarning("target object is not a GameObject, this should not happened because we already specify the input reference object to be a gameobject!");
currentValue = Vector4.one;
}
return currentValue;
};
shape.width /= 2;
if (GUI.Button(shape, new GUIContent("AsStart")))
beginValue.vector4Value = grabValue();
shape.x += shape.width;
if (GUI.Button(shape, new GUIContent("AsEnd")))
endValue.vector4Value = grabValue();
shape.x += shape.width;
shape.width = totalWidth - shape.x;
if (isColor)
{
beginValue.vector4Value = EditorUtils.DrawVector4Field(shape, beginValue.vector4Value, "Begin: ", 64f, 0f, true);
}
else
{
if (animTypeName == TweenType.matColor.ToString() ||
animTypeName == TweenType.lightColor.ToString() ||
animTypeName == TweenType.positionTo.ToString() ||
animTypeName == TweenType.scaleTo.ToString() ||
animTypeName == TweenType.rotationTo.ToString())
beginValue.vector4Value = EditorUtils.DrawVector3Field(shape, beginValue.vector4Value, "Begin: ", 64f, 0f, true);
}
// end value line
shape.x = position.x + (EditorUtils.IndentWidth * indent);
shape.y += EditorUtils.ListRowHeight * 1.25f;
if (isColor)
{
if (animTypeName == TweenType.matColor.ToString())
{
percentWidth = 0.1f;
shape.width = (totalWidth - shape.x) * percentWidth;
EditorGUI.PropertyField(shape, colorName, GUIContent.none);
shape.x += shape.width;
percentWidth = 0.1f;
shape.width = (totalWidth - shape.x) * percentWidth;
colorIndex.intValue = EditorUtils.DrawIntField(shape, colorIndex.intValue, "index", 40f, 0f);
shape.x += shape.width;
shape.width = totalWidth - shape.x;
endValue.vector4Value = EditorUtils.DrawVector4Field(shape, endValue.vector4Value, "End: ", 64f, 0f, true);
}
else
{
percentWidth = 0.1f;
shape.x += (totalWidth - shape.x) * percentWidth;
percentWidth = 0.1f;
shape.width = (totalWidth - shape.x) * percentWidth;
colorIndex.intValue = EditorUtils.DrawIntField(shape, colorIndex.intValue, "index", 40f, 0f);
shape.x += shape.width;
shape.width = totalWidth - shape.x;
endValue.vector4Value = EditorUtils.DrawVector4Field(shape, endValue.vector4Value, "End: ", 64f, 0f, true);
}
}
else
{
percentWidth = 0.2f;
shape.x += (totalWidth - shape.x) * percentWidth;
shape.width = totalWidth - shape.x;
if (animTypeName == TweenType.matColor.ToString() ||
animTypeName == TweenType.lightColor.ToString() ||
animTypeName == TweenType.positionTo.ToString() ||
animTypeName == TweenType.scaleTo.ToString() ||
animTypeName == TweenType.rotationTo.ToString())
endValue.vector4Value = EditorUtils.DrawVector3Field(shape, endValue.vector4Value, "End: ", 64f, 0f, true);
}
shape.y += EditorUtils.ListRowHeight * 0.5f;
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 4 * EditorUtils.ListRowHeight;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment