├── .gitignore ├── Documentation.meta ├── Documentation ├── Architecture.png └── Architecture.png.meta ├── Editor.meta ├── Editor ├── Attributes.meta ├── Attributes │ ├── TagDrawer.cs │ └── TagDrawer.cs.meta ├── EvtDatabaseTabGraph.cs ├── EvtDatabaseTabGraph.cs.meta ├── EvtGraphEditor.cs ├── EvtGraphEditor.cs.meta ├── EvtGraphTemplate.cs ├── EvtGraphTemplate.cs.meta ├── EvtGraphView.cs ├── EvtGraphView.cs.meta ├── EvtNode.cs ├── EvtNode.cs.meta ├── EvtNodeSearchWindow.cs ├── EvtNodeSearchWindow.cs.meta ├── PeartreeGames.Evt.Graph.Editor.asmdef ├── PeartreeGames.Evt.Graph.Editor.asmdef.meta ├── Resources.meta └── Resources │ ├── EvtGraph.uss │ └── EvtGraph.uss.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Attributes.meta ├── Attributes │ ├── TagAttribute.cs │ └── TagAttribute.cs.meta ├── EvtConditionNode.cs ├── EvtConditionNode.cs.meta ├── EvtConditions.meta ├── EvtConditions │ ├── EvtAnimationReactions.meta │ ├── EvtCondition.cs │ ├── EvtCondition.cs.meta │ ├── EvtDistanceCondition.cs │ ├── EvtDistanceCondition.cs.meta │ ├── EvtObjectConditions.meta │ └── EvtObjectConditions │ │ ├── EvtBoolCondition.cs │ │ ├── EvtBoolCondition.cs.meta │ │ ├── EvtFloatCondition.cs │ │ ├── EvtFloatCondition.cs.meta │ │ ├── EvtIntCondition.cs │ │ ├── EvtIntCondition.cs.meta │ │ ├── EvtStringCondition.cs │ │ └── EvtStringCondition.cs.meta ├── EvtEdgeData.cs ├── EvtEdgeData.cs.meta ├── EvtNodeData.cs ├── EvtNodeData.cs.meta ├── EvtNodeItemData.cs ├── EvtNodeItemData.cs.meta ├── EvtReactionNode.cs ├── EvtReactionNode.cs.meta ├── EvtReactions.meta ├── EvtReactions │ ├── EvtAIReactions.meta │ ├── EvtAIReactions │ │ ├── EvtNavMoveReaction.cs │ │ └── EvtNavMoveReaction.cs.meta │ ├── EvtAnimationReactions.meta │ ├── EvtAnimationReactions │ │ ├── EvtAnimationBoolReaction.cs │ │ ├── EvtAnimationBoolReaction.cs.meta │ │ ├── EvtAnimationTriggerReaction.cs │ │ └── EvtAnimationTriggerReaction.cs.meta │ ├── EvtDebugReactions.meta │ ├── EvtDebugReactions │ │ ├── EvtDebugReaction.cs │ │ └── EvtDebugReaction.cs.meta │ ├── EvtGameObjectReactions.meta │ ├── EvtGameObjectReactions │ │ ├── EvtInstantiateReaction.cs │ │ ├── EvtInstantiateReaction.cs.meta │ │ ├── EvtSetActiveReaction.cs │ │ └── EvtSetActiveReaction.cs.meta │ ├── EvtLightControlReaction.cs │ ├── EvtLightControlReaction.cs.meta │ ├── EvtObjectReactions.meta │ ├── EvtObjectReactions │ │ ├── EvtBoolReaction.cs │ │ ├── EvtBoolReaction.cs.meta │ │ ├── EvtFloatReaction.cs │ │ ├── EvtFloatReaction.cs.meta │ │ ├── EvtIntReaction.cs │ │ ├── EvtIntReaction.cs.meta │ │ ├── EvtStringReaction.cs │ │ └── EvtStringReaction.cs.meta │ ├── EvtReaction.cs │ ├── EvtReaction.cs.meta │ ├── EvtSceneReactions.meta │ ├── EvtSceneReactions │ │ ├── EvtLoadSceneReaction.cs │ │ ├── EvtLoadSceneReaction.cs.meta │ │ ├── EvtUnloadSceneReaction.cs │ │ └── EvtUnloadSceneReaction.cs.meta │ ├── EvtUnityEventReaction.cs │ ├── EvtUnityEventReaction.cs.meta │ ├── EvtWaitRandomReaction.cs │ ├── EvtWaitRandomReaction.cs.meta │ ├── EvtWaitReaction.cs │ └── EvtWaitReaction.cs.meta ├── EvtTriggers.meta ├── EvtTriggers │ ├── EvtCollisionTrigger.cs │ ├── EvtCollisionTrigger.cs.meta │ ├── EvtInteractTrigger.cs │ ├── EvtInteractTrigger.cs.meta │ ├── EvtStartTrigger.cs │ ├── EvtStartTrigger.cs.meta │ ├── EvtTrigger.cs │ └── EvtTrigger.cs.meta ├── PeartreeGames.Evt.Graph.asmdef ├── PeartreeGames.Evt.Graph.asmdef.meta ├── Utils.meta └── Utils │ ├── EvtArithmeticOperator.cs │ ├── EvtArithmeticOperator.cs.meta │ ├── EvtComparisonOperator.cs │ └── EvtComparisonOperator.cs.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Uu]ser[Ss]ettings/ 12 | 13 | # MemoryCaptures can get excessive in size. 14 | # They also could contain extremely sensitive data 15 | /[Mm]emoryCaptures/ 16 | 17 | # Recordings can get excessive in size 18 | /[Rr]ecordings/ 19 | 20 | # Asset meta data should only be ignored when the corresponding asset is also ignored 21 | !/[Aa]ssets/**/*.meta 22 | 23 | # Uncomment this line if you wish to ignore the asset store tools plugin 24 | # /[Aa]ssets/AssetStoreTools* 25 | 26 | # Autogenerated Jetbrains Rider plugin 27 | /[Aa]ssets/Plugins/Editor/JetBrains* 28 | 29 | # Visual Studio cache directory 30 | .vs/ 31 | 32 | # Gradle cache directory 33 | .gradle/ 34 | 35 | # Autogenerated VS/MD/Consulo solution and project files 36 | ExportedObj/ 37 | .consulo/ 38 | *.csproj 39 | *.unityproj 40 | *.sln 41 | *.suo 42 | *.tmp 43 | *.user 44 | *.userprefs 45 | *.pidb 46 | *.booproj 47 | *.svd 48 | *.pdb 49 | *.mdb 50 | *.opendb 51 | *.VC.db 52 | 53 | # Unity3D generated meta files 54 | *.pidb.meta 55 | *.pdb.meta 56 | *.mdb.meta 57 | 58 | # Unity3D generated file on crash reports 59 | sysinfo.txt 60 | 61 | # Builds 62 | *.apk 63 | *.aab 64 | *.unitypackage 65 | *.app 66 | 67 | # Crashlytics generated file 68 | crashlytics-build.properties 69 | 70 | # Packed Addressables 71 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 72 | 73 | # Temporary auto-generated Android Assets 74 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 75 | /[Aa]ssets/[Ss]treamingAssets/aa/* 76 | 77 | .idea/ -------------------------------------------------------------------------------- /Documentation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff466bdea186d3c47b337b28fa1c7c9a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Documentation/Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peartreegames/evt-graph/5d6d7d303fe42852bac126aa1b1ce738cd36d7ea/Documentation/Architecture.png -------------------------------------------------------------------------------- /Documentation/Architecture.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ebd07623645eb934badd2973f16ab089 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | platformSettings: 67 | - serializedVersion: 3 68 | buildTarget: DefaultTexturePlatform 69 | maxTextureSize: 2048 70 | resizeAlgorithm: 0 71 | textureFormat: -1 72 | textureCompression: 1 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | androidETC2FallbackOverride: 0 78 | forceMaximumCompressionQuality_BC6H_BC7: 0 79 | spriteSheet: 80 | serializedVersion: 2 81 | sprites: [] 82 | outline: [] 83 | physicsShape: [] 84 | bones: [] 85 | spriteID: 86 | internalID: 0 87 | vertices: [] 88 | indices: 89 | edges: [] 90 | weights: [] 91 | secondaryTextures: [] 92 | nameFileIdTable: {} 93 | spritePackingTag: 94 | pSDRemoveMatte: 0 95 | pSDShowRemoveMatteOption: 0 96 | userData: 97 | assetBundleName: 98 | assetBundleVariant: 99 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: edd64a5e1323e9b4ebf1a0ecfd7dc819 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Attributes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83790f948fe24f6e819ce2c07e2c42f0 3 | timeCreated: 1639528741 -------------------------------------------------------------------------------- /Editor/Attributes/TagDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph.Editor 5 | { 6 | [CustomPropertyDrawer(typeof(TagAttribute))] 7 | public class TagDrawer : PropertyDrawer 8 | { 9 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 10 | { 11 | property.stringValue = EditorGUI.TagField(position, property.displayName, property.stringValue == string.Empty ? "Untagged" : property.stringValue); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Editor/Attributes/TagDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b17ad33aca65834d8f41493cb5447e0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/EvtDatabaseTabGraph.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using PeartreeGames.Evt.Variables.Editor; 4 | using UnityEngine; 5 | using UnityEngine.UIElements; 6 | 7 | namespace PeartreeGames.Evt.Graph.Editor 8 | { 9 | public class EvtDatabaseTabGraph : EvtDatabaseTab 10 | { 11 | public override string Name => "Graph"; 12 | public override VisualElement CreatePage() 13 | { 14 | Page = EvtDatabase.CreatePage(GetTriggersInScene, OnSelectionIndexChange); 15 | Page.StretchToParentSize(); 16 | return Page; 17 | } 18 | 19 | private void OnSelectionIndexChange(IEnumerable indices) 20 | { 21 | var right = Page.Q("Right"); 22 | right.Clear(); 23 | if (indices == null) return; 24 | var list = Page.Q("List"); 25 | foreach (var i in indices) 26 | { 27 | if (list.itemsSource[i] == null) continue; 28 | right.Add(CreateGraphView(list.itemsSource[i] as EvtTrigger)); 29 | break; 30 | } 31 | } 32 | 33 | private VisualElement CreateGraphView(EvtTrigger evtTrigger) 34 | { 35 | var box = new Box {style = {alignItems = Align.Center}}; 36 | box.StretchToParentSize(); 37 | var label = new Label {style = {top = 50}}; 38 | var graph = new EvtGraphView(EvtDatabase.Instance, evtTrigger) 39 | { 40 | name = "Evt.Graph" 41 | }; 42 | graph.StretchToParentSize(); 43 | return graph; 44 | } 45 | 46 | private static List GetTriggersInScene() => 47 | Object.FindObjectsOfType(true).ToList(); 48 | } 49 | } -------------------------------------------------------------------------------- /Editor/EvtDatabaseTabGraph.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90ef6d37be19451382891998fc909bb1 3 | timeCreated: 1681850593 -------------------------------------------------------------------------------- /Editor/EvtGraphEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEditor.SceneManagement; 3 | using UnityEngine.UIElements; 4 | 5 | namespace PeartreeGames.Evt.Graph.Editor 6 | { 7 | public class EvtGraphEditor : EditorWindow 8 | { 9 | [MenuItem("Tools/Evt/Graph")] 10 | private static void ShowWindow() 11 | { 12 | var window = GetWindow(); 13 | window.titleContent = new UnityEngine.GUIContent("Evt.Graph"); 14 | window.Show(); 15 | } 16 | 17 | private void OnEnable() 18 | { 19 | Init(); 20 | Selection.selectionChanged += Init; 21 | EditorApplication.playModeStateChanged += PlayModeChanged; 22 | } 23 | 24 | private void OnDisable() 25 | { 26 | rootVisualElement.Clear(); 27 | Selection.selectionChanged -= Init; 28 | EditorApplication.playModeStateChanged -= PlayModeChanged; 29 | } 30 | 31 | private void PlayModeChanged(PlayModeStateChange mode) 32 | { 33 | Init(); 34 | } 35 | 36 | private void Init() 37 | { 38 | var box = new Box {style = {alignItems = Align.Center}}; 39 | box.StretchToParentSize(); 40 | var label = new Label {style = {top = 50}}; 41 | EvtTrigger evtTrigger = null; 42 | if (Selection.activeGameObject == null || 43 | !Selection.activeGameObject.TryGetComponent(out evtTrigger)) label.text = "No EvtTrigger selected"; 44 | if (PrefabStageUtility.GetCurrentPrefabStage() != null) label.text = "Cannot edit prefab Evt.Graph"; 45 | if (Selection.count > 1) label.text = "Cannot edit multiple EvtTriggers at once"; 46 | 47 | rootVisualElement.Clear(); 48 | if (label.text != string.Empty || evtTrigger == null) 49 | { 50 | box.Add(label); 51 | rootVisualElement.Add(box); 52 | return; 53 | } 54 | var graph = new EvtGraphView(this, evtTrigger) 55 | { 56 | name = "Evt.Graph" 57 | }; 58 | graph.StretchToParentSize(); 59 | rootVisualElement.Add(graph); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Editor/EvtGraphEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bbe6d5f5f52546b898947c8ff74a7518 3 | timeCreated: 1638663625 -------------------------------------------------------------------------------- /Editor/EvtGraphTemplate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | namespace PeartreeGames.Evt.Graph 8 | { 9 | public class EvtGraphTemplate : ScriptableObject 10 | { 11 | [SerializeField] 12 | private List nodes; 13 | 14 | [Serializable] 15 | private class EvtTemplateEdge 16 | { 17 | public int outputIndex; 18 | public int inputIndex; 19 | public string portName; 20 | } 21 | 22 | [SerializeField] 23 | private List edges; 24 | 25 | public void Save(EvtTrigger evtTrigger) 26 | { 27 | nodes = new List(); 28 | var previous = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(this)); 29 | foreach (var prev in previous) 30 | { 31 | if (AssetDatabase.IsSubAsset(prev)) AssetDatabase.RemoveObjectFromAsset(prev); 32 | } 33 | 34 | foreach (var node in evtTrigger.nodes) 35 | { 36 | var nodeName = node.GetType().Name; 37 | var obj = CreateInstance(nodeName) as EvtNodeData; 38 | obj.name = nodeName; 39 | obj.position = node.position; 40 | obj.ID = Guid.Empty; 41 | AssetDatabase.AddObjectToAsset(obj, this); 42 | switch (node) 43 | { 44 | case EvtConditionNode cond: 45 | { 46 | var condObj = (EvtConditionNode) obj; 47 | condObj.items = new List(); 48 | foreach (var item in cond.items) 49 | { 50 | var cName = item.GetType().Name; 51 | var c = CreateInstance(cName) as EvtCondition; 52 | c.name = cName; 53 | AssetDatabase.AddObjectToAsset(c, this); 54 | condObj.items.Add(c); 55 | 56 | } 57 | break; 58 | } 59 | case EvtReactionNode react: 60 | { 61 | var reactObj = (EvtReactionNode) obj; 62 | reactObj.items = new List(); 63 | foreach (var item in react.items) 64 | { 65 | var rName = item.GetType().Name; 66 | var r = CreateInstance(item.GetType().Name) as EvtReaction; 67 | r.name = rName; 68 | AssetDatabase.AddObjectToAsset(r, this); 69 | reactObj.items.Add(r); 70 | } 71 | break; 72 | } 73 | } 74 | nodes.Add(obj); 75 | } 76 | edges = evtTrigger.edges.Select(edge => new EvtTemplateEdge() 77 | { 78 | outputIndex = evtTrigger.nodes.FindIndex(n => n.ID == edge.OutputId), 79 | inputIndex = evtTrigger.nodes.FindIndex(n => n.ID == edge.InputId), 80 | portName = edge.portName 81 | }).ToList(); 82 | } 83 | 84 | public void Load(EvtTrigger evtTrigger) 85 | { 86 | evtTrigger.nodes.Clear(); 87 | foreach (var node in nodes) 88 | { 89 | var obj = CreateInstance(node.GetType().Name) as EvtNodeData; 90 | obj.position = node.position; 91 | obj.ID = Guid.NewGuid(); 92 | switch (node) 93 | { 94 | case EvtConditionNode cond: 95 | { 96 | var condObj = (EvtConditionNode) obj; 97 | condObj.items = new List(); 98 | foreach (var item in cond.items.Where(item => item != null)) 99 | { 100 | condObj.items.Add(CreateInstance(item.GetType().Name) as EvtCondition); 101 | } 102 | break; 103 | } 104 | case EvtReactionNode react: 105 | { 106 | var reactObj = (EvtReactionNode) obj; 107 | reactObj.items = new List(); 108 | foreach (var item in react.items.Where(item => item != null)) 109 | reactObj.items.Add(CreateInstance(item.GetType().Name) as EvtReaction); 110 | break; 111 | } 112 | } 113 | evtTrigger.nodes.Add(obj); 114 | } 115 | evtTrigger.edges = edges.Select(edge => new EvtEdgeData() 116 | { 117 | OutputId = edge.outputIndex < 0 ? Guid.Empty : evtTrigger.nodes[edge.outputIndex].ID, 118 | InputId = evtTrigger.nodes[edge.inputIndex].ID, 119 | portName = edge.portName 120 | }).ToList(); 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /Editor/EvtGraphTemplate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c58c60ba11f94ce4bbfd4fd6c23437c6 3 | timeCreated: 1640113590 -------------------------------------------------------------------------------- /Editor/EvtGraphView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using UnityEditor; 6 | using UnityEditor.Experimental.GraphView; 7 | using UnityEditor.UIElements; 8 | using UnityEngine; 9 | using UnityEngine.UIElements; 10 | 11 | namespace PeartreeGames.Evt.Graph.Editor 12 | { 13 | public class EvtGraphView : GraphView 14 | { 15 | private readonly EvtTrigger _evtTrigger; 16 | 17 | private static readonly Vector2 DefaultNodeSize = new(100, 200); 18 | 19 | private Edge[] Edges => edges.ToArray(); 20 | private EvtNode[] Nodes => nodes.Cast().ToArray(); 21 | 22 | public EvtGraphView(EditorWindow editorWindow, EvtTrigger evtTrigger) 23 | { 24 | styleSheets.Add(Resources.Load("EvtGraph")); 25 | _evtTrigger = evtTrigger; 26 | this.AddManipulator(new ContentDragger()); 27 | this.AddManipulator(new SelectionDragger()); 28 | this.AddManipulator(new RectangleSelector()); 29 | this.AddManipulator(new ContentZoomer()); 30 | graphViewChanged = OnGraphChanged; 31 | var grid = new GridBackground(); 32 | Insert(0, grid); 33 | AddToolbar(); 34 | var searchWindow = ScriptableObject.CreateInstance(); 35 | searchWindow.Init(editorWindow, this, evtTrigger); 36 | nodeCreationRequest = ctx => 37 | SearchWindow.Open(new SearchWindowContext(ctx.screenMousePosition), searchWindow); 38 | LoadGraph(); 39 | 40 | } 41 | 42 | private void AddToolbar() 43 | { 44 | var tools = new Toolbar(); 45 | tools.AddToClassList("toolbar"); 46 | 47 | var templateSaveButton = new ToolbarButton() { text = "Save As" }; 48 | var templateLoadButton = new ToolbarButton() { text = "Load" }; 49 | templateSaveButton.clicked += () => 50 | { 51 | var path = EditorUtility.SaveFilePanelInProject("Save Evt.Graph Template", "Evt.Graph_", "asset", ""); 52 | if (path == string.Empty) return; 53 | var asset = AssetDatabase.LoadAssetAtPath(path); 54 | if (asset == null) 55 | { 56 | asset = ScriptableObject.CreateInstance(); 57 | asset.name = Path.GetFileName(path); 58 | AssetDatabase.CreateAsset(asset, path); 59 | } 60 | asset.Save(_evtTrigger); 61 | AssetDatabase.SaveAssets(); 62 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset)); 63 | AssetDatabase.Refresh(); 64 | }; 65 | templateLoadButton.clicked += () => 66 | { 67 | var path = EditorUtility.OpenFilePanel("Load Evt.Graph Template", "Assets/", "asset"); 68 | if (path == string.Empty) return; 69 | path = Path.GetRelativePath("Assets/", path); 70 | var asset = AssetDatabase.LoadAssetAtPath($"Assets/{path}"); 71 | if (asset == null) return; 72 | asset.Load(_evtTrigger); 73 | LoadGraph(); 74 | }; 75 | 76 | tools.Add(templateSaveButton); 77 | tools.Add(templateLoadButton); 78 | Add(tools); 79 | } 80 | 81 | 82 | private GraphViewChange OnGraphChanged(GraphViewChange graphViewChange) 83 | { 84 | if (_evtTrigger == null) return graphViewChange; 85 | if (graphViewChange.edgesToCreate != null) 86 | { 87 | foreach (var edge in graphViewChange.edgesToCreate) 88 | { 89 | var outputNode = (EvtNode) edge.output.node; 90 | var inputNode = (EvtNode) edge.input.node; 91 | var portName = edge.output.portName; 92 | if (_evtTrigger.edges.Exists(e => 93 | e.OutputId == outputNode.ID && e.InputId == inputNode.ID && e.portName == portName)) continue; 94 | _evtTrigger.edges.Add(new EvtEdgeData() 95 | { 96 | OutputId = outputNode.ID, 97 | portName = portName, 98 | InputId = inputNode.ID 99 | }); 100 | } 101 | } 102 | 103 | if (graphViewChange.elementsToRemove != null) 104 | { 105 | foreach (var elem in graphViewChange.elementsToRemove) 106 | { 107 | if (elem.GetType() == typeof(EvtNode)) 108 | { 109 | var id = ((EvtNode) elem).ID; 110 | _evtTrigger.nodes.RemoveAll(n => n.ID == id); 111 | _evtTrigger.edges.RemoveAll(e => e.OutputId == id || e.InputId == id); 112 | } 113 | if (elem.GetType() != typeof(Edge)) continue; 114 | 115 | var outputNode = (EvtNode) ((Edge) elem).output.node; 116 | var inputNode = (EvtNode) ((Edge) elem).input.node; 117 | var port = ((Edge) elem).output.portName; 118 | _evtTrigger.edges.RemoveAll(e => 119 | e.OutputId == outputNode.ID && e.InputId == inputNode.ID && e.portName == port); 120 | } 121 | } 122 | 123 | if (graphViewChange.movedElements != null) 124 | { 125 | foreach (var elem in graphViewChange.movedElements) 126 | { 127 | if (elem.GetType() != typeof(EvtNode)) continue; 128 | var node = (EvtNode) elem; 129 | if (node.ID == Guid.Empty) continue; 130 | var referenceNode = _evtTrigger.nodes.FirstOrDefault(n => n.ID == node.ID); 131 | if (referenceNode == null) continue; 132 | referenceNode.position = node.GetPosition().position; 133 | } 134 | } 135 | 136 | EditorUtility.SetDirty(_evtTrigger); 137 | return graphViewChange; 138 | } 139 | 140 | private void LoadGraph() 141 | { 142 | if (_evtTrigger == null) return; 143 | ClearGraph(); 144 | var root = CreateRootNode(); 145 | AddElement(root); 146 | RecreateGraph(); 147 | } 148 | 149 | private void RecreateGraph() 150 | { 151 | if (_evtTrigger == null || _evtTrigger.nodes == null || _evtTrigger.edges == null) return; 152 | foreach (var nodeData in _evtTrigger.nodes) 153 | { 154 | var node = CreateNode(nodeData); 155 | if (node == null) continue; 156 | AddElement(node); 157 | node.SetPosition(new Rect(nodeData.position, DefaultNodeSize)); 158 | } 159 | 160 | var cachedNodes = Nodes; 161 | foreach (var node in cachedNodes) 162 | { 163 | for (var i = 0; i < node.outputContainer.childCount; i++) 164 | { 165 | var port = node.outputContainer[i].Q(); 166 | var edgeData = _evtTrigger.edges.Where(e => e.OutputId == node.ID && e.portName == port.portName).ToArray(); 167 | foreach (var edge in edgeData) 168 | { 169 | var targetId = edge.InputId; 170 | var targetNode = cachedNodes.FirstOrDefault(n => n.ID == targetId); 171 | if (targetNode == null) continue; 172 | var nodeData = _evtTrigger.nodes.FirstOrDefault(n => n.ID == targetNode.ID); 173 | if (nodeData == null) continue; 174 | if (targetNode.inputContainer.childCount == 0) continue; 175 | LinkNodes(port, (Port) targetNode.inputContainer[0]); 176 | } 177 | } 178 | } 179 | } 180 | 181 | private void ClearGraph() 182 | { 183 | foreach(var edge in Edges) RemoveElement(edge); 184 | foreach(var node in Nodes) RemoveElement(node); 185 | } 186 | 187 | private EvtNode CreateRootNode() 188 | { 189 | var root = new EvtNode() 190 | { 191 | title = _evtTrigger.name, 192 | ID = Guid.Empty 193 | }; 194 | root.AddToClassList("root"); 195 | var port = CreatePort(root, Direction.Output, Port.Capacity.Multi); 196 | port.portName = "OnTrigger"; 197 | root.outputContainer.Add(port); 198 | 199 | root.RefreshExpandedState(); 200 | root.RefreshPorts(); 201 | root.SetPosition(new Rect(Vector2.one * 100, DefaultNodeSize)); 202 | return root; 203 | } 204 | 205 | private static Port CreatePort(EvtNode node, Direction direction, Port.Capacity capacity) => 206 | node.InstantiatePort(Orientation.Horizontal, direction, capacity, typeof(float)); 207 | 208 | public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) => 209 | ports.Where(port => startPort != port && startPort.node != port.node).ToList(); 210 | 211 | private void LinkNodes(Port output, Port input) 212 | { 213 | var edge = new Edge() 214 | { 215 | output = output, 216 | input = input 217 | }; 218 | edge.input.Connect(edge); 219 | edge.output.Connect(edge); 220 | Add(edge); 221 | } 222 | 223 | public EvtNode CreateNode(EvtNodeData data) 224 | { 225 | if (data == null) return null; 226 | var node = new EvtNode() 227 | { 228 | ID = data.ID 229 | }; 230 | 231 | switch (data) 232 | { 233 | case EvtConditionNode condition: 234 | CreateConditionNode(node, condition); 235 | break; 236 | case EvtReactionNode reaction: 237 | CreateReactionNode(node, reaction); 238 | break; 239 | } 240 | 241 | var input = CreatePort(node, Direction.Input, Port.Capacity.Multi); 242 | input.portName = "Input"; 243 | node.inputContainer.Add(input); 244 | node.RefreshExpandedState(); 245 | node.RefreshPorts(); 246 | node.SetPosition(new Rect(data.position, DefaultNodeSize)); 247 | AddElement(node); 248 | return node; 249 | } 250 | 251 | private void CreateReactionNode(EvtNode node, EvtReactionNode reaction) 252 | { 253 | var choices = CreateDropDown(); 254 | choices.choices.Insert(0, "Select Reaction"); 255 | choices.index = 0; 256 | node.title = "Reaction"; 257 | node.extensionContainer.Add(choices); 258 | var output = CreatePort(node, Direction.Output, Port.Capacity.Multi); 259 | output.portName = EvtReactionNode.OnCompletePortName; 260 | node.outputContainer.Add(output); 261 | 262 | var serialized = new SerializedObject(reaction); 263 | var reactions = serialized.FindProperty("items"); 264 | choices.RegisterValueChangedCallback(change => 265 | { 266 | if (CreateInstanceFromDropdown(change.newValue) is not EvtReaction react) return; 267 | react.name = change.newValue; 268 | choices.SetValueWithoutNotify("Select Reaction"); 269 | reactions.arraySize++; 270 | reactions.GetArrayElementAtIndex(reactions.arraySize - 1).objectReferenceValue = react; 271 | serialized.ApplyModifiedProperties(); 272 | var box = CreatePropertyBox(node, serialized, reactions, reactions.arraySize - 1); 273 | box.Q().value = true; 274 | node.extensionContainer.Add(box); 275 | node.RefreshExpandedState(); 276 | }); 277 | 278 | CreatePropertyBoxes(node, serialized, reactions); 279 | 280 | node.extensionContainer.style.borderBottomWidth = reaction.IsActive ? 5 : 0; 281 | reaction.OnActive += enabled => node.extensionContainer.style.borderBottomWidth = enabled ? 5 : 0; 282 | } 283 | 284 | 285 | private void CreateConditionNode(EvtNode node, EvtConditionNode condition) 286 | { 287 | var choices = CreateDropDown(); 288 | choices.choices.Insert(0, "Select Condition"); 289 | choices.index = 0; 290 | node.title = "Condition"; 291 | node.extensionContainer.Add(choices); 292 | 293 | var truePort = CreatePort(node, Direction.Output, Port.Capacity.Multi); 294 | truePort.portName = EvtConditionNode.TruePortName; 295 | node.outputContainer.Add(truePort); 296 | var falsePort = CreatePort(node, Direction.Output, Port.Capacity.Multi); 297 | falsePort.portName = EvtConditionNode.FalsePortName; 298 | node.outputContainer.Add(falsePort); 299 | 300 | var serialized = new SerializedObject(condition); 301 | var conditions = serialized.FindProperty("items"); 302 | choices.RegisterValueChangedCallback(change => 303 | { 304 | if (CreateInstanceFromDropdown(change.newValue) is not EvtCondition cond) return; 305 | cond.name = change.newValue; 306 | choices.SetValueWithoutNotify("Select Condition"); 307 | conditions.arraySize++; 308 | conditions.GetArrayElementAtIndex(conditions.arraySize - 1).objectReferenceValue = cond; 309 | serialized.ApplyModifiedProperties(); 310 | var box = CreatePropertyBox(node, serialized, conditions, conditions.arraySize - 1); 311 | box.Q().value = true; 312 | node.extensionContainer.Add(box); 313 | node.RefreshExpandedState(); 314 | }); 315 | 316 | CreatePropertyBoxes(node, serialized, conditions); 317 | } 318 | 319 | private static void CreatePropertyBoxes(EvtNode node, SerializedObject serializedObject, SerializedProperty serializedProperty) 320 | { 321 | if (serializedProperty == null) return; 322 | for (var i = 0; i < serializedProperty.arraySize; i++) 323 | { 324 | var box = CreatePropertyBox(node, serializedObject, serializedProperty, i); 325 | if (box == null) continue; 326 | node.extensionContainer.Add(box); 327 | } 328 | } 329 | 330 | private static GroupBox CreatePropertyBox(EvtNode node, SerializedObject serializedObject, SerializedProperty serializedProperty, int i) 331 | { 332 | var obj = serializedProperty.GetArrayElementAtIndex(i).objectReferenceValue; 333 | if (obj is null) return null; 334 | var box = new GroupBox(); 335 | box.AddToClassList("property-box"); 336 | var foldOut = new Foldout 337 | { 338 | text = obj.GetType().GetProperty("DisplayName")?.GetValue(null).ToString() ?? obj.GetType().Name 339 | }; 340 | foldOut.contentContainer.AddToClassList("property-foldout"); 341 | var serializedProp = new SerializedObject(obj); 342 | var itr = serializedProp.GetIterator(); 343 | if (itr.NextVisible(true)) 344 | { 345 | do 346 | { 347 | if (itr.name == "m_Script") continue; 348 | var field = new PropertyField(itr); 349 | field.Bind(serializedProp); 350 | foldOut.contentContainer.Add(field); 351 | } while (itr.NextVisible(false)); 352 | } 353 | foldOut.contentContainer.Add(new Button(() => 354 | { 355 | serializedProperty.DeleteArrayElementAtIndex(i); 356 | serializedObject.ApplyModifiedProperties(); 357 | node.extensionContainer.Remove(box); 358 | }) { text = "x", style = { alignSelf = Align.FlexEnd } }); 359 | box.Add(foldOut); 360 | foldOut.value = serializedProp.FindProperty("isExpanded").boolValue; 361 | foldOut.BindProperty(serializedProp.FindProperty("isExpanded")); 362 | return box; 363 | } 364 | 365 | private static DropdownField CreateDropDown() where TU : EvtNodeItemData => 366 | new() 367 | { 368 | choices = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(TU))) 369 | .Select(t => t.GetProperty("DisplayName")?.GetValue(null).ToString() ?? t.Name).ToList(), 370 | label = "" 371 | }; 372 | 373 | private static ScriptableObject CreateInstanceFromDropdown(string str) where TU : EvtNodeItemData 374 | { 375 | var choices = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(TU))) 376 | .Select(t => (display: t.GetProperty("DisplayName")?.GetValue(null).ToString() ?? t.Name, value: t.Name)).ToList(); 377 | var choice = choices.Find(choice => choice.display == str); 378 | return ScriptableObject.CreateInstance(choice.value); 379 | } 380 | } 381 | } 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | -------------------------------------------------------------------------------- /Editor/EvtGraphView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74b970f6e7f74c2cb98d4048eb7447f0 3 | timeCreated: 1638677096 -------------------------------------------------------------------------------- /Editor/EvtNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.Experimental.GraphView; 3 | 4 | namespace PeartreeGames.Evt.Graph.Editor 5 | { 6 | public class EvtNode : Node 7 | { 8 | public Guid ID; 9 | } 10 | } -------------------------------------------------------------------------------- /Editor/EvtNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6de39c9df1f44a1b937f604d606918d 3 | timeCreated: 1638677074 -------------------------------------------------------------------------------- /Editor/EvtNodeSearchWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEditor; 4 | using UnityEditor.Experimental.GraphView; 5 | using UnityEngine; 6 | using UnityEngine.UIElements; 7 | 8 | namespace PeartreeGames.Evt.Graph.Editor 9 | { 10 | public class EvtNodeSearchWindow : ScriptableObject, ISearchWindowProvider 11 | { 12 | private EvtGraphView _view; 13 | private EditorWindow _editor; 14 | private EvtTrigger _evtTrigger; 15 | 16 | public void Init(EditorWindow editor, EvtGraphView view, EvtTrigger trigger) 17 | { 18 | _editor = editor; 19 | _view = view; 20 | _evtTrigger = trigger; 21 | } 22 | 23 | public List CreateSearchTree(SearchWindowContext context) 24 | { 25 | var tree = new List 26 | { 27 | new SearchTreeGroupEntry(new GUIContent("Create Element")), 28 | new(new GUIContent("Condition")) 29 | { 30 | userData = CreateInstance(), 31 | level = 1 32 | }, 33 | new(new GUIContent("Reaction")) 34 | { 35 | userData = CreateInstance(), 36 | level = 1 37 | } 38 | }; 39 | return tree; 40 | } 41 | 42 | public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context) 43 | { 44 | var node = (EvtNodeData) SearchTreeEntry.userData; 45 | node.ID = Guid.NewGuid(); 46 | 47 | var worldMousePosition = _editor.rootVisualElement.ChangeCoordinatesTo(_editor.rootVisualElement.parent, 48 | context.screenMousePosition - _editor.position.position); 49 | var localMousePosition = _view.contentViewContainer.WorldToLocal(worldMousePosition); 50 | 51 | node.position = localMousePosition; 52 | _evtTrigger.nodes ??= new List(); 53 | switch (node) 54 | { 55 | case EvtConditionNode condition: 56 | _view.CreateNode(condition); 57 | _evtTrigger.nodes.Add(condition); 58 | break; 59 | case EvtReactionNode reaction: 60 | _view.CreateNode(reaction); 61 | _evtTrigger.nodes.Add(reaction); 62 | break; 63 | } 64 | 65 | return true; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Editor/EvtNodeSearchWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a11c127f59f4a66b3d5685a8f41e202 3 | timeCreated: 1638678694 -------------------------------------------------------------------------------- /Editor/PeartreeGames.Evt.Graph.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PeartreeGames.Evt.Graph.Editor", 3 | "rootNamespace": "PeartreeGames.Evt.Graph.Editor", 4 | "references": [ 5 | "PeartreeGames.Evt.Graph", 6 | "PeartreeGames.Evt.Variables.Editor" 7 | ], 8 | "includePlatforms": [ 9 | "Editor" 10 | ], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [], 18 | "noEngineReferences": false 19 | } -------------------------------------------------------------------------------- /Editor/PeartreeGames.Evt.Graph.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30ae43daac44c7347ac3996cb9ad2c13 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d55ec86b70794fd0a3d841fd4381d7e1 3 | timeCreated: 1638677897 -------------------------------------------------------------------------------- /Editor/Resources/EvtGraph.uss: -------------------------------------------------------------------------------- 1 | GridBackground { 2 | --grid-background-color: #282828; 3 | --line-color: rgba(193, 196, 192, 0.1); 4 | --thick-line-color: rgba(193, 196, 192, 0.1); 5 | --spacing: 10; 6 | } 7 | 8 | #collapsible-area { 9 | background-color: rgba(62,62,62, 205); 10 | } 11 | 12 | #extension { 13 | flex-shrink: 0; 14 | flex-grow: 1; 15 | padding: 10px; 16 | min-width: 400px; 17 | border-color: #84E4E7; 18 | } 19 | 20 | .property-box { 21 | background-color: #515151; 22 | border-radius: 1px; 23 | border-color: black; 24 | } 25 | 26 | .property-foldout { 27 | padding-right: 10px; 28 | } 29 | 30 | .root { 31 | min-width: 100px; 32 | } 33 | 34 | .toolbar { 35 | justify-content: flex-end; 36 | } -------------------------------------------------------------------------------- /Editor/Resources/EvtGraph.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b15ad9fb304476d97d78c31c6222e8d 3 | timeCreated: 1638677907 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Peartree Games 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8152aad7024f5d3419838c1c1c8e41b6 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Evt.Graph 2 | Code for "Creating a Serialized Conditional Reaction Sequence Graph in Unity" [YouTube videos](https://www.youtube.com/watch?v=KJ_ba50nooQ) 3 | 4 | Repository has been converted to a package module. The `video-end` branch contains the project at the time of the part 2 completion. 5 | 6 | A few UIElements used were introduced in Unity 2021, for previous version of Unity the code will need to be modified to work. A PR with version compile directives would be welcome, but I don't think I'll ever get around to it. 7 | 8 | ## Installation 9 | Can be installed via the Package Manager > Add Package From Git URL... 10 | 11 | This repo has a dependency on the EvtVariable package which *MUST* be installed first. (From my understanding Unity does not allow git urls to be used as dependencies of packages) 12 | `https://github.com/peartreegames/evt-variables.git` 13 | 14 | then the repo can be added 15 | 16 | `https://github.com/peartreegames/evt-graph.git` 17 | 18 | ## Architectural Overview 19 | ![Architecture](./Documentation/Architecture.png) 20 | 21 | ## Changes 22 | 23 | - Templates: Save As and Load Evt.Graph structures as template assets 24 | 25 | ## Todos 26 | - [ ] Zoom Persistence (Seems to be more complicated than originally thought) 27 | - [X] Foldout Persistence 28 | - [X] Rest of EvtTriggers 29 | - [ ] Standard set of Condition/Reactions 30 | - [ ] Allow template graph editing directly in GraphView 31 | - [ ] Lock GraphView to selected EvtTrigger (Entering play mode causes issues, need to revisit) -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ea0534efe0c466446b68201c0b098c0d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e1042858e0dc5d4ea39524cd1b81599 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Attributes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b325d6b9393241ec9da3171f825bcb4e 3 | timeCreated: 1639528728 -------------------------------------------------------------------------------- /Runtime/Attributes/TagAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | [AttributeUsage(AttributeTargets.Field)] 7 | public class TagAttribute : PropertyAttribute 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /Runtime/Attributes/TagAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffe62d3806aa481bbc0e89c05f3f5599 3 | timeCreated: 1639528119 -------------------------------------------------------------------------------- /Runtime/EvtConditionNode.cs: -------------------------------------------------------------------------------- 1 | namespace PeartreeGames.Evt.Graph 2 | { 3 | public class EvtConditionNode : EvtNodeData 4 | { 5 | public const string TruePortName = "True"; 6 | public const string FalsePortName = "False"; 7 | private bool CheckIsSatisfied(EvtTrigger trigger) => 8 | items.TrueForAll(condition => condition.CheckIsSatisfied(trigger)); 9 | public override void Execute(EvtTrigger trigger) 10 | { 11 | var connections = trigger.GetConnectedNodes(this, CheckIsSatisfied(trigger) ? TruePortName : FalsePortName); 12 | foreach(var connection in connections) connection.Execute(trigger); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Runtime/EvtConditionNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9c9df5c374642ecb78897dbc5e67568 3 | timeCreated: 1638674950 -------------------------------------------------------------------------------- /Runtime/EvtConditions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 01e82085dc4f489ea6e8ae33d0c45448 3 | timeCreated: 1638662677 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtAnimationReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c3ca64963dd2e542b4fdfa790f2b9d4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtCondition.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace PeartreeGames.Evt.Graph 4 | { 5 | public abstract class EvtCondition : EvtNodeItemData 6 | { 7 | #pragma warning disable 0414 8 | [HideInInspector] [SerializeField] private bool isExpanded = true; 9 | #pragma warning restore 0414 10 | public abstract bool CheckIsSatisfied(EvtTrigger trigger); 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 240932312fde454a8c27029db44b2664 3 | timeCreated: 1638661988 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtDistanceCondition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtDistanceCondition : EvtCondition 7 | { 8 | public new static string DisplayName => "Vector3/Distance"; 9 | [SerializeField] private Transform from; 10 | [SerializeField] private Transform to; 11 | [SerializeField] private EvtComparisonOperator compOp; 12 | [SerializeField] private float distance; 13 | public override bool CheckIsSatisfied(EvtTrigger trigger) 14 | { 15 | var fromPosition = from.position; 16 | var toPosition = to.position; 17 | return compOp switch 18 | { 19 | EvtComparisonOperator.Equal => Vector3.Distance(fromPosition, toPosition) - distance < Mathf.Epsilon, 20 | EvtComparisonOperator.NotEqual => Vector3.Distance(fromPosition, toPosition) - distance > Mathf.Epsilon, 21 | EvtComparisonOperator.LessThan => Vector3.Distance(fromPosition, toPosition) < distance, 22 | EvtComparisonOperator.GreaterThan => Vector3.Distance(fromPosition, toPosition) > distance, 23 | EvtComparisonOperator.LessThanOrEqual => Vector3.Distance(fromPosition, toPosition) <= distance, 24 | EvtComparisonOperator.GreaterThanOrEqual => Vector3.Distance(fromPosition, toPosition) >= distance, 25 | _ => throw new ArgumentOutOfRangeException() 26 | }; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtDistanceCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 025de024c52145a4a68be0c315d1480f 3 | timeCreated: 1638734644 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5666989df986405b90ba0d3b31f8abe6 3 | timeCreated: 1638762052 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtBoolCondition.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using PeartreeGames.Evt.Variables; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtBoolCondition : EvtCondition 7 | { 8 | public new static string DisplayName => "Variable/Bool"; 9 | [SerializeField] private EvtBool variable; 10 | [SerializeField] private bool target; 11 | public override bool CheckIsSatisfied(EvtTrigger trigger) => variable.Value == target; 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtBoolCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88e0e582d1dd4cc5b11d8059806a345f 3 | timeCreated: 1638762199 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtFloatCondition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using PeartreeGames.Evt.Variables; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtFloatCondition : EvtCondition 8 | { 9 | public new static string DisplayName => "Variable/Float"; 10 | [SerializeField] private EvtFloat variable; 11 | [SerializeField] private EvtComparisonOperator compOp; 12 | [SerializeField] private float target; 13 | 14 | public override bool CheckIsSatisfied(EvtTrigger trigger) => compOp switch 15 | { 16 | EvtComparisonOperator.Equal => Math.Abs(variable.Value - target) < Mathf.Epsilon, 17 | EvtComparisonOperator.NotEqual => Math.Abs(variable.Value - target) > Mathf.Epsilon, 18 | EvtComparisonOperator.LessThan => variable.Value < target, 19 | EvtComparisonOperator.GreaterThan => variable.Value > target, 20 | EvtComparisonOperator.LessThanOrEqual => variable.Value <= target, 21 | EvtComparisonOperator.GreaterThanOrEqual => variable.Value >= target, 22 | _ => throw new ArgumentOutOfRangeException() 23 | }; 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtFloatCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32fadf1aab05e834299f9ec153d23034 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtIntCondition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using PeartreeGames.Evt.Variables; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtIntCondition : EvtCondition 8 | { 9 | public new static string DisplayName => "Variable/Int"; 10 | [SerializeField] private EvtInt variable; 11 | [SerializeField] private EvtComparisonOperator compOp; 12 | [SerializeField] private int target; 13 | 14 | public override bool CheckIsSatisfied(EvtTrigger trigger) => compOp switch 15 | { 16 | EvtComparisonOperator.Equal => variable.Value == target, 17 | EvtComparisonOperator.NotEqual => variable.Value != target, 18 | EvtComparisonOperator.LessThan => variable.Value < target, 19 | EvtComparisonOperator.GreaterThan => variable.Value > target, 20 | EvtComparisonOperator.LessThanOrEqual => variable.Value <= target, 21 | EvtComparisonOperator.GreaterThanOrEqual => variable.Value >= target, 22 | _ => throw new ArgumentOutOfRangeException() 23 | }; 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtIntCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 012fd7d5b5bb44fe863d968a3706f49a 3 | timeCreated: 1638762082 -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtStringCondition.cs: -------------------------------------------------------------------------------- 1 | using PeartreeGames.Evt.Variables; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtStringCondition : EvtCondition 7 | { 8 | public new static string DisplayName => "Variable/String"; 9 | [SerializeField] private EvtString variable; 10 | [SerializeField] private string target; 11 | public override bool CheckIsSatisfied(EvtTrigger trigger) => variable.Value == target; 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/EvtConditions/EvtObjectConditions/EvtStringCondition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 603c7257e4a0fdb4d879d5ef56ec6643 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtEdgeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | [Serializable] 7 | public class EvtEdgeData : ISerializationCallbackReceiver 8 | { 9 | public Guid OutputId; 10 | public Guid InputId; 11 | public string portName; 12 | 13 | [SerializeField] private string outputIdString; 14 | [SerializeField] private string inputIdString; 15 | public void OnBeforeSerialize() 16 | { 17 | outputIdString = OutputId.ToString(); 18 | inputIdString = InputId.ToString(); 19 | } 20 | 21 | public void OnAfterDeserialize() 22 | { 23 | Guid.TryParse(outputIdString, out OutputId); 24 | Guid.TryParse(inputIdString, out InputId); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Runtime/EvtEdgeData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfabf9f76ec1483da867b261c55018d3 3 | timeCreated: 1638662536 -------------------------------------------------------------------------------- /Runtime/EvtNodeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public abstract class EvtNodeData : ScriptableObject, ISerializationCallbackReceiver 8 | { 9 | public Guid ID; 10 | public Vector2 position; 11 | 12 | public abstract void Execute(EvtTrigger trigger); 13 | 14 | [SerializeField] private string idString; 15 | public void OnBeforeSerialize() => idString = ID.ToString(); 16 | public void OnAfterDeserialize() => Guid.TryParse(idString, out ID); 17 | } 18 | 19 | public abstract class EvtNodeData : EvtNodeData where T : EvtNodeItemData 20 | { 21 | [HideInInspector] 22 | [SerializeField] public List items; 23 | 24 | private void OnValidate() 25 | { 26 | items.RemoveAll(item => item == null); 27 | items.TrimExcess(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/EvtNodeData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ea019c06df543a98108926771425a6e 3 | timeCreated: 1638662442 -------------------------------------------------------------------------------- /Runtime/EvtNodeItemData.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace PeartreeGames.Evt.Graph 4 | { 5 | public abstract class EvtNodeItemData : ScriptableObject 6 | { 7 | public static string DisplayName { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/EvtNodeItemData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7dc9bc738b954d41a0dc41122bed6f90 3 | timeCreated: 1638661966 -------------------------------------------------------------------------------- /Runtime/EvtReactionNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtReactionNode : EvtNodeData 8 | { 9 | public bool IsActive { get; private set; } 10 | #if UNITY_EDITOR 11 | public event Action OnActive; 12 | #endif 13 | 14 | public const string OnCompletePortName = "OnComplete"; 15 | 16 | public override void Execute(EvtTrigger trigger) 17 | { 18 | trigger.StartCoroutine(React(trigger)); 19 | } 20 | 21 | private IEnumerator React(EvtTrigger trigger) 22 | { 23 | IsActive = true; 24 | #if UNITY_EDITOR 25 | OnActive?.Invoke(IsActive); 26 | #endif 27 | var coroutines = items.ConvertAll(reaction => trigger.StartCoroutine(reaction.React(trigger))); 28 | foreach (var coroutine in coroutines) yield return coroutine; 29 | var connections = trigger.GetConnectedNodes(this, OnCompletePortName); 30 | foreach (var connection in connections) connection.Execute(trigger); 31 | IsActive = false; 32 | #if UNITY_EDITOR 33 | OnActive?.Invoke(IsActive); 34 | #endif 35 | } 36 | 37 | } 38 | } -------------------------------------------------------------------------------- /Runtime/EvtReactionNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4291bafb9bb84464807b4372ca3a30d4 3 | timeCreated: 1638674899 -------------------------------------------------------------------------------- /Runtime/EvtReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1c00cafbaa749c4ba64ad83961b1821 3 | timeCreated: 1638662665 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAIReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afecf9b0e86ba904ea185a67289a82ef 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAIReactions/EvtNavMoveReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using UnityEngine.AI; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtNavMoveReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "AI/NavAgentMove"; 10 | [SerializeField] private NavMeshAgent agent; 11 | [SerializeField] private Transform destination; 12 | [SerializeField] private float distanceThreshold = 0.1f; 13 | public override IEnumerator React(EvtTrigger trigger) 14 | { 15 | agent.destination = destination.position; 16 | while (Vector3.Distance(agent.transform.position, destination.position) > distanceThreshold) 17 | yield return null; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAIReactions/EvtNavMoveReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 456cbea7fddd5d941aadab1d280e49d3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAnimationReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b96d03ced4233514cbdea0ba23b1a168 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAnimationReactions/EvtAnimationBoolReaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | 8 | public class EvtAnimationBoolReaction : EvtReaction 9 | { 10 | public new static string DisplayName => "Animation/Bool"; 11 | [SerializeField] private Animator animator; 12 | [SerializeField] private string parameterName; 13 | [SerializeField] private bool active; 14 | public override IEnumerator React(EvtTrigger trigger) 15 | { 16 | animator.SetBool(parameterName, active); 17 | yield break; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAnimationReactions/EvtAnimationBoolReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8fa7dc4294c3a954b9a2e357b9bb1671 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAnimationReactions/EvtAnimationTriggerReaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | 8 | public class EvtAnimationTriggerReaction : EvtReaction 9 | { 10 | public new static string DisplayName => "Animation/Trigger"; 11 | [SerializeField] private Animator animator; 12 | [SerializeField] private string parameterName; 13 | public override IEnumerator React(EvtTrigger trigger) 14 | { 15 | animator.SetTrigger(parameterName); 16 | yield break; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtAnimationReactions/EvtAnimationTriggerReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7300d24930747514494b9a843191ca6c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtDebugReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25fc9934dcaa60142aafcd71127eaf88 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtDebugReactions/EvtDebugReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtDebugReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "Debug/Log"; 9 | [SerializeField] private string message; 10 | public override IEnumerator React(EvtTrigger trigger) 11 | { 12 | Debug.Log(message); 13 | yield break; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtDebugReactions/EvtDebugReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 821aba6189798ff4195cacf85fd35772 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtGameObjectReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86466fa06c34a934698c8a85299e1cf2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtGameObjectReactions/EvtInstantiateReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtInstantiateReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "GameObject/Instantiate"; 9 | [SerializeField] private GameObject prefab; 10 | [SerializeField] private Transform spawn; 11 | [SerializeField] private Transform parent; 12 | [SerializeField] private int quantity = 1; 13 | [SerializeField] private float delayPerSpawn; 14 | public override IEnumerator React(EvtTrigger trigger) 15 | { 16 | for (var i = 0; i < quantity; i++) 17 | { 18 | Instantiate(prefab, spawn.position, spawn.rotation, parent); 19 | yield return new WaitForSeconds(delayPerSpawn); 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtGameObjectReactions/EvtInstantiateReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ca7c802cbb1ed349a03516394829206 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtGameObjectReactions/EvtSetActiveReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtSetActiveReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "GameObject/SetActive"; 9 | [SerializeField] private GameObject gameObject; 10 | [SerializeField] private bool active; 11 | public override IEnumerator React(EvtTrigger trigger) 12 | { 13 | gameObject.SetActive(active); 14 | yield break; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtGameObjectReactions/EvtSetActiveReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c03989fbbbfc4fc469c107c710f02e34 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtLightControlReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtLightControlReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "Light/Control"; 9 | [SerializeField] private Light light; 10 | [SerializeField] private Color color; 11 | [SerializeField] private float intensity; 12 | public override IEnumerator React(EvtTrigger trigger) 13 | { 14 | light.color = color; 15 | light.intensity = intensity; 16 | yield break; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtLightControlReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34d1e242a92949f7bbeee8fac17058e8 3 | timeCreated: 1638728852 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff0d2b6f3fb84da38e184c00f6ee8c5e 3 | timeCreated: 1638762262 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtBoolReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using PeartreeGames.Evt.Variables; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtBoolReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "Variable/Bool"; 10 | [SerializeField] private EvtBool variable; 11 | [SerializeField] private bool value; 12 | public override IEnumerator React(EvtTrigger trigger) 13 | { 14 | variable.Value = value; 15 | yield break; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtBoolReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ea2ca42d8414fc2865ef6286ed3092a 3 | timeCreated: 1638762531 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtFloatReaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | using PeartreeGames.Evt.Variables; 5 | 6 | namespace PeartreeGames.Evt.Graph 7 | { 8 | public class EvtFloatReaction : EvtReaction 9 | { 10 | public new static string DisplayName => "Variable/Float"; 11 | [SerializeField] private EvtFloat variable; 12 | [SerializeField] private EvtArithmeticOperator arithOp; 13 | [SerializeField] private float value; 14 | 15 | public override IEnumerator React(EvtTrigger trigger) 16 | { 17 | var result = arithOp switch 18 | { 19 | EvtArithmeticOperator.Sum => variable.Value + value, 20 | EvtArithmeticOperator.Subtract => variable.Value - value, 21 | EvtArithmeticOperator.Multiply => variable.Value * value, 22 | EvtArithmeticOperator.Divide => variable.Value / value, 23 | EvtArithmeticOperator.Modulo => variable.Value % value, 24 | _ => throw new ArgumentOutOfRangeException() 25 | }; 26 | variable.Value = result; 27 | yield break; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtFloatReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2dfb8c08515ca942b33e36dc4d16abb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtIntReaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | using PeartreeGames.Evt.Variables; 5 | 6 | namespace PeartreeGames.Evt.Graph 7 | { 8 | public class EvtIntReaction : EvtReaction 9 | { 10 | public new static string DisplayName => "Variable/Int"; 11 | [SerializeField] private EvtInt variable; 12 | [SerializeField] private EvtArithmeticOperator arithOp; 13 | [SerializeField] private int value; 14 | 15 | public override IEnumerator React(EvtTrigger trigger) 16 | { 17 | var result = arithOp switch 18 | { 19 | EvtArithmeticOperator.Sum => variable.Value + value, 20 | EvtArithmeticOperator.Subtract => variable.Value - value, 21 | EvtArithmeticOperator.Multiply => variable.Value * value, 22 | EvtArithmeticOperator.Divide => variable.Value / value, 23 | EvtArithmeticOperator.Modulo => variable.Value % value, 24 | _ => throw new ArgumentOutOfRangeException() 25 | }; 26 | variable.Value = result; 27 | yield break; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtIntReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e828da6978f64999b9c83ed2c5d931c4 3 | timeCreated: 1638762270 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtStringReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using PeartreeGames.Evt.Variables; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtStringReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "Variable/String"; 10 | [SerializeField] private EvtString variable; 11 | [SerializeField] private string value; 12 | public override IEnumerator React(EvtTrigger trigger) 13 | { 14 | variable.Value = value; 15 | yield break; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtObjectReactions/EvtStringReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c17a6fa9c0154a445a9cac5380d0b5e9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public abstract class EvtReaction : EvtNodeItemData 7 | { 8 | #pragma warning disable 0414 9 | [HideInInspector] [SerializeField] private bool isExpanded = true; 10 | #pragma warning restore 0414 11 | public abstract IEnumerator React(EvtTrigger trigger); 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30efb3d00ed3404895ce2831202e1079 3 | timeCreated: 1638662068 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtSceneReactions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3567a3d4d6749df4ebc59f7bfa00d146 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtSceneReactions/EvtLoadSceneReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using UnityEngine.SceneManagement; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtLoadSceneReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "Scene/Load"; 10 | [SerializeField] private LoadSceneMode mode; 11 | [SerializeField] private string sceneName; 12 | public override IEnumerator React(EvtTrigger trigger) 13 | { 14 | yield return SceneManager.LoadSceneAsync(sceneName, mode); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtSceneReactions/EvtLoadSceneReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62efa6b0c295cdd49b7023d21b94e743 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtSceneReactions/EvtUnloadSceneReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using UnityEngine.SceneManagement; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtUnloadSceneReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "Scene/Unload"; 10 | [SerializeField] private string scene; 11 | public override IEnumerator React(EvtTrigger trigger) 12 | { 13 | yield return SceneManager.UnloadSceneAsync(scene); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtSceneReactions/EvtUnloadSceneReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ed5b05efcaca9749b74cfb10bf59e97 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtUnityEventReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | using UnityEngine.Events; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | public class EvtUnityEventReaction : EvtReaction 8 | { 9 | public new static string DisplayName => "UnityEvent"; 10 | [SerializeField] private UnityEvent unityEvent; 11 | public override IEnumerator React(EvtTrigger trigger) 12 | { 13 | unityEvent?.Invoke(); 14 | yield break; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtUnityEventReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48e789ca23f556f4bbe9b43762ed9178 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtWaitRandomReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtWaitRandomReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "Time/Wait Random"; 9 | [SerializeField] private float minDelay; 10 | [SerializeField] private float maxDelay; 11 | private float _remainingDelay; 12 | public override IEnumerator React(EvtTrigger trigger) 13 | { 14 | _remainingDelay = Random.Range(minDelay, maxDelay); 15 | while (_remainingDelay > 0) 16 | { 17 | _remainingDelay -= Time.deltaTime; 18 | yield return null; 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtWaitRandomReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1154a576364f42b293362399e9909611 3 | timeCreated: 1659731119 -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtWaitReaction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | namespace PeartreeGames.Evt.Graph 5 | { 6 | public class EvtWaitReaction : EvtReaction 7 | { 8 | public new static string DisplayName => "Time/Wait"; 9 | [SerializeField] private float delay; 10 | private float _remainingDelay; 11 | public override IEnumerator React(EvtTrigger trigger) 12 | { 13 | _remainingDelay = delay; 14 | while (_remainingDelay > 0) 15 | { 16 | _remainingDelay -= Time.deltaTime; 17 | yield return null; 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Runtime/EvtReactions/EvtWaitReaction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5a79065f7334cf7bb16b79c4dfc1dbb 3 | timeCreated: 1638662316 -------------------------------------------------------------------------------- /Runtime/EvtTriggers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d654f634a70d4dd884aa2f2f23739013 3 | timeCreated: 1638662692 -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtCollisionTrigger.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace PeartreeGames.Evt.Graph 4 | { 5 | public class EvtCollisionTrigger : EvtTrigger 6 | { 7 | [Tag] 8 | [SerializeField] private string targetTag; 9 | 10 | private void OnTriggerEnter(Collider other) 11 | { 12 | if (other.CompareTag(targetTag)) Trigger(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtCollisionTrigger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eb91ccc0955647446bd56aea1bae038e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtInteractTrigger.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace PeartreeGames.Evt.Graph 4 | { 5 | public class EvtInteractTrigger : EvtTrigger 6 | { 7 | public void Interact(GameObject interactor) => Trigger(); 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtInteractTrigger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c33139e32f84444ab6b61943b1b73ab6 3 | timeCreated: 1638727819 -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtStartTrigger.cs: -------------------------------------------------------------------------------- 1 | namespace PeartreeGames.Evt.Graph 2 | { 3 | public class EvtStartTrigger : EvtTrigger 4 | { 5 | private void Start() 6 | { 7 | Trigger(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtStartTrigger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fbfdb6dbc5874e7b9978310fe39cf9b2 3 | timeCreated: 1638662760 -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtTrigger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace PeartreeGames.Evt.Graph 6 | { 7 | [DisallowMultipleComponent] 8 | public abstract class EvtTrigger : MonoBehaviour 9 | { 10 | [HideInInspector] 11 | [SerializeField] public float zoomLevel; 12 | 13 | public List nodes = new(); 14 | public List edges = new(); 15 | 16 | private bool IsRunning => nodes?.FindAll(n => n is EvtReactionNode reaction && reaction.IsActive).Count > 0; 17 | 18 | protected void Trigger() 19 | { 20 | if (IsRunning) return; 21 | foreach (var node in GetRootNodes()) node.Execute(this); 22 | } 23 | 24 | private List GetRootNodes() 25 | { 26 | var edgeData = edges.FindAll(e => e.OutputId == Guid.Empty); 27 | return nodes.FindAll(n => edgeData.Exists(e => e.InputId == n.ID)); 28 | } 29 | 30 | public List GetConnectedNodes(EvtNodeData node, string portName) 31 | { 32 | var edgeData = edges.FindAll(e => e.OutputId == node.ID && e.portName == portName); 33 | return nodes.FindAll(n => edgeData.Exists(e => e.InputId == n.ID)); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Runtime/EvtTriggers/EvtTrigger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dace5eb9c5ad481abd4fea76a0b217d9 3 | timeCreated: 1638662692 -------------------------------------------------------------------------------- /Runtime/PeartreeGames.Evt.Graph.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PeartreeGames.Evt.Graph", 3 | "rootNamespace": "PeartreeGames.Evt.Graph", 4 | "references": [ 5 | "PeartreeGames.Evt.Variables" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Runtime/PeartreeGames.Evt.Graph.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6da1b17138dfeeb479150bef945487da 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: abc5d606a6e24a6792f3668e85acb97f 3 | timeCreated: 1638734613 -------------------------------------------------------------------------------- /Runtime/Utils/EvtArithmeticOperator.cs: -------------------------------------------------------------------------------- 1 | namespace PeartreeGames.Evt.Graph 2 | { 3 | public enum EvtArithmeticOperator 4 | { 5 | Sum, 6 | Subtract, 7 | Multiply, 8 | Divide, 9 | Modulo 10 | } 11 | } -------------------------------------------------------------------------------- /Runtime/Utils/EvtArithmeticOperator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bba6e95d81cb48c0b76c46dc1dfaf03b 3 | timeCreated: 1638762313 -------------------------------------------------------------------------------- /Runtime/Utils/EvtComparisonOperator.cs: -------------------------------------------------------------------------------- 1 | namespace PeartreeGames.Evt.Graph 2 | { 3 | public enum EvtComparisonOperator 4 | { 5 | Equal, 6 | NotEqual, 7 | LessThan, 8 | GreaterThan, 9 | LessThanOrEqual, 10 | GreaterThanOrEqual 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/Utils/EvtComparisonOperator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df3fb019330647f0bdf0e7aca37c0c18 3 | timeCreated: 1638734613 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.peartreegames.evt.graph", 3 | "version": "0.2.2", 4 | "displayName": "Evt.Graph", 5 | "description": "Serialized Conditional Reaction Sequence Graph", 6 | "unity": "2021.2", 7 | "unityRelease": "2f1", 8 | "documentationUrl": "https://github.com/peartreegames/evt-graph", 9 | "changelogUrl": "https://github.com/peartreegames/evt-graph/changelog.html", 10 | "licensesUrl": "https://github.com/peartreegames/evt-graph/licensing.html", 11 | "dependencies": { 12 | "com.unity.modules.uielements": "0.1.0", 13 | "com.peartreegames.evt.variables": "0.2.1" 14 | }, 15 | "keywords": [ 16 | "peartree", 17 | "scriptableobjects", 18 | "graphview" 19 | ], 20 | "author": { 21 | "name": "Peartree Games", 22 | "email": "bgk@peartree.games", 23 | "url": "https://peartree.games" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3d4d4f31dd595d44b59c64a89a52133 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------