浏览代码

Globals Debug Window + Renamed OnGlobalLogic > GlobalLogic + Reset State Objects option in state machines + Fixes in TimerDisplayRig

/main
Thomas ICHÉ 5 年前
当前提交
c30239a4
共有 11 个文件被更改,包括 422 次插入171 次删除
  1. 17
      CHANGELOG.md
  2. 3
      Runtime/Ingredients/StateMachine/StateMachine.cs
  3. 29
      Runtime/Ingredients/Timer/TimerDisplayRig.cs
  4. 50
      Runtime/Managers/Globals/Globals.cs
  5. 8
      Editor/GlobalsDebugWindow.meta
  6. 205
      Runtime/Managers/Globals/GlobalLogic.cs
  7. 122
      Editor/GlobalsDebugWindow/GlobalsDebugWindow.cs
  8. 11
      Editor/GlobalsDebugWindow/GlobalsDebugWindow.cs.meta
  9. 148
      Runtime/Managers/Globals/OnGlobalLogic.cs
  10. 0
      /Runtime/Managers/Globals/GlobalLogic.cs.meta

17
CHANGELOG.md


* **Call Tree Explorer :** Using Window/Gameplay Ingredients/Call Tree Explorer , opens a window that lists the tree of Events, Logic and Actions, State Machines and Event Calling Actions
* **Folders:** In the Game Object creation Menu, Select folder to add a folder in the hierarchy. Automatically adds Static Game Objects with colored icon (Displayed using Advanced Hierarchy View)
* **Global Variables System**
- Added Global Variables (Globals + Local Scope)
- Added Global Variable Debug Window
- Added Global Variable Set Action
- Added Global Variable Logic
- Added Global Variables Reset Action
* **Timers**
* Added Timer Component
* Added TimerAction to control Timer
* Added TimerDisplayRig
* Added option in GameplayIngredientsSettings to disable visibility of Callable[] bound to Update Loops.
* Added OnUpdate Event : Perform calls every update
* Added OnColider Event : Perform calls upon collisions

* Added RigidBody Action : Perform actions on a rigidbody
* Added SetAnimatorParameterAction : Perform parameter setting on Animators
* Added Sacrifice Oldest option to Factory : When needing a new spawn but no slots left, sacrifices the first spawn of the list
* Added Timer Component
* Added TimerAction to control Timer
* Added TimerDisplayRig
* Added Global Variables (Globals + Local Scope)
* Added Global Variable Set Action
* Added Global Variable Logic
* Added Global Variables Reset Action
* Added Context Menu in ToggleGameObjectAction to update entries based on current enabled state in scene.
#### Changed

3
Runtime/Ingredients/StateMachine/StateMachine.cs


State m_CurrentState;
private void OnValidate()
[ContextMenu("Reset State Objects")]
private void UpdateFromState()
{
foreach(var state in States)
{

29
Runtime/Ingredients/Timer/TimerDisplayRig.cs


[InfoBox("Use the following wildcards:\n - %h : hours\n - %m : minutes\n - %s : seconds\n - %x : milliseconds", InfoBoxType.Normal)]
public string format = "%h:%m:%s:%x";
private void OnValidate()
{
UpdateText();
}
private void Reset()
{
UpdateText();
}
UpdateText();
}
void UpdateText()
{
value = value.Replace("%h", timer.CurrentHours.ToString("D2"));
value = value.Replace("%m", timer.CurrentMinutes.ToString("D2"));
value = value.Replace("%s", timer.CurrentSeconds.ToString("D2"));
value = value.Replace("%x", timer.CurrentMilliseconds.ToString("D3"));
uint hours = timer != null ? timer.CurrentHours: 0;
uint minutes = timer != null ? timer.CurrentMinutes : 0;
uint seconds = timer != null ? timer.CurrentSeconds : 0;
uint milliseconds = timer != null ? timer.CurrentMilliseconds : 0;
value = value.Replace("%h", hours.ToString("D2"));
value = value.Replace("%m", minutes.ToString("D2"));
value = value.Replace("%s", seconds.ToString("D2"));
value = value.Replace("%x", milliseconds.ToString("D3"));
if (text != null)
text.text = value;

50
Runtime/Managers/Globals/Globals.cs


return globalFloats[name];
}
}
public static bool GetObject(string name, Scope scope)
public static GameObject GetObject(string name, Scope scope)
{
switch (scope)
{

{
default:
case Scope.Local:
SetValue(localBooleans, name, value); return;
SetValue(localBooleans, name, value); break;
SetValue(globalBooleans, name, value); return;
SetValue(globalBooleans, name, value); break;
if (OnGlobalsUpdated != null)
OnGlobalsUpdated(Type.Boolean, name, value);
return;
}
public static void SetInt(string name, int value, Scope scope)
{

case Scope.Local:
SetValue(localInts, name, value); return;
SetValue(localInts, name, value); break;
SetValue(globalInts, name, value); return;
SetValue(globalInts, name, value); break;
if (OnGlobalsUpdated != null)
OnGlobalsUpdated(Type.Integer, name, value);
return;
}
public static void SetString(string name, string value, Scope scope)
{

case Scope.Local:
SetValue(localStrings, name, value); return;
SetValue(localStrings, name, value); break;
SetValue(globalStrings, name, value); return;
SetValue(globalStrings, name, value); break;
if (OnGlobalsUpdated != null)
OnGlobalsUpdated(Type.String, name, value);
return;
}
public static void SetFloat(string name, float value, Scope scope)
{

case Scope.Local:
SetValue(localFloats, name, value); return;
SetValue(localFloats, name, value); break;
SetValue(globalFloats, name, value); return;
SetValue(globalFloats, name, value); break;
if (OnGlobalsUpdated != null)
OnGlobalsUpdated(Type.Float, name, value);
return;
}
public static void SetObject(string name, GameObject value, Scope scope)
{

case Scope.Local:
SetValue(localObjects, name, value); return;
SetValue(localObjects, name, value); break;
SetValue(globalObjects, name, value); return;
SetValue(globalObjects, name, value); break;
if (OnGlobalsUpdated != null)
OnGlobalsUpdated(Type.GameObject, name, value);
return;
#region Debug
public delegate void GlobalsUpdatedDelegate(Type t, string name, object value);
public static event GlobalsUpdatedDelegate OnGlobalsUpdated;
public static IEnumerable<string> GetBoolNames(Scope scope) { return scope == Scope.Global ? globalBooleans.Keys : localBooleans.Keys; }
public static IEnumerable<string> GetIntNames(Scope scope) { return scope == Scope.Global ? globalInts.Keys : localInts.Keys; }
public static IEnumerable<string> GetFloatNames(Scope scope) { return scope == Scope.Global ? globalFloats.Keys : localFloats.Keys; }
public static IEnumerable<string> GetStringNames(Scope scope) { return scope == Scope.Global ? globalStrings.Keys : localStrings.Keys; }
public static IEnumerable<string> GetObjectNames(Scope scope) { return scope == Scope.Global ? globalObjects.Keys : localObjects.Keys; }
#endregion
}

8
Editor/GlobalsDebugWindow.meta


fileFormatVersion: 2
guid: e3cfe5bb18bcf554b83a3f0646547273
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

205
Runtime/Managers/Globals/GlobalLogic.cs


using NaughtyAttributes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GameplayIngredients.Logic
{
public class GlobalLogic : LogicBase
{
[Header("Base Value")]
public Globals.Scope scope = Globals.Scope.Global;
public Globals.Type type = Globals.Type.Boolean;
public string Variable = "SomeVariable";
public Evaluation evaluation = Evaluation.Equal;
[Header("Compare To...")]
[ShowIf("isCompareToOther")]
public CompareTo compareTo = CompareTo.Value;
[ShowIf("isBool")]
public bool boolValue = true;
[ShowIf("isInt")]
public int intValue = 1;
[ShowIf("isString")]
public string stringValue = "Value";
[ShowIf("isFloat")]
public float floatValue = 1.0f;
[ShowIf("isGameObject")]
public GameObject gameObjectValue;
[ShowIf("isGlobal")]
public string compareToVariable = "OtherVariable";
[ShowIf("isGlobal")]
public Globals.Scope compareToScope = Globals.Scope.Global;
public enum Evaluation
{
Equal,
NotEqual,
Greater,
GreaterOrEqual,
Less,
LessOrEqual,
Exists
}
public enum CompareTo
{
Value,
OtherGlobalVariable,
}
bool isBool() { return isValue() && type == Globals.Type.Boolean; }
bool isInt() { return isValue() && type == Globals.Type.Integer; }
bool isFloat() { return isValue() && type == Globals.Type.Float; }
bool isString() { return isValue() && type == Globals.Type.String; }
bool isGameObject() { return isValue() && type == Globals.Type.GameObject; }
bool isValue() { return compareTo == CompareTo.Value && isCompareToOther(); }
bool isGlobal() { return compareTo == CompareTo.OtherGlobalVariable && isCompareToOther(); }
bool isCompareToOther() { return evaluation != Evaluation.Exists; }
[ReorderableList]
public Callable[] OnTestSuccess;
[ReorderableList]
public Callable[] OnTestFail;
public override void Execute(GameObject instigator = null)
{
bool result = false;
if (evaluation == Evaluation.Exists)
{
switch (type)
{
case Globals.Type.Boolean: result = Globals.HasBool(Variable, scope); break;
case Globals.Type.Float: result = Globals.HasFloat(Variable, scope); break;
case Globals.Type.Integer: result = Globals.HasInt(Variable, scope); break;
case Globals.Type.String: result = Globals.HasString(Variable, scope); break;
case Globals.Type.GameObject: result = Globals.HasObject(Variable, scope); break;
}
}
else
{
try
{
switch (type)
{
case Globals.Type.Boolean:
result = TestValue(Globals.GetBool(Variable, scope), GetBoolValue());
break;
case Globals.Type.Integer:
result = TestValue(Globals.GetInt(Variable, scope), GetIntValue());
break;
case Globals.Type.Float:
result = TestValue(Globals.GetFloat(Variable, scope), GetFloatValue());
break;
case Globals.Type.String:
result = TestValue(Globals.GetString(Variable, scope), GetStringValue());
break;
case Globals.Type.GameObject:
result = TestObjectValue(Globals.GetObject(Variable, scope), GetObjectValue());
break;
}
}
catch { }
}
if (result)
Callable.Call(OnTestSuccess, instigator);
else
Callable.Call(OnTestFail, instigator);
}
bool GetBoolValue()
{
switch (compareTo)
{
default:
case CompareTo.Value:
return boolValue;
case CompareTo.OtherGlobalVariable:
return Globals.GetBool(compareToVariable, compareToScope);
}
}
int GetIntValue()
{
switch (compareTo)
{
default:
case CompareTo.Value:
return intValue;
case CompareTo.OtherGlobalVariable:
return Globals.GetInt(compareToVariable, compareToScope);
}
}
float GetFloatValue()
{
switch (compareTo)
{
default:
case CompareTo.Value:
return floatValue;
case CompareTo.OtherGlobalVariable:
return Globals.GetFloat(compareToVariable, compareToScope);
}
}
string GetStringValue()
{
switch (compareTo)
{
default:
case CompareTo.Value:
return stringValue;
case CompareTo.OtherGlobalVariable:
return Globals.GetString(compareToVariable, compareToScope);
}
}
GameObject GetObjectValue()
{
switch (compareTo)
{
default:
case CompareTo.Value:
return gameObjectValue;
case CompareTo.OtherGlobalVariable:
return Globals.GetObject(compareToVariable, compareToScope);
}
}
bool TestValue<T>(T value, T other) where T : System.IComparable<T>
{
switch (evaluation)
{
case Evaluation.Equal: return value.CompareTo(other) == 0;
case Evaluation.NotEqual: return value.CompareTo(other) != 0;
case Evaluation.Greater: return value.CompareTo(other) > 0;
case Evaluation.GreaterOrEqual: return value.CompareTo(other) >= 0;
case Evaluation.Less: return value.CompareTo(other) < 0;
case Evaluation.LessOrEqual: return value.CompareTo(other) <= 0;
}
return false;
}
bool TestObjectValue(GameObject value, GameObject other)
{
switch (evaluation)
{
case Evaluation.Equal:
return value == other;
case Evaluation.NotEqual:
case Evaluation.Greater:
case Evaluation.GreaterOrEqual:
case Evaluation.Less:
case Evaluation.LessOrEqual:
return value != other;
}
return false;
}
}
}

122
Editor/GlobalsDebugWindow/GlobalsDebugWindow.cs


using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
namespace GameplayIngredients.Editor
{
public class GlobalsDebugWindow : EditorWindow
{
[MenuItem("Window/Gameplay Ingredients/Globals Debug")]
static void Open()
{
GetWindow<GlobalsDebugWindow>();
}
private void OnEnable()
{
titleContent = new GUIContent("Globals Debug");
minSize = new Vector2(360, 140);
Globals.OnGlobalsUpdated += Globals_OnGlobalsUpdated;
}
private void Globals_OnGlobalsUpdated (Globals.Type t, string name, object value)
{
Repaint();
}
private void OnDisable()
{
Globals.OnGlobalsUpdated -= Globals_OnGlobalsUpdated;
}
Vector2 scroll;
private void OnGUI()
{
var localBools = Globals.GetBoolNames(Globals.Scope.Local);
var globalBools = Globals.GetBoolNames(Globals.Scope.Global);
var localInts = Globals.GetIntNames(Globals.Scope.Local);
var globalInts = Globals.GetIntNames(Globals.Scope.Global);
var localFloats = Globals.GetFloatNames(Globals.Scope.Local);
var globalFloats = Globals.GetFloatNames(Globals.Scope.Global);
var localStrings = Globals.GetStringNames(Globals.Scope.Local);
var globalStrings = Globals.GetStringNames(Globals.Scope.Global);
var localObjects = Globals.GetObjectNames(Globals.Scope.Local);
var globalObjects = Globals.GetObjectNames(Globals.Scope.Global);
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 1);
using(new GUILayout.HorizontalScope(EditorStyles.toolbar))
{
GUILayout.Label("Name", Styles.header);
GUILayout.Label("Global", Styles.header, GUILayout.Width(64));
GUILayout.Label("Type", Styles.header, GUILayout.Width(64));
GUILayout.Label("Value", Styles.header, GUILayout.Width(128));
}
GUI.backgroundColor = Color.white;
scroll = EditorGUILayout.BeginScrollView(scroll);
foreach (var item in globalBools.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Global, Globals.Type.Boolean); }
foreach (var item in localBools.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Local, Globals.Type.Boolean); }
foreach (var item in globalInts.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Global, Globals.Type.Integer); }
foreach (var item in localInts.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Local, Globals.Type.Integer); }
foreach (var item in globalFloats.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Global, Globals.Type.Float); }
foreach (var item in localFloats.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Local, Globals.Type.Float); }
foreach (var item in globalStrings.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Global, Globals.Type.String); }
foreach (var item in localStrings.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Local, Globals.Type.String); }
foreach (var item in globalObjects.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Global, Globals.Type.GameObject); }
foreach (var item in localObjects.OrderBy(o => o)) { DrawItem(item, Globals.Scope.Local, Globals.Type.GameObject); }
EditorGUILayout.EndScrollView();
}
void DrawItem(string name, Globals.Scope scope, Globals.Type type)
{
using(new GUILayout.HorizontalScope())
{
GUILayout.Label(name, Styles.cell);
GUILayout.Label(scope.ToString(), Styles.cell, GUILayout.Width(64));
GUILayout.Label(type.ToString(), Styles.cell, GUILayout.Width(64));
switch (type)
{
case Globals.Type.Boolean:
GUILayout.Toggle(Globals.GetBool(name, scope),"", GUILayout.Width(128));
break;
case Globals.Type.Integer:
GUILayout.TextField(Globals.GetInt(name, scope).ToString(), GUILayout.Width(128));
break;
case Globals.Type.String:
GUILayout.TextField(Globals.GetString(name, scope).ToString(), GUILayout.Width(128));
break;
case Globals.Type.Float:
GUILayout.TextField(Globals.GetFloat(name, scope).ToString(), GUILayout.Width(128));
break;
case Globals.Type.GameObject:
EditorGUILayout.ObjectField("",Globals.GetObject(name, scope), typeof(GameObject), true, GUILayout.Width(128));
break;
default:
break;
}
}
}
static class Styles
{
public static GUIStyle header;
public static GUIStyle cell;
static Styles()
{
header = new GUIStyle(EditorStyles.toolbarButton);
header.alignment = TextAnchor.MiddleLeft;
header.fontStyle = FontStyle.Bold;
cell = new GUIStyle(EditorStyles.toolbarButton);
cell.alignment = TextAnchor.MiddleLeft;
cell.fontSize = 10;
}
}
}
}

11
Editor/GlobalsDebugWindow/GlobalsDebugWindow.cs.meta


fileFormatVersion: 2
guid: afc22b24e415f0d4a87bcfd086d002cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

148
Runtime/Managers/Globals/OnGlobalLogic.cs


using NaughtyAttributes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GameplayIngredients.Logic
{
public class OnGlobalLogic : LogicBase
{
public Globals.Scope scope = Globals.Scope.Global;
public Globals.Type type = Globals.Type.Boolean;
public string Variable = "SomeVariable";
public Evaluation evaluation = Evaluation.Equal;
[ShowIf("isBool")]
public bool boolValue = true;
[ShowIf("isInt")]
public int intValue = 1;
[ShowIf("isString")]
public string stringValue = "Value";
[ShowIf("isFloat")]
public float floatValue = 1.0f;
[ShowIf("isGameObject")]
public GameObject gameObjectValue;
public enum Evaluation
{
Equal,
NotEqual,
Greater,
GreaterOrEqual,
Less,
LessOrEqual,
Exists
}
bool isBool() { return type == Globals.Type.Boolean; }
bool isInt() { return type == Globals.Type.Integer; }
bool isFloat() { return type == Globals.Type.Float; }
bool isString() { return type == Globals.Type.String; }
bool isGameObject() { return type == Globals.Type.GameObject; }
[ReorderableList]
public Callable[] OnTestSuccess;
[ReorderableList]
public Callable[] OnTestFail;
public override void Execute(GameObject instigator = null)
{
bool result = false;
if (evaluation == Evaluation.Exists)
{
switch (type)
{
case Globals.Type.Boolean: result = Globals.HasBool(Variable, scope); break;
case Globals.Type.Float: result = Globals.HasFloat(Variable, scope); break;
case Globals.Type.Integer: result = Globals.HasInt(Variable, scope); break;
case Globals.Type.String: result = Globals.HasString(Variable, scope); break;
}
}
else
{
switch (type)
{
case Globals.Type.Boolean:
if (!Globals.HasBool(Variable, scope))
{
WarnNotExist(Variable, type, scope);
}
else
{
result = TestValue(Globals.GetBool(Variable, scope), boolValue);
}
break;
case Globals.Type.Integer:
if (!Globals.HasInt(Variable, scope))
{
WarnNotExist(Variable, type, scope);
}
else
{
result = TestValue(Globals.GetInt(Variable, scope), intValue);
}
break;
case Globals.Type.Float:
if (!Globals.HasFloat(Variable, scope))
{
WarnNotExist(Variable, type, scope);
}
else
{
result = TestValue(Globals.GetFloat(Variable, scope), floatValue);
}
break;
case Globals.Type.String:
if (!Globals.HasString(Variable, scope))
{
WarnNotExist(Variable, type, scope);
}
else
{
result = TestValue(Globals.GetString(Variable, scope), stringValue);
}
break;
case Globals.Type.GameObject:
if (!Globals.HasObject(Variable, scope))
{
WarnNotExist(Variable, type, scope);
}
else
{
result = TestValue(Globals.GetObject(Variable, scope), gameObjectValue);
}
break;
}
}
if (result)
Callable.Call(OnTestSuccess, instigator);
else
Callable.Call(OnTestFail, instigator);
}
bool TestValue<T>(T value, T other) where T : System.IComparable<T>
{
switch (evaluation)
{
case Evaluation.Equal: return value.CompareTo(other) == 0;
case Evaluation.NotEqual: return value.CompareTo(other) != 0;
case Evaluation.Greater: return value.CompareTo(other) > 0;
case Evaluation.GreaterOrEqual: return value.CompareTo(other) >= 0;
case Evaluation.Less: return value.CompareTo(other) < 0;
case Evaluation.LessOrEqual: return value.CompareTo(other) <= 0;
}
return false;
}
void WarnNotExist(string name,Globals.Type type, Globals.Scope location)
{
Debug.LogWarning(string.Format("Save Data Logic: Trying to get {0} value to non existent {1} data in {2} save.", type, name, location));
}
}
}

/Runtime/Managers/Globals/OnGlobalLogic.cs.meta → /Runtime/Managers/Globals/GlobalLogic.cs.meta

正在加载...
取消
保存