public override void OnInspectorGUI() { var script = (SpawnPool)target; EditorGUI.indentLevel = 0; PGEditorUtils.LookLikeControls(); script.poolName = EditorGUILayout.TextField("Pool Name", script.poolName); script.matchPoolScale = EditorGUILayout.Toggle("Match Pool Scale", script.matchPoolScale); script.matchPoolLayer = EditorGUILayout.Toggle("Match Pool Layer", script.matchPoolLayer); script.dontReparent = EditorGUILayout.Toggle("Don't Reparent", script.dontReparent); script.dontDestroyOnLoad = EditorGUILayout.Toggle("Don't Destroy On Load", script.dontDestroyOnLoad); script.logMessages = EditorGUILayout.Toggle("Log Messages", script.logMessages); this.expandPrefabs = PGEditorUtils.SerializedObjFoldOutList <PrefabPool> ( "Per-Prefab Pool Options", script._perPrefabPoolOptions, this.expandPrefabs, ref script._editorListItemStates, true ); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
private void drawRegion(DOSetter <Vector3> reset, Vector3 resetVal, DOSetter <Quaternion> go, Quaternion goVal, CharactersActionData item, string lableName) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(45); // Matches the content indent EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.FlexibleSpace(); EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100)); if (GUILayout.Button(new GUIContent("reset", "重置当前数值"), EditorStyles.toolbarButton)) { reset(resetVal); } if (GUILayout.Button(new GUIContent("goto", "将物体变成所设置的数值"), EditorStyles.toolbarButton)) { go(goVal); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); PGEditorUtils.FieldInfoField <CharactersActionData>(item, typeof(CharactersActionData).GetField(lableName)); }
protected override void OnInspectorGUIUpdate() { base.OnInspectorGUIUpdate(); var script = (TransformConstraint)target; GUILayout.BeginHorizontal(); script.constrainPosition = EditorGUILayout.Toggle("Position", script.constrainPosition); if (script.constrainPosition) { GUIStyle style = EditorStyles.toolbarButton; style.alignment = TextAnchor.MiddleCenter; style.stretchWidth = true; script.outputPosX = GUILayout.Toggle(script.outputPosX, "X", style); script.outputPosY = GUILayout.Toggle(script.outputPosY, "Y", style); script.outputPosZ = GUILayout.Toggle(script.outputPosZ, "Z", style); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); script.constrainRotation = EditorGUILayout.Toggle("Rotation", script.constrainRotation); if (script.constrainRotation) { script.output = PGEditorUtils.EnumPopup <UnityConstraints.OUTPUT_ROT_OPTIONS>(script.output); } GUILayout.EndHorizontal(); script.constrainScale = EditorGUILayout.Toggle("Scale", script.constrainScale); }
/// <summary> /// Adds the GUI header line which contains the label and add buttons. /// </summary> /// <param name="label">The visible label in the GUI</param> /// <param name="list">Needed to add a new item if count is 0</param> /// <param name="expanded"></param> /// <param name="lastIndent"></param> private static bool AddFoldOutListHeader <T>(string label, List <T> list, bool expanded, int lastIndent) { int buttonSpacer = 6; EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); expanded = PGEditorUtils.Foldout(expanded, label); if (!expanded) { // Don't add the '+' button when the contents are collapsed. Just quit. EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = lastIndent; // Return to the last indent return(expanded); } EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50)); // 1/2 the item button width GUILayout.Space(buttonSpacer); // Master add at end button. List items will insert if (GUILayout.Button(new GUIContent("+", "Click to add"), EditorStyles.toolbarButton)) { list.Add(default(T)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); return(expanded); }
protected override void OnInspectorGUIHeader() { base.OnInspectorGUIHeader(); var script = (ConstraintBaseClass)target; script.target = PGEditorUtils.ObjectField <Transform>("Target", script.target); }
protected override void OnInspectorGUIUpdate() { base.OnInspectorGUIUpdate(); var script = (LookAtConstraint)target; script.upTarget = PGEditorUtils.ObjectField <Transform>("Up Target (Optional)", script.upTarget); }
public override void OnInspectorGUI() { this.serializedObject.Update(); GUIContent content; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; Object[] targetObjs = this.serializedObject.targetObjects; EventInfoListStandalone curEditTarget; content = new GUIContent ( "Event Info List", "A list of event descriptions to be passed by struct to Targets" ); if (this.serializedObject.isEditingMultipleObjects) { EditorGUILayout.PropertyField(this.eventInfoList, content, true); } else { GUILayout.Space(6); EditorGUI.indentLevel += 2; curEditTarget = (EventInfoListStandalone)targetObjs[0]; this.expandInfo = PGEditorUtils.SerializedObjFoldOutList <EventInfoListGUIBacker> ( content.text, curEditTarget._eventInfoListGUIBacker, this.expandInfo, ref curEditTarget._inspectorListItemStates, true ); EditorGUI.indentLevel -= 2; GUILayout.Space(4); } serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); Object[] targetObjs = this.serializedObject.targetObjects; IgnoreTagModifier curEditTarget; GUIContent content; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; EditorGUI.indentLevel = 1; GUILayout.Space(6); if (this.serializedObject.isEditingMultipleObjects) { content = new GUIContent("Tags to Ignore", "List of tags to ignore."); EditorGUILayout.PropertyField(this.ignoreList, content, true); } else { curEditTarget = (IgnoreTagModifier)targetObjs[0]; // Display and get user changes PGEditorUtils.FoldOutTextList ( "Tags to ignore", curEditTarget.ignoreList, true // Force the fold-out state ); } GUILayout.Space(4); content = new GUIContent ( "Debug Level", "Set it higher to see more verbose information." ); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { var script = (Targetable)target; EditorGUI.indentLevel = 0; PGEditorUtils.LookLikeControls(); script.debugLevel = PGEditorUtils.EnumPopup <DEBUG_LEVELS>("Debug Level", script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { var script = (PreRuntimePoolItem)target; EditorGUI.indentLevel = 0; PGEditorUtils.LookLikeControls(); script.poolName = EditorGUILayout.TextField("Pool Name", script.poolName); script.prefabName = EditorGUILayout.TextField("Prefab Name", script.prefabName); script.despawnOnStart = EditorGUILayout.Toggle("Despawn On Start", script.despawnOnStart); script.doNotReparent = EditorGUILayout.Toggle("Do Not Reparent", script.doNotReparent); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
protected override void OnInspectorGUIFooter() { var script = (ConstraintBaseClass)target; // For backwards compatibility. I removed an option and it moved these two // Options back, so Once is now Constrain and Constrain is out of bounds. // Unfortunatly I can't fix the old Once back to once. if (script._mode != UnityConstraints.MODE_OPTIONS.Align && script._mode != UnityConstraints.MODE_OPTIONS.Constrain) { script._mode = UnityConstraints.MODE_OPTIONS.Constrain; } script._mode = PGEditorUtils.EnumPopup <UnityConstraints.MODE_OPTIONS>("Mode", script._mode); script._noTargetMode = PGEditorUtils.EnumPopup <UnityConstraints.NO_TARGET_OPTIONS>("No-Target Mode", script._noTargetMode); base.OnInspectorGUIFooter(); }
// This is Unity's. Block from sub-classes - Use header, update and footer callbacks callbacks public override void OnInspectorGUI() { // Used like a header to set a global label width EditorGUI.indentLevel = 0; PGEditorUtils.SetLabelWidth(); this.serializedObject.Update(); this.OnInspectorGUIHeader(); this.OnInspectorGUIUpdate(); EditorGUILayout.Space(); this.OnInspectorGUIFooter(); // Flag Unity to save the changes to to the prefab to disk serializedObject.ApplyModifiedProperties(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
protected override void OnInspectorGUIUpdate() { base.OnInspectorGUIUpdate(); var script = (SmoothLookAtConstraint)target; script.upTarget = PGEditorUtils.ObjectField <Transform>("Up Target (Optional)", script.upTarget); script.interpolation = PGEditorUtils.EnumPopup <UnityConstraints.INTERP_OPTIONS> ( "Interpolation", script.interpolation ); script.speed = EditorGUILayout.FloatField("Speed", script.speed); script.output = PGEditorUtils.EnumPopup <UnityConstraints.OUTPUT_ROT_OPTIONS> ( "Output", script.output ); }
protected override void OnInspectorGUIUpdate() { base.OnInspectorGUIUpdate(); GUIContent content; GUILayout.BeginHorizontal(); content = new GUIContent("Position", "Option to match the target's position."); EditorGUILayout.PropertyField(this.position, content); if (this.position.boolValue) { PGEditorUtils.ToggleButton(this.outputPosX, new GUIContent("X", "Toggle Costraint for this axis."), 24); PGEditorUtils.ToggleButton(this.outputPosY, new GUIContent("Y", "Toggle Costraint for this axis."), 24); PGEditorUtils.ToggleButton(this.outputPosZ, new GUIContent("Z", "Toggle Costraint for this axis."), 24); } GUILayout.EndHorizontal(); content = new GUIContent("Rotation", "Option to match the target's rotation."); EditorGUILayout.PropertyField(this.rotation, content); if (this.rotation.boolValue) { EditorGUI.indentLevel += 1; content = new GUIContent("Output", "Used to alter the way the rotations are set."); EditorGUILayout.PropertyField(this.output, content); EditorGUI.indentLevel -= 1; } content = new GUIContent("Scale", "Option to match the target's scale."); EditorGUILayout.PropertyField(this.scale, content); }
public bool SerializedObjFoldOutList(string label, List <CharactersActionData> list, bool expanded, ref Dictionary <object, bool> foldOutStates, bool collapseBools, Transform tf) { // Store the previous indent and return the flow to it at the end int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; int buttonSpacer = 6; #region Header Foldout // Use a Horizanal space or the toolbar will extend to the left no matter what EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel = 0; // Space will handle this for the header GUILayout.Space(indent * 6); // Matches the content indent EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); expanded = PGEditorUtils.Foldout(expanded, label); if (!expanded) { // Don't add the '+' button when the contents are collapsed. Just quit. EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = indent; // Return to the last indent return(expanded); } // BUTTONS... EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100)); // Add expand/collapse buttons if there are items in the list bool masterCollapse = false; bool masterExpand = false; if (list.Count > 0) { GUIContent content; var collapseIcon = '\u2261'.ToString(); content = new GUIContent(collapseIcon, "Click to collapse all"); masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton); var expandIcon = '\u25A1'.ToString(); content = new GUIContent(expandIcon, "Click to expand all"); masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton); } else { GUILayout.FlexibleSpace(); } EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50)); // A little space between button groups GUILayout.Space(buttonSpacer); // Main Add button if (GUILayout.Button(new GUIContent("+", "Click to add"), EditorStyles.toolbarButton)) { list.Add(new CharactersActionData()); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); #endregion Header Foldout #region List Items // Use a for, instead of foreach, to avoid the iterator since we will be // be changing the loop in place when buttons are pressed. Even legal // changes can throw an error when changes are detected for (int i = 0; i < list.Count; i++) { CharactersActionData item = list[i]; #region Section Header // If there is a field with the name 'name' use it for our label string itemLabel = PGEditorUtils.GetSerializedObjFieldName <CharactersActionData>(item); if (itemLabel == "") { itemLabel = string.Format("Element {0}", i); } // Get the foldout state. // If this item is new, add it too (singleton) // Singleton works better than multiple Add() calls because we can do // it all at once, and in one place. bool foldOutState; if (!foldOutStates.TryGetValue(item, out foldOutState)) { foldOutStates[item] = true; foldOutState = true; } // Force states if master buttons were pressed if (masterCollapse) { foldOutState = false; } if (masterExpand) { foldOutState = true; } // Use a Horizanal space or the toolbar will extend to the start no matter what EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel = 0; // Space will handle this for the header GUILayout.Space((indent + 3) * 6); // Matches the content indent EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); // Display foldout with current state foldOutState = PGEditorUtils.Foldout(foldOutState, itemLabel); foldOutStates[item] = foldOutState; // Used again below PGEditorUtils.LIST_BUTTONS listButtonPressed = PGEditorUtils.AddFoldOutListItemButtons(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); #endregion Section Header // If folded out, display all serialized fields if (foldOutState == true) { EditorGUI.indentLevel = indent + 3; // Display Fields for the list instance // PGEditorUtils.SerializedObjectFields<T>(item, collapseBools); System.Type type = typeof(CharactersActionData); // System.Reflection.FieldInfo[] fields = type.GetFields(); // Display Fields Dynamically item.actionType = PGEditorUtils.EnumPopup <Config.ColliderAction>("actionType", item.actionType); item.condition = PGEditorUtils.EnumPopup <Config.ActionTriggerCondition>("triggerCondition", item.condition); PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("loop")); switch (item.actionType) { case Config.ColliderAction.Movement: drawRegion(x => item.startVal = x, tf.localPosition, x => tf.localPosition = x, item.startVal, item, "startVal"); drawRegion(x => item.endVal = x, tf.localPosition, x => tf.localPosition = x, item.endVal, item, "endVal"); break; case Config.ColliderAction.Rotation: drawRegion(x => item.startVal = x, tf.localRotation.eulerAngles, x => tf.localRotation = Quaternion.Euler(item.startVal), item.startVal, item, "startVal"); drawRegion(x => item.endVal = x, tf.localRotation.eulerAngles, x => tf.localRotation = x, Quaternion.Euler(item.endVal), item, "endVal"); break; case Config.ColliderAction.Scale: drawRegion(x => item.startVal = x, tf.localScale, x => tf.localScale = x, item.startVal, item, "startVal"); drawRegion(x => item.endVal = x, tf.localScale, x => tf.localScale = x, item.endVal, item, "endVal"); break; case Config.ColliderAction.Alpha: PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("startAlpha")); PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("endAlpha")); break; } PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("duration")); if (item.loop > 1 || item.loop < 0) { item.loopType = PGEditorUtils.EnumPopup <DG.Tweening.LoopType>("loopType", item.loopType); PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("pauseTime")); } PGEditorUtils.FieldInfoField <CharactersActionData>(item, type.GetField("delay")); GUILayout.Space(2); } #region Process List Changes // Don't allow 'up' presses for the first list item switch (listButtonPressed) { case PGEditorUtils.LIST_BUTTONS.None: // Nothing was pressed, do nothing break; case PGEditorUtils.LIST_BUTTONS.Up: if (i > 0) { CharactersActionData shiftItem = list[i]; list.RemoveAt(i); list.Insert(i - 1, shiftItem); } break; case PGEditorUtils.LIST_BUTTONS.Down: // Don't allow 'down' presses for the last list item if (i + 1 < list.Count) { CharactersActionData shiftItem = list[i]; list.RemoveAt(i); list.Insert(i + 1, shiftItem); } break; case PGEditorUtils.LIST_BUTTONS.Remove: list.RemoveAt(i); foldOutStates.Remove(item); // Clean-up break; case PGEditorUtils.LIST_BUTTONS.Add: list.Insert(i, new CharactersActionData()); break; } #endregion Process List Changes } #endregion List Items EditorGUI.indentLevel = indent; return(expanded); }
public override void OnInspectorGUI() { this.serializedObject.Update(); GUIContent content; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; Object[] targetObjs = this.serializedObject.targetObjects; EventFireController curEditTarget; // Try and init the TargetTracker field for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventFireController)targetObjs[i]; if (curEditTarget.targetTracker == null) { curEditTarget.targetTracker = curEditTarget.GetComponent <TargetTracker>(); // null OK } } content = new GUIContent("Interval", "Fire every X seconds"); EditorGUILayout.PropertyField(this.interval, content); content = new GUIContent ( "Init Countdown at 0", "Able to fire immediatly when first spawned, before interval count begins" ); EditorGUILayout.PropertyField(this.initIntervalCountdownAtZero, content); content = new GUIContent ( "Notify Targets", "Sets the target notification behavior. Telling targets they are hit is optional " + "for situations where a delayed response is required, such as launching a , " + "projectile or for custom handling.\n" + "\n" + "MODES\n" + " Off\n" + " Do not notify anything. delegates can still be used\n" + " for custom handling\n" + " Direct\n" + " OnFire targets will be notified immediately\n" + " PassInfoToEventTrigger\n" + " OnFire, for each Target hit, a new EventTrigger will\n" + " be spawned and passed this EventFireController's \n" + " EventInfo.\n" + " UseEventTriggerInfo\n" + " Same as PassInfoToEventTrigger but the new\n" + " EventTrigger will use its own EventInfo (this \n" + " EventTrigger's EventInfo will be ignored). " ); EditorGUILayout.PropertyField(this.notifyTargets, content); // // If using an EventTrigger Prefab... // EventFireController.NOTIFY_TARGET_OPTIONS curOption; curOption = (EventFireController.NOTIFY_TARGET_OPTIONS) this.notifyTargets.enumValueIndex; if (curOption > EventFireController.NOTIFY_TARGET_OPTIONS.Direct) { EditorGUI.indentLevel += 1; content = new GUIContent ( "Spawn At Transform", "This transform is optionally used as the position at which an EventTrigger " + "prefab is spawned from. Some Utility components may also use this as a " + "position reference if chosen." ); EditorGUILayout.PropertyField(this.spawnEventTriggerAtTransform, content); if (curOption == EventFireController.NOTIFY_TARGET_OPTIONS.PassInfoToEventTrigger || curOption == EventFireController.NOTIFY_TARGET_OPTIONS.UseEventTriggerInfo) { content = new GUIContent ( "EventTrigger Prefab", "An optional EventTrigger to spawn OnFire depending on notifyTarget's " + "NOTIFY_TARGET_OPTIONS." ); EditorGUILayout.PropertyField(this.eventTriggerPrefab, content); } if (InstanceManager.POOLING_ENABLED) { if (this.eventTriggerPrefab.objectReferenceValue != null) { content = new GUIContent ( "Use Pooling", "If false, do not add the new instance to a pool. Use Unity's " + "Instantiate/Destroy" ); EditorGUILayout.PropertyField(this.usePooling, content); if (this.usePooling.boolValue) { EditorGUI.indentLevel += 1; content = new GUIContent ( "Override Pool", "If an eventTriggerPrefab is spawned, setting this to true will " + "override the EventTrigger's poolName and use this instead. The " + "instance will also be passed this EventFireController's " + "eventTriggerPoolName to be used when the EventTrigger is " + "desapwned." ); EditorGUILayout.PropertyField(this.overridePoolName, content); if (this.overridePoolName.boolValue) { content = new GUIContent ( "Pool Name", "The name of a pool to be used with PoolManager or other " + "pooling solution. If not using pooling, this will do " + "nothing and be hidden in the Inspector.\n" + "WARNING: If poolname is set to '', Pooling will be disabled " + "and Unity's Instantiate will be used." ); EditorGUILayout.PropertyField(this.eventTriggerPoolName, content); } EditorGUI.indentLevel -= 1; } } else { this.overridePoolName.boolValue = false; // Reset } } EditorGUI.indentLevel -= 1; } if (curOption != EventFireController.NOTIFY_TARGET_OPTIONS.UseEventTriggerInfo) { content = new GUIContent ( "Event Info List", "A list of event descriptions to be passed by struct to Targets" ); if (this.serializedObject.isEditingMultipleObjects) { EditorGUILayout.PropertyField(this.eventInfoList, content, true); } else { EditorGUI.indentLevel += 2; curEditTarget = (EventFireController)targetObjs[0]; this.expandEventInfoList = PGEditorUtils.SerializedObjFoldOutList <EventInfoListGUIBacker> ( content.text, curEditTarget._eventInfoList, this.expandEventInfoList, ref curEditTarget._editorListItemStates, true ); EditorGUI.indentLevel -= 2; } } // Init with the TargetTracker found on the same GameObject if possible for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventFireController)targetObjs[i]; if (curEditTarget.targetTracker == null) { curEditTarget.targetTracker = curEditTarget.GetComponent <AreaTargetTracker>(); } } GUILayout.Space(6); content = new GUIContent ( "TargetTracker", "This FireController's TargetTracker. Defaults to one on the same GameObject." ); EditorGUILayout.PropertyField(this.targetTracker, content); GUILayout.Space(8); content = new GUIContent("Debug Level", "Set it higher to see more verbose information."); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
protected override void OnInspectorGUIUpdate() { base.OnInspectorGUIUpdate(); GUIContent content; GUILayout.BeginHorizontal(); content = new GUIContent("Position", "Option to match the target's position."); EditorGUILayout.PropertyField(this.position, content); if (this.position.boolValue) { PGEditorUtils.ToggleButton(this.outputPosX, new GUIContent("X", "Toggle Costraint for this axis."), 24); PGEditorUtils.ToggleButton(this.outputPosY, new GUIContent("Y", "Toggle Costraint for this axis."), 24); PGEditorUtils.ToggleButton(this.outputPosZ, new GUIContent("Z", "Toggle Costraint for this axis."), 24); GUILayout.EndHorizontal(); EditorGUI.indentLevel += 1; content = new GUIContent("interpolation Mode", "Option to match the target's position."); EditorGUILayout.PropertyField(this.pos_interp, content); var posInterp = (SmoothTransformConstraint.INTERP_OPTIONS_POS) this.pos_interp.enumValueIndex; switch (posInterp) { case SmoothTransformConstraint.INTERP_OPTIONS_POS.DampLimited: content = new GUIContent("Time", "roughly how long it takes to match the target (lag)."); EditorGUILayout.PropertyField(this.positionSpeed, content); content = new GUIContent("Max Speed", "The speed limit. Causes more constant motion."); EditorGUILayout.PropertyField(this.positionMaxSpeed, content); break; case SmoothTransformConstraint.INTERP_OPTIONS_POS.Damp: content = new GUIContent("Time", "roughly how long it takes to match the target (lag)."); EditorGUILayout.PropertyField(this.positionSpeed, content); break; default: content = new GUIContent("Percent", "Controls lag."); EditorGUILayout.PropertyField(this.positionSpeed, content); break; } EditorGUI.indentLevel -= 1; } else { GUILayout.EndHorizontal(); } content = new GUIContent("Rotation", "Option to match the target's rotation."); EditorGUILayout.PropertyField(this.rotation, content); if (this.rotation.boolValue) { EditorGUI.indentLevel += 1; content = new GUIContent("Output", "Used to alter the way the rotations are set."); EditorGUILayout.PropertyField(this.output, content); content = new GUIContent ( "Interpolation Mode", "The type of rotation calculation to use. Linear is faster but spherical is more stable when " + "rotations make large adjustments.." ); EditorGUILayout.PropertyField(this.interpolation, content); content = new GUIContent("Speed", "How fast to rotate. Appears different depending on Mode."); EditorGUILayout.PropertyField(this.rotationSpeed, content); EditorGUI.indentLevel -= 1; } content = new GUIContent("Scale", "Option to match the target's scale."); EditorGUILayout.PropertyField(this.scale, content); if (this.scale.boolValue) { EditorGUI.indentLevel += 1; content = new GUIContent("Percent", "Controls lag."); EditorGUILayout.PropertyField(this.scaleSpeed, content); EditorGUI.indentLevel -= 1; } }
/// <summary> /// Adds a fold-out list GUI from a generic list of any serialized object type. /// Uses System.Reflection to add all fields for a passed serialized object /// instance. Handles most basic types including automatic naming like the /// inspector does by default /// /// Adds collapseBools (see docs below) /// </summary> /// <param name="label"> The field label</param> /// <param name="list">A generic List</param> /// <param name="expanded">A bool to determine the state of the primary fold-out</param> /// <param name="foldOutStates">Dictionary<object, bool> used to track list item states</param> /// <param name="collapseBools"> /// If true, bools on list items will collapse fields which follow them /// </param> /// <returns>The new foldout state from user input. Just like Unity's foldout</returns> public static bool SerializedObjFoldOutList <T>(string label, List <T> list, bool expanded, ref Dictionary <object, bool> foldOutStates, bool collapseBools) where T : new() { // Store the previous indent and return the flow to it at the end int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; int buttonSpacer = 6; #region Header Foldout // Use a Horizanal space or the toolbar will extend to the left no matter what EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel = 0; // Space will handle this for the header GUILayout.Space(indent * 6); // Matches the content indent EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); expanded = Foldout(expanded, label); if (!expanded) { // Don't add the '+' button when the contents are collapsed. Just quit. EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = indent; // Return to the last indent return(expanded); } // BUTTONS... EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100)); // Add expand/collapse buttons if there are items in the list bool masterCollapse = false; bool masterExpand = false; if (list.Count > 0) { GUIContent content; var collapseIcon = '\u2261'.ToString(); content = new GUIContent(collapseIcon, "Click to collapse all"); masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton); var expandIcon = '\u25A1'.ToString(); content = new GUIContent(expandIcon, "Click to expand all"); masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton); } else { GUILayout.FlexibleSpace(); } EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50)); // A little space between button groups GUILayout.Space(buttonSpacer); // Main Add button if (GUILayout.Button(new GUIContent("+", "Click to add"), EditorStyles.toolbarButton)) { list.Add(new T()); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); #endregion Header Foldout #region List Items // Use a for, instead of foreach, to avoid the iterator since we will be // be changing the loop in place when buttons are pressed. Even legal // changes can throw an error when changes are detected for (int i = 0; i < list.Count; i++) { T item = list[i]; #region Section Header // If there is a field with the name 'name' use it for our label string itemLabel = PGEditorUtils.GetSerializedObjFieldName <T>(item); if (itemLabel == "") { itemLabel = string.Format("Element {0}", i); } // Get the foldout state. // If this item is new, add it too (singleton) // Singleton works better than multiple Add() calls because we can do // it all at once, and in one place. bool foldOutState; if (!foldOutStates.TryGetValue(item, out foldOutState)) { foldOutStates[item] = true; foldOutState = true; } // Force states if master buttons were pressed if (masterCollapse) { foldOutState = false; } if (masterExpand) { foldOutState = true; } // Use a Horizanal space or the toolbar will extend to the start no matter what EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel = 0; // Space will handle this for the header GUILayout.Space((indent + 3) * 6); // Matches the content indent EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); // Display foldout with current state foldOutState = Foldout(foldOutState, itemLabel); foldOutStates[item] = foldOutState; // Used again below LIST_BUTTONS listButtonPressed = AddFoldOutListItemButtons(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); #endregion Section Header // If folded out, display all serialized fields if (foldOutState == true) { EditorGUI.indentLevel = indent + 3; // Display Fields for the list instance PGEditorUtils.SerializedObjectFields <T>(item, collapseBools); GUILayout.Space(2); } #region Process List Changes // Don't allow 'up' presses for the first list item switch (listButtonPressed) { case LIST_BUTTONS.None: // Nothing was pressed, do nothing break; case LIST_BUTTONS.Up: if (i > 0) { T shiftItem = list[i]; list.RemoveAt(i); list.Insert(i - 1, shiftItem); } break; case LIST_BUTTONS.Down: // Don't allow 'down' presses for the last list item if (i + 1 < list.Count) { T shiftItem = list[i]; list.RemoveAt(i); list.Insert(i + 1, shiftItem); } break; case LIST_BUTTONS.Remove: list.RemoveAt(i); foldOutStates.Remove(item); // Clean-up break; case LIST_BUTTONS.Add: list.Insert(i, new T()); break; } #endregion Process List Changes } #endregion List Items EditorGUI.indentLevel = indent; return(expanded); }
public override void OnInspectorGUI() { var script = (LineOfSightModifier)target; PGEditorUtils.LookLikeControls(); EditorGUI.indentLevel = 1; // Display some information GUILayout.Space(6); GUIStyle style = new GUIStyle(EditorStyles.textField); style.wordWrap = true; style.fontStyle = FontStyle.Italic; style.padding = new RectOffset(4, 4, 4, 4); EditorGUILayout.LabelField ( "Add layers to activate LOS filtering.\n" + " - Target Tracker to ignore targets\n" + " - Fire Controller to hold fire", style ); script.targetTrackerLayerMask = PGEditorUtils.LayerMaskField ( "Target Tracker Mask", script.targetTrackerLayerMask ); // Might as well set the component if we are going to do GetComponent. // Also works as a singleton, not that it matters much in Editor scripts. if (script.fireCtrl == null) { script.fireCtrl = script.GetComponent <FireController>(); } if (script.fireCtrl) { script.fireControllerLayerMask = PGEditorUtils.LayerMaskField ( "Fire Controller Mask", script.fireControllerLayerMask ); } GUILayout.Space(6); script.testMode = PGEditorUtils.EnumPopup <LineOfSightModifier.TEST_MODE> ( "LOS Test Mode", script.testMode ); if (script.testMode == LineOfSightModifier.TEST_MODE.SixPoint) { EditorGUI.indentLevel = 2; script.radius = EditorGUILayout.FloatField("Radius", script.radius); EditorGUI.indentLevel = 1; } GUILayout.Space(4); script.debugLevel = (DEBUG_LEVELS)EditorGUILayout.EnumPopup("Debug Level", (System.Enum)script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { var script = (TargetTracker)target; EditorGUI.indentLevel = 1; PGEditorUtils.LookLikeControls(); script.numberOfTargets = EditorGUILayout.IntField("Targets (-1 for all)", script.numberOfTargets); script.targetLayers = PGEditorUtils.LayerMaskField("Target Layers", script.targetLayers); script.sortingStyle = PGEditorUtils.EnumPopup <TargetTracker.SORTING_STYLES> ( "Sorting Style", script.sortingStyle ); if (script.sortingStyle != TargetTracker.SORTING_STYLES.None) { EditorGUI.indentLevel = 2; script.sortInterval = EditorGUILayout.FloatField("Minimum Interval", script.sortInterval); EditorGUI.indentLevel = 1; } EditorGUI.indentLevel = 0; this.showPerimeter = EditorGUILayout.Foldout(this.showPerimeter, "Perimeter Settings"); if (this.showPerimeter) { EditorGUI.indentLevel = 2; script.perimeterLayer = EditorGUILayout.LayerField("Perimeter Layer", script.perimeterLayer); EditorGUILayout.BeginHorizontal(); // Only trigger the update if it actually changes. This runs code in a peroperty // that may be expensive var shape = script.perimeterShape; shape = PGEditorUtils.EnumPopup <TargetTracker.PERIMETER_SHAPES>("Perimeter Shape", shape); if (shape != script.perimeterShape) { script.perimeterShape = shape; } GUILayout.Label("Gizmo", GUILayout.MaxWidth(40)); script.drawGizmo = EditorGUILayout.Toggle(script.drawGizmo, GUILayout.MaxWidth(47)); EditorGUILayout.EndHorizontal(); if (script.drawGizmo) { EditorGUI.indentLevel = 3; EditorGUILayout.BeginHorizontal(); script.gizmoColor = EditorGUILayout.ColorField("Gizmo Color", script.gizmoColor); GUIStyle style = EditorStyles.miniButton; style.alignment = TextAnchor.MiddleCenter; style.fixedWidth = 52; bool clicked = GUILayout.Toggle(false, "Reset", style); if (clicked) { script.gizmoColor = script.defaultGizmoColor; } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 2; GUILayout.Space(4); } Vector3 range = script.range; switch (script.perimeterShape) { case TargetTracker.PERIMETER_SHAPES.Sphere: range.x = EditorGUILayout.FloatField("Range", range.x); range.y = range.x; range.z = range.x; break; case TargetTracker.PERIMETER_SHAPES.Box: range = EditorGUILayout.Vector3Field("Range", range); break; case TargetTracker.PERIMETER_SHAPES.Capsule: range = EditorGUILayout.Vector2Field("Range", range); range.z = range.x; break; } script.range = range; script.perimeterPositionOffset = EditorGUILayout.Vector3Field("Position Offset", script.perimeterPositionOffset); script.perimeterRotationOffset = EditorGUILayout.Vector3Field("Rotation Offset", script.perimeterRotationOffset); } EditorGUI.indentLevel = 1; GUILayout.Space(4); script.debugLevel = (DEBUG_LEVELS)EditorGUILayout.EnumPopup("Debug Level", (System.Enum)script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
// Use this for initialization public override void OnInspectorGUI() { FontAnalyse script = (FontAnalyse)target; EditorGUI.indentLevel = 0; PGEditorUtils.LookLikeControls(); Rect sfxPathRect = EditorGUILayout.GetControlRect(); // 用刚刚获取的文本输入框的位置和大小参数,创建一个文本输入框,用于输入特效路径 EditorGUI.TextField(sfxPathRect, "ImgPath", script.ImgPath); // 判断当前鼠标正拖拽某对象或者在拖拽的过程中松开了鼠标按键 // 同时还需要判断拖拽时鼠标所在位置处于文本输入框内 if ((Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragExited) && sfxPathRect.Contains(Event.current.mousePosition)) { // 判断是否拖拽了文件 if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0) { string sfxPath = DragAndDrop.paths [0]; // 拖拽的过程中,松开鼠标之后,拖拽操作结束,此时就可以使用获得的 sfxPath 变量了 #if UNITY_EDITOR_OSX if (!string.IsNullOrEmpty(sfxPath) && Event.current.type == EventType.DragExited) { #else if (!string.IsNullOrEmpty(sfxPath) && Event.current.type == EventType.DragUpdated) { #endif DragAndDrop.AcceptDrag(); script.ImgPath = common.TextUtil.cut(sfxPath, "Resources/", false, false); } } } sfxPathRect = EditorGUILayout.GetControlRect(); // 用刚刚获取的文本输入框的位置和大小参数,创建一个文本输入框,用于输入特效路径 EditorGUI.TextField(sfxPathRect, "DataPath", script.DataPath); // 判断当前鼠标正拖拽某对象或者在拖拽的过程中松开了鼠标按键 // 同时还需要判断拖拽时鼠标所在位置处于文本输入框内 if ((Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragExited) && sfxPathRect.Contains(Event.current.mousePosition)) { // 判断是否拖拽了文件 if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0) { string sfxPath = DragAndDrop.paths [0]; // 拖拽的过程中,松开鼠标之后,拖拽操作结束,此时就可以使用获得的 sfxPath 变量了 #if UNITY_EDITOR_OSX if (!string.IsNullOrEmpty(sfxPath) && Event.current.type == EventType.DragExited) { #else if (!string.IsNullOrEmpty(sfxPath) && Event.current.type == EventType.DragUpdated) { #endif DragAndDrop.AcceptDrag(); script.DataPath = common.TextUtil.cut(sfxPath, "Resources/", false, false); } } } script.advanceAddition = EditorGUILayout.IntField("advanceAddition", script.advanceAddition); script.pixelPerUnit = EditorGUILayout.FloatField("pixelPerUnit", script.pixelPerUnit); // // script.matchPoolScale = EditorGUILayout.Toggle("Match Pool Scale", script.matchPoolScale); // script.matchPoolLayer = EditorGUILayout.Toggle("Match Pool Layer", script.matchPoolLayer); // // script.dontReparent = EditorGUILayout.Toggle("Don't Reparent", script.dontReparent); // // script._dontDestroyOnLoad = EditorGUILayout.Toggle("Don't Destroy On Load", script._dontDestroyOnLoad); // // script.logMessages = EditorGUILayout.Toggle("Log Messages", script.logMessages); EditorGUILayout.BeginHorizontal(); // 1/2 the item button width GUILayout.Space(0); // Master add at end button. List items will insert if (GUILayout.Button(new GUIContent("Generate", "Click to generate data"), EditorStyles.toolbarButton)) { if (script.ImgPath != null && script.DataPath != null) { script.slice(script.ImgPath, script.DataPath); CharacterGroup[] groups = FindObjectsOfType <CharacterGroup>(); for (int i = 0; i < groups.Length; i++) { groups[i].setTextInEditor(false); } } } if (GUILayout.Button(new GUIContent("Clear", "Click to generate data"), EditorStyles.toolbarButton)) { script.clear(); } EditorGUILayout.EndHorizontal(); this.expandPrefabs = PGEditorUtils.SerializedObjFoldOutList <FontData> ( "Per-Prefab Pool Options", script.fontDataList, this.expandPrefabs, ref script._editorListItemStates, true ); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } } }
public override void OnInspectorGUI() { this.serializedObject.Update(); Object[] targetObjs = this.serializedObject.targetObjects; FireDistanceModifier curEditTarget; GUIContent content; GUIStyle style; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; EditorGUI.indentLevel = 1; content = new GUIContent ( "Origin Mode", "The origin is the point from which the distance is measuered." ); EditorGUILayout.PropertyField(this.originMode, content); var noLabel = new GUIContent(""); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Distance:", GUILayout.MaxWidth(70)); EditorGUILayout.LabelField("Min", GUILayout.MaxWidth(40)); EditorGUILayout.PropertyField(this.minDistance, noLabel, GUILayout.MinWidth(40)); EditorGUILayout.LabelField("Max", GUILayout.MaxWidth(40)); EditorGUILayout.PropertyField(this.maxDistance, noLabel, GUILayout.MinWidth(40)); EditorGUILayout.EndHorizontal(); // GIZMO... EditorGUILayout.BeginHorizontal(); GUILayout.Space(12); // For some reason the button won't indent. So fake it. content = new GUIContent ( "Gizmo", "Visualize the distance in the Editor by turning this on." ); PGEditorUtils.ToggleButton(this.drawGizmo, content, 50); if (this.drawGizmo.boolValue) { EditorGUILayout.PropertyField(this.gizmoColor, noLabel, GUILayout.MinWidth(60)); style = EditorStyles.miniButton; style.alignment = TextAnchor.MiddleCenter; style.fixedWidth = 52; if (GUILayout.Button("Reset", style)) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (FireDistanceModifier)targetObjs[i]; curEditTarget.gizmoColor = curEditTarget.defaultGizmoColor; } } } EditorGUILayout.EndHorizontal(); GUILayout.Space(4); content = new GUIContent ( "Debug Level", "Set it higher to see more verbose information." ); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { var script = (TargetProMessenger)target; EditorGUI.indentLevel = 1; PGEditorUtils.LookLikeControls(); script.otherTarget = PGEditorUtils.ObjectField <GameObject> ( "Other Message Target (Optional)", script.otherTarget ); script.forComponent = (TargetProMessenger.COMPONENTS)EditorGUILayout.EnumPopup ( new GUIContent("For Component", "Choose which component's events to use"), script.forComponent ); script.messageMode = (TargetProMessenger.MESSAGE_MODE)EditorGUILayout.EnumPopup ( new GUIContent("Message Mode", "SendMessage will only send to this GameObject"), script.messageMode ); // Change the label spacing EditorGUIUtility.LookLikeControls(220); EditorGUI.indentLevel = 3; if (script.forComponent == TargetProMessenger.COMPONENTS.FireController) { script.fireController_OnStart = EditorGUILayout.Toggle("FireController_OnStart", script.fireController_OnStart); script.fireController_OnUpdate = EditorGUILayout.Toggle("FireController_OnUpdate", script.fireController_OnUpdate); script.fireController_OnTargetUpdate = EditorGUILayout.Toggle("FireController_OnTargetUpdate", script.fireController_OnTargetUpdate); script.fireController_OnIdleUpdate = EditorGUILayout.Toggle("FireController_OnIdleUpdate", script.fireController_OnIdleUpdate); script.fireController_OnFire = EditorGUILayout.Toggle("FireController_OnFire", script.fireController_OnFire); script.fireController_OnStop = EditorGUILayout.Toggle("FireController_OnStop", script.fireController_OnStop); } else if (script.forComponent == TargetProMessenger.COMPONENTS.Projectile) { script.projectile_OnLaunched = EditorGUILayout.Toggle("Projectile_OnLaunched", script.projectile_OnLaunched); script.projectile_OnLaunchedUpdate = EditorGUILayout.Toggle("Projectile_OnLaunchedUpdate", script.projectile_OnLaunchedUpdate); script.projectile_OnDetonation = EditorGUILayout.Toggle("Projectile_OnDetonation", script.projectile_OnDetonation); } else if (script.forComponent == TargetProMessenger.COMPONENTS.Targetable) { script.targetable_OnHit = EditorGUILayout.Toggle("Targetable_OnHit", script.targetable_OnHit); script.targetable_OnDetected = EditorGUILayout.Toggle("Targetable_OnDetected", script.targetable_OnDetected); script.targetable_OnNotDetected = EditorGUILayout.Toggle("Targetable_OnNotDetected", script.targetable_OnNotDetected); } EditorGUI.indentLevel = 1; GUILayout.Space(4); // Change the label spacing back PGEditorUtils.LookLikeControls(); script.debugLevel = PGEditorUtils.EnumPopup <DEBUG_LEVELS>("Debug Level", script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); GUIContent content; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; Object[] targetObjs = this.serializedObject.targetObjects; EventTrigger curEditTarget; if (InstanceManager.POOLING_ENABLED) { content = new GUIContent ( "PoolName", "The name of a pool to be used with PoolManager or other pooling solution. If " + "not using pooling, this will do nothing and be hidden in the Inspector. " ); EditorGUILayout.PropertyField(this.poolName, content); } content = new GUIContent ( "Hit Layers", "The layers in which the Area is allowed to find targets." ); EditorGUILayout.PropertyField(this.targetLayers, content); content = new GUIContent ( "Hit Mode", "Determines what should cause this EventTrigger to fire.\n" + " TargetOnly\n" + " Only a direct hit will trigger the OnFire event\n" + " HitLayers\n" + " Contact with any colliders in any of the layers in\n" + " the HitLayers mask will trigger the OnFire event." ); EditorGUILayout.PropertyField(this.hitMode, content); content = new GUIContent ( "listenTimeout (0 = OFF)", "An optional timer to allow this EventTrigger to timeout and self-destruct. When " + "set to a value above zero, when this reaches 0, the Fire coroutine will be " + "started and anything in range may be hit (depending on settings). This can be " + "used to give a projectile a max amount of time it can fly around before it " + "dies, or a time-based land mine or pick-up." ); EditorGUILayout.PropertyField(this.listenTimeout, content); content = new GUIContent ( "Fire On Spawn", "If true, the event will be fired as soon as this EventTrigger is spawned by " + "instantiation or pooling." ); EditorGUILayout.PropertyField(this.fireOnSpawn, content); content = new GUIContent ( "Fire On Sleep", "If this EventTrigger has a rigidbody, setting this to true will cause it to " + "fire if it falls asleep. See Unity's docs for more information on how " + "this happens." ); EditorGUILayout.PropertyField(this.fireOnRigidBodySleep, content); content = new GUIContent ( "Area Hit", "If true, more than just the primary target will be affected when this EventTrigger " + "fires. Use the range options to determine the behavior." ); EditorGUILayout.PropertyField(this.areaHit, content); // To make the gizmo delay work correctly, update the GUI here. serializedObject.ApplyModifiedProperties(); if (this.areaHit.boolValue) { this.overrideGizmoVisibility.boolValue = false; EditorGUI.indentLevel += 1; content = new GUIContent( "Targets (-1 = all)", "The number of targets to return. Set to -1 to return all targets" ); EditorGUILayout.PropertyField(this.numberOfTargets, content); content = new GUIContent("Sorting Style", "The style of sorting to use"); EditorGUILayout.PropertyField(this.sortingStyle, content); var sortingStyle = (EventTrigger.SORTING_STYLES) this.sortingStyle.enumValueIndex; if (sortingStyle != EventTrigger.SORTING_STYLES.None) { EditorGUI.indentLevel += 1; content = new GUIContent( "Minimum Interval", "How often the target list will be sorted. If set to 0, " + "sorting will only be triggered when Targets enter or exit range." ); EditorGUILayout.PropertyField(this.updateInterval, content); EditorGUI.indentLevel -= 1; } EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Area Layer", "The layer to put the Area in." ); content = EditorGUI.BeginProperty(new Rect(0, 0, 0, 0), content, this.areaLayer); int layer = EditorGUILayout.LayerField(content, this.areaLayer.intValue); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventTrigger)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " Area Layer"); curEditTarget.areaLayer = layer; } } EditorGUI.EndProperty(); EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Area Shape", "The shape of the Area used to detect targets in range" ); EditorGUILayout.PropertyField(this.areaShape, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { var shape = (AreaTargetTracker.AREA_SHAPES) this.areaShape.enumValueIndex; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventTrigger)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " areaShape"); curEditTarget.areaShape = shape; } } content = new GUIContent ( "Gizmo ", "Visualize the Area in the Editor by turning this on." ); PGEditorUtils.ToggleButton(this.drawGizmo, content, 50); EditorGUILayout.EndHorizontal(); if (this.drawGizmo.boolValue) { EditorGUI.indentLevel += 1; EditorGUILayout.BeginHorizontal(); content = new GUIContent ( "Gizmo Color", "The color of the gizmo when displayed" ); EditorGUILayout.PropertyField(this.gizmoColor, content); // If clicked, reset the color to the default GUIStyle style = EditorStyles.miniButton; style.alignment = TextAnchor.MiddleCenter; style.fixedWidth = 52; if (GUILayout.Button("Reset", style)) { for (int i = 0; i < this.serializedObject.targetObjects.Length; i++) { curEditTarget = (EventTrigger)this.serializedObject.targetObjects[i]; curEditTarget.gizmoColor = curEditTarget.defaultGizmoColor; } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel -= 1; GUILayout.Space(4); } content = new GUIContent ( "Duration (<0 = stay)", "An optional duration to control how long this EventTrigger stays active. " + "Each target will only be hit once with the event notification unless the " + "Target leaves and then re-enters range. Set this to -1 to keep it alive " + "forever." ); EditorGUILayout.PropertyField(this.duration, content); serializedObject.ApplyModifiedProperties(); if (this.duration.floatValue > 0) { EditorGUI.indentLevel += 1; content = new GUIContent ( "Start Range", "When duration is greater than 0 this can be used have the range change " + "over the course of the duration. This is used for things like a " + "chockwave from a large explosion, which grows over time. " ); content = EditorGUI.BeginProperty(new Rect(0, 0, 0, 0), content, this.startRange); EditorGUI.BeginChangeCheck(); Vector3 startRange = this.startRange.vector3Value; switch ((AreaTargetTracker.AREA_SHAPES) this.areaShape.enumValueIndex) { case AreaTargetTracker.AREA_SHAPES.Circle2D: // Fallthrough case AreaTargetTracker.AREA_SHAPES.Sphere: startRange.x = EditorGUILayout.FloatField(content, startRange.x); startRange.y = startRange.x; startRange.z = startRange.x; break; case AreaTargetTracker.AREA_SHAPES.Box2D: float oldZ = startRange.z; startRange = EditorGUILayout.Vector2Field(content.text, startRange); startRange.z = oldZ; // Nice to maintain if switching between 2D and 3D break; case AreaTargetTracker.AREA_SHAPES.Box: startRange = EditorGUILayout.Vector3Field(content.text, startRange); break; case AreaTargetTracker.AREA_SHAPES.Capsule: startRange = EditorGUILayout.Vector2Field(content.text, startRange); startRange.z = startRange.x; break; } // Only assign the value back if it was actually changed by the user. // Otherwise a single value will be assigned to all objects when multi-object // editing, even when the user didn't touch the control. if (EditorGUI.EndChangeCheck()) { this.startRange.vector3Value = startRange; } EditorGUI.EndProperty(); EditorGUI.indentLevel -= 1; } this.displayRange <EventTrigger>(targetObjs); EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Position Offset", "An optional position offset for the Area. For example, if you have an" + "object resting on the ground which has a range of 4, a position offset of" + "Vector3(0, 4, 0) will place your Area so it is also sitting on the ground." ); EditorGUILayout.PropertyField(this.areaPositionOffset, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { string undo_message = targetObjs[0].GetType() + " areaPositionOffset"; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventTrigger)targetObjs[i]; Undo.RecordObject(curEditTarget, undo_message); curEditTarget.areaPositionOffset = this.areaPositionOffset.vector3Value; } } EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Rotation Offset", "An optional rotational offset for the Area." ); EditorGUILayout.PropertyField(this.areaRotationOffset, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { string undo_message = targetObjs[0].GetType() + " areaPositionOffset"; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (EventTrigger)targetObjs[i]; Undo.RecordObject(curEditTarget, undo_message); curEditTarget.areaRotationOffset = this.areaRotationOffset.vector3Value; } } GUILayout.Space(8); } else { this.overrideGizmoVisibility.boolValue = true; } content = new GUIContent ( "Notify Targets", "Sets the target notification behavior. Telling targets they are hit is optional " + "for situations where a delayed response is required, such as launching a , " + "projectile or for custom handling.\n" + "\n" + "MODES\n" + " Off\n" + " Do not notify anything. delegates can still be used\n" + " for custom handling\n" + " Direct\n" + " OnFire targets will be notified immediately\n" + " PassInfoToEventTrigger\n" + " For every Target hit, a new EventTrigger will be\n" + " spawned and passed this EventTrigger's \n" + " EventInfo. PassToEventTriggerOnce is more \n" + " commonly used when secondary EventTrigger is\n" + " needed, but this can be used for some creative\n" + " or edge use-cases.\n" + " PassInfoToEventTriggerOnce\n" + " OnFire a new EventTrigger will be spawned and\n" + " passed this EventTrigger's EventInfo. Only 1 will\n" + " be spawned. This is handy for making bombs \n" + " where only the first Target would trigger the \n" + " event and only 1 EventTrigger would be spawned\n" + " to expand over time (using duration and start\n" + " range attributes).\n" + " UseEventTriggerInfo\n" + " Same as PassInfoToEventTrigger but the new\n" + " EventTrigger will use its own EventInfo (this \n" + " EventTrigger's EventInfo will be ignored).\n" + " UseEventTriggerInfoOnce\n" + " Same as PassInfoToEventTriggerOnce but the new\n" + " EventTrigger will will used its own EventInfo\n" + " (this EventTrigger's EventInfo will be ignored)." ); EditorGUILayout.PropertyField(this.notifyTargets, content); // // If using EventTrigger... // EventTrigger.NOTIFY_TARGET_OPTIONS curOption; curOption = (EventTrigger.NOTIFY_TARGET_OPTIONS) this.notifyTargets.enumValueIndex; if (curOption > EventTrigger.NOTIFY_TARGET_OPTIONS.Direct) { EditorGUI.indentLevel += 1; content = new GUIContent ( "EventTrigger Prefab", "An optional prefab to instance another EventTrigger. This can be handy if you " + "want to use a 'one-shot' event trigger to then spawn one that expands over " + "time using the duration and startRange to simulate a huge explosion." ); EditorGUILayout.PropertyField(this.eventTriggerPrefab, content); if (InstanceManager.POOLING_ENABLED) { EditorGUI.indentLevel += 1; if (this.eventTriggerPrefab.objectReferenceValue != null) { content = new GUIContent ( "Use Pooling", "If false, do not add the new instance to a pool. Use Unity's " + "Instantiate/Destroy" ); EditorGUILayout.PropertyField(this.usePooling, content); if (this.usePooling.boolValue) { content = new GUIContent ( "Override Pool Name", "If an eventTriggerPrefab is spawned, setting this to true will " + "override the EventTrigger's poolName and use this instead. The " + "instance will also be passed this EventTrigger's " + "eventTriggerPoolName to be used when the EventTrigger is " + "desapwned." ); EditorGUILayout.PropertyField(this.overridePoolName, content); if (this.overridePoolName.boolValue) { content = new GUIContent ( "Pool Name", "The name of a pool to be used with PoolManager or other " + "pooling solution. If not using pooling, this will do " + "nothing and be hidden in the Inspector.\n" + "WARNING: If poolname is set to '', Pooling will be " + "disabled and Unity's Instantiate will be used." ); EditorGUILayout.PropertyField(this.eventTriggerPoolName, content); } } EditorGUI.indentLevel -= 1; } else { this.overridePoolName.boolValue = false; // Reset } } EditorGUI.indentLevel -= 1; } if (curOption < EventTrigger.NOTIFY_TARGET_OPTIONS.UseEventTriggerInfo) { if (this.serializedObject.isEditingMultipleObjects) { content = new GUIContent ( "Event Info List", "A list of EventInfo structs which hold one or more event descriptions of how " + "this EventTrigger can affect a Target." ); EditorGUILayout.PropertyField(this.eventInfoList, content, true); } else { EditorGUI.indentLevel += 2; curEditTarget = (EventTrigger)targetObjs[0]; this.expandEventInfo = PGEditorUtils.SerializedObjFoldOutList <EventInfoListGUIBacker> ( "Event Info List", curEditTarget._eventInfoList, this.expandEventInfo, ref curEditTarget._editorListItemStates, true ); EditorGUI.indentLevel -= 2; } } GUILayout.Space(4); content = new GUIContent ( "Debug Level", "Set it higher to see more verbose information." ); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { var script = (Detonator)target; GUIStyle style; PGEditorUtils.LookLikeControls(); EditorGUI.indentLevel = 1; script.targetLayers = PGEditorUtils.LayerMaskField ( "Hit Layers", script.targetLayers ); script.perimeterLayer = EditorGUILayout.LayerField("Range Layer", script.perimeterLayer); EditorGUILayout.BeginHorizontal(); // Only trigger the update if it actually changes. This runs code in a peroperty // that may be expensive var shape = script.perimeterShape; shape = PGEditorUtils.EnumPopup <TargetTracker.PERIMETER_SHAPES>("Detonation Shape", shape); if (shape != script.perimeterShape) { script.perimeterShape = shape; } script.overrideGizmoVisibility = false; GUILayout.Label("Gizmo", GUILayout.MaxWidth(40)); script.drawGizmo = EditorGUILayout.Toggle(script.drawGizmo, GUILayout.MaxWidth(47)); EditorGUILayout.EndHorizontal(); if (script.drawGizmo) { EditorGUI.indentLevel = 3; EditorGUILayout.BeginHorizontal(); script.gizmoColor = EditorGUILayout.ColorField("Gizmo Color", script.gizmoColor); style = EditorStyles.miniButton; style.alignment = TextAnchor.MiddleCenter; style.fixedWidth = 52; bool clicked = GUILayout.Toggle(false, "Reset", style); if (clicked) { script.gizmoColor = script.defaultGizmoColor; } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = 2; GUILayout.Space(4); } script.durration = EditorGUILayout.FloatField("Expand Durration", script.durration); // Display some information GUILayout.Space(6); style = new GUIStyle(EditorStyles.label); style.wordWrap = true; style.fontStyle = FontStyle.Italic; GUILayout.Label ( "If spawned by a projectile, " + "the folowing range and effects are inherited from the projectile...", style ); Vector3 range = script.range; switch (script.perimeterShape) { case TargetTracker.PERIMETER_SHAPES.Sphere: range.x = EditorGUILayout.FloatField("Max Range", range.x); range.y = range.x; range.z = range.x; break; case TargetTracker.PERIMETER_SHAPES.Box: range = EditorGUILayout.Vector3Field("Max Range", range); break; case TargetTracker.PERIMETER_SHAPES.Capsule: range = EditorGUILayout.Vector2Field("Max Range", range); range.z = range.x; break; } script.range = range; GUILayout.Space(6); this.expandEffects = PGEditorUtils.SerializedObjFoldOutList <HitEffectGUIBacker> ( "EffectOnTargets", script._effectsOnTarget, this.expandEffects, ref script._editorListItemStates, true ); GUILayout.Space(4); script.debugLevel = (DEBUG_LEVELS)EditorGUILayout.EnumPopup("Debug Level", (System.Enum)script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); GUIContent content; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; Object[] targetObjs = this.serializedObject.targetObjects; AreaTargetTracker curEditTarget; content = new GUIContent( "Targets (-1 for all)", "The number of targets to return. Set to -1 to return all targets" ); EditorGUILayout.PropertyField(this.numberOfTargets, content); content = new GUIContent ( "Target Layers", "The layers in which the area is allowed to find targets." ); EditorGUILayout.PropertyField(this.targetLayers, content); EditorGUI.BeginChangeCheck(); content = new GUIContent("Sorting Style", "The style of sorting to use"); EditorGUILayout.PropertyField(this.sortingStyle, content); var sortingStyle = (TargetTracker.SORTING_STYLES) this.sortingStyle.enumValueIndex; // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " sortingStyle"); curEditTarget.sortingStyle = sortingStyle; } } if (sortingStyle != TargetTracker.SORTING_STYLES.None) { EditorGUI.indentLevel += 1; content = new GUIContent( "Minimum Interval", "How often the target list will be sorted. If set to 0, " + "sorting will only be triggered when Targets enter or exit range." ); EditorGUILayout.PropertyField(this.updateInterval, content); EditorGUI.indentLevel -= 1; } this.showArea = EditorGUILayout.Foldout(this.showArea, "Area Settings"); if (this.showArea) { EditorGUI.indentLevel += 1; EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Area Layer", "The layer to put the area in." ); content = EditorGUI.BeginProperty(new Rect(0, 0, 0, 0), content, this.areaLayer); int layer = EditorGUILayout.LayerField(content, this.areaLayer.intValue); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " areaLayer"); curEditTarget.areaLayer = layer; } } EditorGUI.EndProperty(); EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Area Shape", "The shape of the area used to detect targets in range" ); EditorGUILayout.PropertyField(this.areaShape, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { var shape = (AreaTargetTracker.AREA_SHAPES) this.areaShape.enumValueIndex; string undo_message = targetObjs[0].GetType() + " areaShape"; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; if (curEditTarget.area != null) // Only works at runtime. { // // This would have happened anyway, but this way is undoable // if (curEditTarget.area.coll != null) // { // Undo.DestroyObjectImmediate(curEditTarget.area.coll); // } // else if (curEditTarget.area.coll2D != null) // { // Undo.DestroyObjectImmediate(curEditTarget.area.coll2D); // } Undo.RecordObject(curEditTarget.area.transform, undo_message); } Undo.RecordObject(curEditTarget, undo_message); // Property. Handles collider changes at runtime. curEditTarget.areaShape = shape; } } Area area; bool ok; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; area = curEditTarget.area; ok = false; if (area == null) { continue; } if (area.coll != null) { switch (curEditTarget.areaShape) { case AreaTargetTracker.AREA_SHAPES.Sphere: if (area.coll is SphereCollider) { ok = true; } break; case AreaTargetTracker.AREA_SHAPES.Box: if (area.coll is BoxCollider) { ok = true; } break; case AreaTargetTracker.AREA_SHAPES.Capsule: if (area.coll is CapsuleCollider) { ok = true; } break; } } else if (area.coll2D != null) { switch (curEditTarget.areaShape) { case AreaTargetTracker.AREA_SHAPES.Box2D: if (area.coll2D is BoxCollider2D) { ok = true; } break; case AreaTargetTracker.AREA_SHAPES.Circle2D: if (area.coll2D is CircleCollider2D) { ok = true; } break; } } if (!ok) { var shape = (AreaTargetTracker.AREA_SHAPES) this.areaShape.enumValueIndex; curEditTarget.areaShape = shape; } } content = new GUIContent ( "Gizmo ", "Visualize the area in the Editor by turning this on." ); PGEditorUtils.ToggleButton(this.drawGizmo, content, 50); //script.drawGizmo = EditorGUILayout.Toggle(script.drawGizmo, GUILayout.MaxWidth(47)); EditorGUILayout.EndHorizontal(); if (this.drawGizmo.boolValue) { EditorGUI.indentLevel += 1; EditorGUILayout.BeginHorizontal(); content = new GUIContent ( "Gizmo Color", "The color of the gizmo when displayed" ); EditorGUILayout.PropertyField(this.gizmoColor, content); // If clicked, reset the color to the default GUIStyle style = EditorStyles.miniButton; style.alignment = TextAnchor.MiddleCenter; style.fixedWidth = 52; if (GUILayout.Button("Reset", style)) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; curEditTarget.gizmoColor = curEditTarget.defaultGizmoColor; } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel -= 1; GUILayout.Space(4); } this.displayRange <AreaTargetTracker>(targetObjs); EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Position Offset", "An optional position offset for the area. For example, if you have an" + "object resting on the ground which has a range of 4, a position offset of" + "Vector3(0, 4, 0) will place your area so it is also sitting on the ground." ); EditorGUILayout.PropertyField(this.areaPositionOffset, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { string undo_message = targetObjs[0].GetType() + " areaPositionOffset"; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; Undo.RecordObject(curEditTarget, undo_message); if (curEditTarget.area != null) // Only works at runtime. { Undo.RecordObject(curEditTarget.area.transform, undo_message); } curEditTarget.areaPositionOffset = this.areaPositionOffset.vector3Value; } } EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Rotation Offset", "An optional rotational offset for the area." ); EditorGUILayout.PropertyField(this.areaRotationOffset, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { string undo_message = targetObjs[0].GetType() + " areaPositionOffset"; for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AreaTargetTracker)targetObjs[i]; Undo.RecordObject(curEditTarget, undo_message); if (curEditTarget.area != null) // Only works at runtime. { Undo.RecordObject(curEditTarget.area.transform, undo_message); } curEditTarget.areaRotationOffset = this.areaRotationOffset.vector3Value; } } } EditorGUI.indentLevel -= 1; GUILayout.Space(8); content = new GUIContent ( "Debug Level", "Set it higher to see more verbose information." ); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); Object[] targetObjs = this.serializedObject.targetObjects; AngleLimitModifier curEditTarget; GUIContent content; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; EditorGUI.indentLevel = 0; EditorGUI.BeginChangeCheck(); content = new GUIContent ( "Origin", "The transform used to determine alignment. If not used, this will be the transform " + "of the GameObject this component is attached to." ); EditorGUILayout.PropertyField(this.origin, content); // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (AngleLimitModifier)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " origin"); curEditTarget.origin = (Transform)this.origin.objectReferenceValue; } } EditorGUILayout.BeginHorizontal(); EditorGUIUtility.labelWidth = 106; content = new GUIContent ( "Angle Tolerance", "If waitForAlignment is true: If the emitter is pointing towards " + "the target within this angle in degrees, the target can be fired on." ); EditorGUILayout.PropertyField(this.angle, content); EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; content = new GUIContent ( "Flat Comparison", "If false the actual angles will be compared for alignment. " + "(More precise. Emitter must point at target.)\n" + "If true, only the direction matters. " + "(Good when turning in a direction but perfect alignment isn't needed.)" ); PGEditorUtils.ToggleButton(this.flatAngleCompare, content, 88); EditorGUILayout.EndHorizontal(); if (this.flatAngleCompare.boolValue) { EditorGUI.indentLevel += 1; EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); // To make the rest of the row right-justified content = new GUIContent ( "Flatten Axis", "The axis to flatten when comparing angles to see if alignment has occurred. " + "For example, for a 2D game, this should be Z. For a 3D game that wants to " + "ignore altitude, set this to Y." ); EditorGUILayout.PropertyField(this.flatCompareAxis, content, GUILayout.Width(228)); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel -= 1; } content = new GUIContent ( "Filter Type", "Determines if filtering will be performed on a TargetTracker's targets or an " + "EventTrigger's targets. See the component description for more detail. This is" + "ignored unless a its GameObject has both. Otherwise the mode will be " + "auto-detected." ); EditorGUILayout.PropertyField(this.filterType, content); GUILayout.Space(4); content = new GUIContent ( "Debug Level", "Set it higher to see more verbose information." ); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }
protected override void OnInspectorGUIUpdate() { var script = (WorldTo2DCameraConstraint)target; script.targetCamera = PGEditorUtils.ObjectField <Camera>("Target Camera", script.targetCamera); script.orthoCamera = PGEditorUtils.ObjectField <Camera>("Output Camera", script.orthoCamera); EditorGUILayout.Space(); script.offsetMode = PGEditorUtils.EnumPopup <WorldTo2DCameraConstraint.OFFSET_MODE> ( "Offset Mode", script.offsetMode ); script.offset = EditorGUILayout.Vector3Field("Offset", script.offset); EditorGUILayout.Space(); script.offScreenMode = PGEditorUtils.EnumPopup <WorldTo2DCameraConstraint.OFFSCREEN_MODE> ( "Offscreen Mode", script.offScreenMode ); EditorGUI.indentLevel += 2; if (script.offScreenMode != WorldTo2DCameraConstraint.OFFSCREEN_MODE.Constrain) { script.offscreenThreasholdH = EditorGUILayout.Vector2Field("Height Threashold", script.offscreenThreasholdH); script.offscreenThreasholdW = EditorGUILayout.Vector2Field("Width Threashold", script.offscreenThreasholdW); } EditorGUI.indentLevel -= 2; EditorGUILayout.Space(); base.OnInspectorGUIUpdate(); // Set some singletone defaults (will only run once).. // This will actually run when the inspector changes, but still better than // running every update if (this.cameras == null) { this.cameras = FindObjectsOfType(typeof(Camera)) as Camera[]; } // Default to the first ortho camera that is set to render this object if (script.orthoCamera == null) { foreach (Camera cam in cameras) { if (!cam.orthographic) { continue; } if ((cam.cullingMask & 1 << script.gameObject.layer) > 0) { script.orthoCamera = cam; break; } } } // Default to the first camera that is set to render the target if (script.target != null && script.targetCamera == null) { foreach (Camera cam in cameras) { if ((cam.cullingMask & 1 << script.target.gameObject.layer) > 0) { script.targetCamera = cam; break; } } } }
public override void OnInspectorGUI() { var script = (FireController)target; GUIContent content; EditorGUI.indentLevel = 1; PGEditorUtils.LookLikeControls(); content = new GUIContent("Interval", "Fire every X seconds"); script.interval = EditorGUILayout.FloatField(content, script.interval); content = new GUIContent ( "Init Countdown at 0", "Able to fire immediatly when first spawned, before interval count begins" ); script.initIntervalCountdownAtZero = EditorGUILayout.Toggle(content, script.initIntervalCountdownAtZero); content = new GUIContent ( "Wait For Alignment", "Wait for the emitter to line up with the target before fireing. The " + "count will continue so this will fire as soon as possible." ); script.waitForAlignment = EditorGUILayout.Toggle(content, script.waitForAlignment); if (script.waitForAlignment) { EditorGUI.indentLevel = 2; script.emitter = PGEditorUtils.ObjectField <Transform>("Emitter (Optional)", script.emitter); content = new GUIContent ( "Angle Tolerance", "If waitForAlignment is true: If the emitter is pointing towards " + "the target within this angle in degrees, the target can be fired on." ); script.lockOnAngleTolerance = EditorGUILayout.FloatField(content, script.lockOnAngleTolerance); content = new GUIContent ( "Flat Comparison", "If false the true angles will be compared for alignment. " + "(More precise. Emitter must point at target.)\n" + "If true, only the direction matters. " + "(Good when turning in a direction but perfect alignment isn't needed.)" ); script.flatAngleCompare = EditorGUILayout.Toggle(content, script.flatAngleCompare); EditorGUI.indentLevel = 1; } script.notifyTargets = PGEditorUtils.EnumPopup <FireController.NOTIFY_TARGET_OPTIONS> ( "Notify Targets", script.notifyTargets ); if (script.notifyTargets > FireController.NOTIFY_TARGET_OPTIONS.Off) { script.ammoPrefab = PGEditorUtils.ObjectField <Transform> ( "Ammo (Optional)", script.ammoPrefab ); } EditorGUI.indentLevel = 2; this.expandEffects = PGEditorUtils.SerializedObjFoldOutList <HitEffectGUIBacker> ( "EffectOnTargets", script._effectsOnTarget, this.expandEffects, ref script._editorListItemStates, true ); EditorGUI.indentLevel = 1; GUILayout.Space(4); script.debugLevel = PGEditorUtils.EnumPopup <DEBUG_LEVELS>("Debug Level", script.debugLevel); // Flag Unity to save the changes to to the prefab to disk if (GUI.changed) { EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); GUIContent content; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = PGEditorUtils.CONTROLS_DEFAULT_LABEL_WIDTH; Object[] targetObjs = this.serializedObject.targetObjects; CompoundTargetTracker curEditTarget; EditorGUILayout.PropertyField(this.numberOfTargets, new GUIContent("Targets (-1 for all)")); EditorGUI.BeginChangeCheck(); content = new GUIContent("Sorting Style", "The style of sorting to use"); EditorGUILayout.PropertyField(this.sortingStyle, content); var sortingStyle = (TargetTracker.SORTING_STYLES) this.sortingStyle.enumValueIndex; // If changed, trigger the property setter for all objects being edited if (EditorGUI.EndChangeCheck()) { for (int i = 0; i < targetObjs.Length; i++) { curEditTarget = (CompoundTargetTracker)targetObjs[i]; Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " sortingStyle"); curEditTarget.sortingStyle = sortingStyle; } } if (sortingStyle != TargetTracker.SORTING_STYLES.None) { EditorGUI.indentLevel += 1; content = new GUIContent( "Minimum Interval", "How often the target list will be sorted. If set to 0, " + "sorting will only be triggered when Targets enter or exit range." ); EditorGUILayout.PropertyField(this.updateInterval, content); EditorGUI.indentLevel -= 1; } GUILayout.Space(8); // If multi-selected, use Unity's display. Much easier in this case. if (serializedObject.isEditingMultipleObjects) { content = new GUIContent ( "TargetTrackers", "The TargetTrackers whos targets will be combined by this CompoundTargetTracker." ); EditorGUILayout.PropertyField(this.targetTrackers, content, true); } else { curEditTarget = (CompoundTargetTracker)targetObjs[0]; // Track changes so we only register undo entries when needed. EditorGUI.BeginChangeCheck(); var targetTrackersCopy = new List <TargetTracker>(curEditTarget.targetTrackers); PGEditorUtils.FoldOutObjList <TargetTracker> ( "TargetTrackers", targetTrackersCopy, true ); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(curEditTarget, targetObjs[0].GetType() + " targetTrackers"); curEditTarget.targetTrackers.Clear(); curEditTarget.targetTrackers.AddRange(targetTrackersCopy); } } GUILayout.Space(4); EditorGUILayout.BeginHorizontal(); content = new GUIContent ( "Show All Gizmos", "Click to force all TargetTracker gizmos to be visibile to visualize the Area " + "in the Editor." ); this.GizmoVisibilityButton(targetObjs, content, true); content = new GUIContent ( "Hide All Gizmos", "Click to force all TargetTracker gizmos to be hidden." ); this.GizmoVisibilityButton(targetObjs, content, false); EditorGUILayout.EndHorizontal(); GUILayout.Space(8); content = new GUIContent("Debug Level", "Set it higher to see more verbose information."); EditorGUILayout.PropertyField(this.debugLevel, content); serializedObject.ApplyModifiedProperties(); // Flag Unity to save the changes to to the prefab to disk // This is needed to make the gizmos update immediatly. if (GUI.changed) { EditorUtility.SetDirty(target); } }