public virtual void Setup(AttributeDrawer drawer, Rect area, SerializedProperty property, GUIContent label) { string skinName = EditorGUIUtility.isProSkin || EditorPref.Get <bool>("Zios.Theme.Dark", false) ? "Dark" : "Light"; if (this.skin == null || !this.skin.name.Contains(skinName)) { this.skin = File.GetAsset <GUISkin>("Gentleface-" + skinName + ".guiskin"); this.attribute = property.GetObject <Attribute>(); } var info = this.attribute.info; this.activeDataset = info.data; this.drawer = drawer; this.property = property; this.label = label; Rect fullRect = area.SetHeight(EditorGUIUtility.singleLineHeight); this.SetupAreas(fullRect); ProxyEditor.RecordObject(info.parent, "Attribute Changes"); this.Draw(); if (GUI.changed || this.dirty) { this.attribute.Setup(info.relativePath, info.parent); info.parent.DelayEvent(info.fullPath, "On Validate", 1); property.serializedObject.Update(); ProxyEditor.SetDirty(info.parent); ProxyEditor.RepaintInspectors(); this.dirty = false; GUI.changed = true; } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorUI.Reset(); var parent = property.serializedObject.targetObject; var target = property.GetObject(); var value = ""; if (target is AttributeString) { var attribute = target.As <AttributeString>(); if (!attribute.isSetup) { return; } value = attribute.Get(); } if (target is string) { value = property.stringValue; } if (this.items.Count < 1) { foreach (var group in InputManager.Get().groups) { foreach (var action in group.actions) { this.items.Add(group.name.ToPascalCase() + "-" + action.name.ToPascalCase()); } this.index = this.items.IndexOf(value); if (this.index == -1) { this.index = 0; } } } ProxyEditor.RecordObject(parent, "Input Name Changes"); this.index = this.items.Draw(position, this.index, "Input Action"); if (GUI.changed || value.IsEmpty()) { value = this.items[index]; if (target is AttributeString) { target.As <AttributeString>().Set(value); } if (target is string) { property.stringValue = value; } parent.CallEvent("On Validate"); property.serializedObject.Update(); ProxyEditor.SetDirty(parent); } }
public void UngroupSelected() { var selected = this.tableGUI.rows.Where(x => x.selected).ToArray(); ProxyEditor.RecordObject(this.target, "State Window - Group Assignment"); foreach (var row in selected) { var stateRow = (StateRow)row.target; stateRow.section = ""; } ProxyEditor.SetDirty(this.target, false, true); this.BuildTable(); }
public void SetSpeedMode(object index) { if (index.As <SpeedUnit>() == AnimationConfiguration.speedMode) { return; } ProxyEditor.RecordObject(this.target, "Animation Speed Mode Changed"); AnimationConfiguration.speedMode.Set(index.As <SpeedUnit>()); foreach (var config in this.target.As <AnimationSettings>().animations) { config.speed = AnimationConfiguration.speedMode == SpeedUnit.Framerate ? config.speed * config.originalSpeed : config.speed / config.originalSpeed; } ProxyEditor.SetDirty(this.target); }
public override void Clicked(int button) { var window = StateWindow.Get(); ProxyEditor.RecordObject(window.target, "State Window - Field Toggle"); this.row.selected = false; int state = 0; var requirement = (StateRequirement)this.target; if (requirement.requireOn) { state = 1; } if (requirement.requireOff) { state = 2; } if (requirement.requireUsed) { state = 3; } int amount = button == 0 ? 1 : -1; state += amount; state = state.Modulus(4); requirement.requireOn = false; requirement.requireOff = false; requirement.requireUsed = false; if (state == 1) { requirement.requireOn = true; } if (state == 2) { requirement.requireOff = true; } if (state == 3) { requirement.requireUsed = true; } ProxyEditor.SetDirty(window.target); window.target.UpdateStates(); window.Repaint(); }
//================================= // Main //================================= public override void OnInspectorGUI() { if (Event.current.type.MatchesAny("mouseMove")) { return; } EditorUI.Reset(); this.hash = this.hash ?? ProxyEditor.GetInspector(this).GetInstanceID().ToString(); this.skin = this.skin ?? this.target.As <GUISkin>(); this.isFragment = this.skin.name.Contains("#"); //this.optimize = Utility.GetPref<bool>("GUISkinEditor-Optimize",false); EditorUI.foldoutChanged = false; this.DrawViewMode(); if (this.viewMode == 0) { this.DrawDefaultInspector(); return; } if (!Event.current.type.MatchesAny("Repaint", "Layout", "scrollWheel", "used")) { ProxyEditor.RecordObject(this.skin, "GUI Skin Changes"); foreach (var fragment in this.fragments) { ProxyEditor.RecordObject(fragment, "GUI Skin Changes"); } } GUI.changed = false; this.drawn = false; this.count = 0; this.fragments = File.GetAssets <GUISkin>(this.skin.name + "#*.guiskin", false); this.ProcessMenu(); this.DrawSearch(); //this.DrawSplit(); if (this.inputMode == 0 && this.inputTerms.Count == 0 || this.inputTerms[0] == "Search") { this.DrawStandard(); this.DrawCustom(); this.DrawFragmented(); } this.CheckChanges(); this.CheckReset(); GUILayout.Space(this.lowerBounds); }
public static void Add(string operation, string undo, string redo, Action <string> method) { var instance = Undo.Get(); if (Proxy.IsBusy() || instance.IsNull() || (undo.IsEmpty() && redo.IsEmpty())) { return; } ProxyEditor.RecordObject(instance, operation); var seed = UnityRandom.Range(0.0f, 100.0f).ToString() + "!"; undo = seed + undo; redo = seed + redo; instance.buffer.Add(undo); instance.cache.Add(undo); instance.buffer.Add(redo); instance.cache.Add(redo); Undo.position = (instance.buffer.Count() / 2) - 1; instance.callback = instance.callback.Take(Undo.position).ToList(); instance.callback.Add(method); }
public void CheckHotkeys() { if (prompted) { int state = "Group Name?".ToLabel().DrawPrompt(ref this.newSection); if (state > 0) { ProxyEditor.RecordObject(this.target, "State Window - Group Assignment"); var selected = this.tableGUI.rows.Where(x => x.selected).ToArray(); foreach (var row in selected) { row.target.As <StateRow>().section = this.newSection; } ProxyEditor.SetDirty(this.target, false, true); } if (state != 0) { GUIUtility.keyboardControl = 0; this.prompted = false; this.BuildTable(); } return; } if (Button.EventKeyUp("A")) { this.SelectAll(); } if (Button.EventKeyUp("I")) { this.InvertSelection(); } if (Button.EventKeyUp("G")) { this.GroupSelected(); } if (Button.EventKeyUp("Escape")) { this.DeselectAll(); } }
public override void Clicked(int button) { var window = StateWindow.Get(); if (button == 0) { if (window.target.advanced) { window.tableIndex = window.tableIndex == 0 ? 1 : 0; window.BuildTable(); } } if (button == 1) { var menu = new GenericMenu(); MenuFunction markDirty = () => ProxyEditor.SetDirty(window.target); MenuFunction toggleAdvanced = () => { ProxyEditor.RecordObject(window.target, "State Window - Advanced Toggle"); window.target.advanced = !window.target.advanced; window.tableIndex = 0; window.BuildTable(); }; MenuFunction toggleManual = () => { ProxyEditor.RecordObject(window.target, "State Window - Manual Toggle"); window.target.manual = !window.target.manual; window.BuildTable(); }; menu.AddItem("Advanced", window.target.advanced, toggleAdvanced + markDirty); if (window.target.controller != null) { menu.AddItem("Manual", window.target.manual, toggleManual + markDirty); } menu.AddItem("Rebuild", false, window.BuildTable); menu.ShowAsContext(); } }
public static void Draw(Rect area, Target target, GUIContent label) { if (target.parent.IsNull()) { return; } if (TargetDrawer.skin.IsNull()) { string skin = EditorGUIUtility.isProSkin || EditorPref.Get <bool>("Zios.Theme.Dark", false) ? "Dark" : "Light"; TargetDrawer.skin = File.GetAsset <GUISkin>("Gentleface-" + skin + ".guiskin"); } Rect toggleRect = new Rect(area); Rect propertyRect = new Rect(area); float labelWidth = label.text.IsEmpty() ? 0 : EditorGUIUtility.labelWidth; propertyRect.x += labelWidth + 18; propertyRect.width -= labelWidth + 18; toggleRect.x += labelWidth; toggleRect.width = 18; bool previousMode = target.mode == TargetMode.Direct; bool currentMode = previousMode.Draw(toggleRect, "", TargetDrawer.skin.GetStyle("TargetToggle")); if (previousMode != currentMode) { target.mode = target.mode == TargetMode.Direct ? TargetMode.Search : TargetMode.Direct; } label.ToLabel().DrawLabel(area, null, true); ProxyEditor.RecordObject(target.parent, "Target Changes"); if (target.mode == TargetMode.Direct) { target.directObject = target.directObject.Draw <GameObject>(propertyRect, "", true); } else { target.Verify(); var faded = GUI.skin.textField.Background("").TextColor(GUI.skin.textField.normal.textColor.SetAlpha(0.75f)).ContentOffset(-3, 0).UseState("normal"); Rect textRect = propertyRect; string result = !target.searchObject.IsNull() ? target.searchObject.GetPath().Trim("/") : "Not Found."; Vector2 textSize = TargetDrawer.skin.textField.CalcSize(new GUIContent(target.search)); Vector2 subtleSize = faded.CalcSize(new GUIContent(result)); float subtleX = propertyRect.x + propertyRect.width - subtleSize.x; float subtleWidth = subtleSize.x; float minimumX = propertyRect.x + textSize.x + 3; if (subtleX < minimumX) { subtleWidth -= (minimumX - subtleX); subtleX = minimumX; } propertyRect = propertyRect.SetX(subtleX).SetWidth(subtleWidth); EditorGUIUtility.AddCursorRect(propertyRect, MouseCursor.Zoom); if (!target.searchObject.IsNull() && propertyRect.Clicked(0)) { Selection.activeGameObject = target.searchObject; Event.current.Use(); } target.search = target.search.Draw(textRect); result.ToLabel().DrawLabel(propertyRect, faded); } if (GUI.changed && !target.IsNull()) { target.Search(); if (target.parent is DataBehaviour) { var parent = target.parent.As <DataBehaviour>(); parent.DelayEvent(parent.path, "On Validate"); ProxyEditor.SetDirty(parent); } } }
public override void OnInspectorGUI() { EditorUI.Reset(); Events.Add("On Editor Update", this.EditorUpdate); if (this.renderer.sharedMesh != this.blendState.mesh) { this.OnEnable(); } var blendValues = this.blendState.values; var id = this.renderer.GetInstanceID(); EditorUI.SetFieldSize(-1, 150, false); var hasSkeletal = !this.target.As <AnimationSettings>().Get <Animation>().IsNull(); var hasBlendshapes = blendValues.Count > 0; if (hasBlendshapes && (!hasSkeletal || EditorUI.DrawFoldout("Blend Shapes", id + "Blend"))) { EditorGUI.indentLevel += 1; var wrap = this.renderer.gameObject.GetMeshWrap(); var names = blendValues.Keys.ToList(); var values = this.blendStates.Values.ToList(); var active = values.IndexOf(this.blendState); this.blendState = values[this.blendStates.Keys.ToList().Draw(active, "State")]; if (EditorUI.lastChanged) { this.SetBlendState(this.blendState.name); this.Repaint(); } for (var index = 0; index < blendValues.Count; ++index) { if (index > names.Count - 1) { break; } var shapeName = names[index]; var shapeValue = this.renderer.GetBlendShapeWeight(index); var separated = blendValues.ContainsKey(shapeName + "-Left") && blendValues.ContainsKey(shapeName + "-Right"); if (shapeName.EndsWith("-")) { continue; } if (shapeName.EndsWith("+")) { shapeName = shapeName.TrimRight("+"); if (!wrap.blendShapes.ContainsKey(shapeName + "-")) { Log.Warning("[AnimationSettings] Matching blendshape (" + shapeName + "-) does not exist. Skipping."); continue; } var negativeIndex = wrap.blendShapes[shapeName + "-"].index; var positiveIndex = wrap.blendShapes[shapeName + "+"].index; var negativeValue = this.renderer.GetBlendShapeWeight(negativeIndex); var displayValue = shapeValue > 0 ? (shapeValue / 100f).Lerp(50, 100) : 50f; displayValue = negativeValue > 0 ? (negativeValue / 100f).Lerp(50, 0) : displayValue; displayValue = displayValue.DrawSlider(0, 100, shapeName); if (EditorUI.lastChanged) { blendValues[shapeName + "+"] = 100 * displayValue.InverseLerp(50, 100); blendValues[shapeName + "-"] = 100 * displayValue.InverseLerp(50, 0); this.renderer.SetBlendShapeWeight(positiveIndex, blendValues[shapeName + "+"]); this.renderer.SetBlendShapeWeight(negativeIndex, blendValues[shapeName + "-"]); } index += 1; continue; } var expanded = false; if (separated) { EditorGUILayout.BeginHorizontal(); expanded = EditorUI.DrawFoldout(shapeName, id + shapeName + "Individual", EditorStyles.toggle); EditorUI.SetFieldSize(-1, 96); this.DrawBlendState(index, shapeName, shapeValue, null); EditorGUILayout.EndHorizontal(); if (expanded) { EditorGUI.indentLevel += 1; EditorUI.SetFieldSize(-1, 150, false); this.DrawBlendState(index + 1, shapeName + "-Left", this.renderer.GetBlendShapeWeight(index + 1), "Left"); this.DrawBlendState(index + 2, shapeName + "-Right", this.renderer.GetBlendShapeWeight(index + 2), "Right"); EditorGUI.indentLevel -= 1; } index += 2; continue; } this.DrawBlendState(index, shapeName, shapeValue); } EditorGUILayout.BeginHorizontal(); this.newState = this.newState.Layout(150, 18).Draw(); if ("Add State".ToLabel().Layout(100, 19).DrawButton() && !this.newState.IsEmpty() && !this.blendStates.ContainsKey(this.newState)) { var mesh = Mesh.Instantiate(this.renderer.sharedMesh); this.renderer.BakeMesh(mesh); this.blendStates.AddNew(this.newState).Set(this.newState, mesh); this.SetBlendState(this.newState); this.newState = ""; } if ("Randomize".ToLabel().Layout(100, 19).DrawButton()) { foreach (var item in wrap.blendShapes) { var shape = item.Value; this.renderer.SetBlendShapeWeight(shape.index, Random.Range(0, 100)); } } if ("Reset".ToLabel().Layout(100, 19).DrawButton()) { foreach (var item in wrap.blendShapes) { var shape = item.Value; this.renderer.SetBlendShapeWeight(shape.index, 0); } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel -= 1; } EditorUI.allowIndention = false; if (hasSkeletal && (!hasBlendshapes || EditorUI.DrawFoldout("Skeletal", id + "Skeleton"))) { EditorGUILayout.BeginHorizontal(); "Name".Layout(150).DrawLabel(); "Rate •".Layout(50).DrawLabel(); if (GUILayoutUtility.GetLastRect().Clicked()) { AnimationConfiguration.rateMode.Get().GetNames().DrawMenu(this.SetRateMode, AnimationConfiguration.rateMode.Get().ToName().AsList()); } "Speed •".Layout(50).DrawLabel(); if (GUILayoutUtility.GetLastRect().Clicked()) { AnimationConfiguration.speedMode.Get().GetNames().DrawMenu(this.SetSpeedMode, AnimationConfiguration.speedMode.Get().ToName().AsList()); } "Blend".Layout(80).DrawLabel(); "Wrap".Layout(115).DrawLabel(); EditorGUILayout.EndHorizontal(); foreach (var config in this.target.As <AnimationSettings>().animations) { EditorGUILayout.BeginHorizontal(); bool isPlaying = this.active.Contains(config); config.name.Layout(150).DrawLabel(); config.rate = config.rate.Layout(50).Draw(); config.speed = config.speed.Layout(50).Draw(); config.blendMode = config.blendMode.Layout(80).Draw().As <AnimationBlendMode>(); config.wrapMode = config.wrapMode.Layout(115).Draw().As <WrapMode>(); if (isPlaying && "Stop".ToLabel().Layout(0, 17).DrawButton()) { this.Stop(config); } if (!isPlaying && "Play".ToLabel().Layout(0, 17).DrawButton()) { this.StopAll(); this.active.AddNew(config); Events.Pause("On Hierarchy Changed"); } if (GUI.changed) { ProxyEditor.RecordObject(this.target, "Animation Settings Changed"); config.Apply(); ProxyEditor.SetDirty(this.target); } EditorGUILayout.EndHorizontal(); } } }
public static void Flatten(params UnityObject[] targets) { string originalName = ""; foreach (var target in targets) { Material material = (Material)target; FileData shaderFile = VariableMaterial.GetParentShader(target); if (shaderFile.IsNull()) { continue; } string timestamp = shaderFile.GetModifiedDate("MdyyHmmff"); string projectPath = Application.dataPath + "/" + "Shaders"; string hash = timestamp + "-" + material.shaderKeywords.Join(" ").ToMD5(); string folderPath = projectPath + "/" + shaderFile.name + "/"; string outputPath = folderPath + shaderFile.name + "#" + hash + ".shader"; Action update = () => { ProxyEditor.RecordObject(material, "Variable Material - Shader Set"); material.EnableKeyword("VARIABLE_MATERIAL_" + shaderFile.name.ToUpper()); material.shader = File.GetAsset <Shader>(outputPath); ProxyEditor.SetAssetDirty(material); if (VariableMaterial.debug) { Log.Show("[VariableMaterial] Shader set " + outputPath); } }; if (!VariableMaterial.force && File.Exists(outputPath)) { VariableMaterial.updates += update; continue; } originalName = shaderFile.fullName; string text = shaderFile.ReadText(); string shaderName = text.Parse("Shader ", "{").Trim(' ', '"'); if (shaderName.Contains("#")) { continue; } string output = "Shader " + '"' + "Hidden/" + shaderName + "#" + hash + '"' + "{\r\n"; var allowed = new Stack <bool?>(); int tabs = -1; text = text.Replace("\\\r\n", ""); int lineNumber = 0; foreach (string current in text.Split("\r\n").Skip(1)) { lineNumber += 1; if (current.IsEmpty()) { continue; } string line = current; bool hideBlock = allowed.Count > 0 && allowed.Peek() != true; bool allowedBranch = line.ContainsAny("#else", "#elif") && allowed.Peek() != null; bool ignoredBranch = line.Contains("@#"); //if(line.ContainsAny("[KeywordEnum","[Toggle")){continue;} if (!ignoredBranch && line.Contains("#endif")) { allowed.Pop(); if (allowed.Count == 0) { tabs = -1; } continue; } if (hideBlock && !allowedBranch) { if (!ignoredBranch && line.ContainsAny("#if")) { allowed.Push(null); } continue; } if (ignoredBranch) { bool end = line.Contains("#end"); bool include = line.Contains("#include"); if (tabs < 0) { tabs = line.Length - line.TrimStart().Length; } if (end) { tabs -= 1; } line = new String('\t', tabs) + line.TrimStart(); output += line.Replace("@#", "#") + "\r\n"; if (!end && !include) { tabs += 1; } continue; } if (line.Contains("#include")) { line = line.Replace("#include \"", "#include \"../"); } if (line.Contains("#pragma shader_feature")) { continue; } if (line.Contains("#pragma multi_compile ")) { continue; } if (line.ContainsAny("#if", "#elif", "#else")) { bool useBlock = false; if (line.ContainsAny("#else", "#elif")) { bool lastAllowed = allowed.Pop() == true; if (lastAllowed) { allowed.Push(null); continue; } useBlock = line.Contains("#else"); } if (line.ContainsAny("#ifdef", "#ifndef")) { bool hasTerm = material.shaderKeywords.Contains(line.Trim().Split(" ").Last()); useBlock = line.Contains("#ifndef") ? !hasTerm : hasTerm; } else if (line.Contains("defined")) { string[] orBlocks = line.Trim().Trim("#if ").Trim("#elif ").Split("||"); foreach (string orBlock in orBlocks) { string[] andBlocks = orBlock.Split("&&"); foreach (string andBlock in andBlocks) { string term = andBlock.Parse("defined(", ")"); bool hasTerm = material.shaderKeywords.Contains(term); useBlock = andBlock.Contains("!") ? !hasTerm : hasTerm; if (!useBlock) { break; } } if (useBlock) { break; } } } allowed.Push(useBlock); if (useBlock && allowed.Count == 1 && tabs <= 0) { tabs = line.Length - line.TrimStart().Length; } continue; } if (tabs >= 1) { if (line.Contains("}") && !line.Contains("{")) { tabs -= 1; } line = new String('\t', tabs) + line.TrimStart(); if (line.Contains("{") && !line.Contains("}")) { tabs += 1; } } output += line + "\r\n"; } output = output.Replace("{\r\n\t\t\t}", "{}"); string pattern = output.Cut("{\r\n\t\t\t\treturn ", ";\r\n\t\t\t"); while (!pattern.IsEmpty()) { string replace = pattern.Replace("\r\n", "").Replace("\t", ""); output = output.ReplaceFirst(pattern, replace); pattern = output.Cut("{\r\n\t\t\t\treturn ", ";\r\n\t\t\t"); } if (output != text) { Action write = () => { File.Create(outputPath).Write(output); }; VariableMaterial.writes += write; VariableMaterial.updates += update; } } if (VariableMaterial.debug) { Log.Show("[VariableMaterial] " + originalName + " -- " + targets.Length + " flattened."); } if (VariableMaterial.delay) { Call.Delay(VariableMaterial.RefreshEditor, 0.5f); return; } VariableMaterial.RefreshEditor(); VariableMaterial.force = false; }