Giter Club home page Giter Club logo

schema's Introduction

Schema

Schema - Create AI in Unity

asset store license latest

Schema is a visual scripting tool that allows you to create Behavior Trees for video games with minimal hassle and configuration.

Features:

  • 150+ Nodes and Decorators
  • Simple API
  • Zero runtime allocations
  • Sub-millisecond execution per Agent
  • Extensive documentation
  • Data oriented design
  • Event driven
  • Intuitive editor
  • Supports built in Unity serialization (no manual saving or loading needed)
  • Supports custom editors out of the box
  • Blackboard variables
  • Blackboard properties (get and set)
  • Conditional aborts
  • Built in tree formatting
  • 100% free and open source under the MIT License

Quick Start

There are two ways to download and install Schema -- through either the asset store or through this GitHub repository. Downloading the source through GitHub is recommended if you want the latest updates; Unity's Asset Store is generally slower to receive new bugfixes and features. Unity is designed to work for Unity versions 2020.1 and above.

Asset Store

The Asset store page is located here. The asset is free, so all you need to do to add Schema to your library is to click the "Add to My Assets" button. In your Unity project, download and import the asset through the Package Manager. You can find instructions to do this on Unity's tutorial website. This is the recommended installation solution for most people, since it is integrated into the engine.

GitHub

You can download the latest .unitypackage archive file from the releases tab. If you want the latest updates, download the source code or clone the repository and move the code into your project folder.

git clone "https://github.com/acdamiani/schema" Schema
# Move to your project folder
mv Schema your/project/directory

Examples

All examples can be found in the Samples~ folder in the root of the project. The Example project contains a simple behavior tree with a custom node and fully commented code describing what all of the scripts are doing. Open the included scene to see the capabilities of the package.

To get started by making your own tree, checkout the Readme! PDF. To go in more depth to the workings of the project, check out the Docs folder, which contains Markdown files relating the features of Schema.

Contact

If you run into any trouble, have suggestions, or just want to talk about the project, feel free to shoot me an email at [email protected]

A huge thank you to everyone who has helped with this project--your work means a lot!

schema's People

Contributors

acdamiani avatar zenvin-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

schema's Issues

Connections and some nodes are gone after update to commit 15b26ec4829f64418e47cd99410415604fe16ac7

Hi @acdamiani

I've updated Schema AI via import from git (before I downloaded it from Asset Store).

When I open my Graph, I get this error message / stack trace:

Broken text PPtr in file(Assets/Prefabs/Enemies/BaseAIGraph.asset). Local file identifier (86440366174919129) doesn't exist!
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Exception thrown while invoking [OnOpenAssetAttribute] method 'SchemaEditor.NodeEditor:Open (int,int)' : NullReferenceException: Object reference not set to an instance of an object
SchemaEditor.Internal.ComponentSystem.Components.ConditionalComponent.Create (SchemaEditor.Internal.ComponentSystem.CreateArgs args) (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Canvas/Components/ConditionalComponent.cs:177)
SchemaEditor.Internal.ComponentCanvas.Create[T] (SchemaEditor.Internal.ComponentSystem.CreateArgs args) (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Canvas/ComponentCanvas.cs:99)
SchemaEditor.NodeEditor.RebuildComponentTree () (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Window/NodeEditorGUI.cs:390)
SchemaEditor.NodeEditor.Open (Schema.Graph graphObj) (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Window/NodeEditor.cs:142)
SchemaEditor.NodeEditor.OpenGraph (Schema.Graph graphObj) (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Window/NodeEditor.cs:133)
SchemaEditor.NodeEditor.Open (System.Int32 instanceID, System.Int32 line) (at ./Library/PackageCache/com.acdamiani.schema@15b26ec482/Editor/Window/NodeEditor.cs:278)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

Blackboard entries are still there but conditionals and connections seem to be gone at least visually.

BaseAIGraph.asset.zip
AI.zip

I've added my Graph Asset and my custom Action and Conditional for you to reproduce it.

image

After going back to v 1.0.5 from Asset Store I still get the same error and I cannot create new connections. :-(

Stop Idle Node Execution

Hello again :)

The Idle Node is nice but it's useless for me since there is no way to abort it conditionally.

In the description is stated, that it can be pulled of from the flow by a decorator.

namespace Schema.Builtin.Nodes
{
    [Description("Will stop execution of the tree perpetually, until flow is pulled from it by a Decorator."),
     Category("Miscellaneous")]
    public class Idle : Action
    {
        public override NodeStatus Tick(object nodeMemory, SchemaAgent agent)
        {
            return NodeStatus.Running;
        }
    }
}

There are no concrete decorators in the code. The only classes that could be a node decorator are the conditionals and the modifiers.

The only modifier that could possibly used is the LoopUntil modifier. But for the public BlackboardEntrySelector<bool> condition; I'm getting an error in editor from BlackboardEntrySelectorDrawer:
image

in

public static string DoSelectorDrawer(Rect position, SerializedProperty property, GUIContent label,
    Type fieldType, FieldInfo fieldInfo)
{
    Type parentType = property.serializedObject.targetObject.GetType();

    if (!valid.Any(t => t.IsAssignableFrom(parentType)))
    {
        GUI.Label(position,
            new GUIContent("Cannot use a BlackboardEntrySelector in a non tree type",
                Icons.GetEditor("console.warnicon")), EditorStyles.miniLabel);
        return "";
    }
 /// [...]
}

The Conditionals are not executed on a node that has returned a Running status in the last tick.

The only way to abort a node that is Running (e.g. MoveTo) is to write own custom logic into a new node.

Imagine this situation:

An enemy moves to a position 50 meters away and I walk to him. I'm right in front of him. He just ignores me until he has reached his location. There is no way to handle that problem without coding.

Or did I do misunderstand something ?

Thanks in advance for you help and hopefully explanations. :)

I get this error when searching for components.

unity 2021.3.21f1 editor

IndexOutOfRangeException: Index was outside the bounds of the array.
QuickSearch.Search (System.String needle, System.String haystack) (at Assets/Schema/Editor/Window/QuickSearch.cs:342)
QuickSearch.SearchThroughResults (System.Collections.Generic.IEnumerable1[T] types, System.String query) (at Assets/Schema/Editor/Window/QuickSearch.cs:322) QuickSearch.<CorrectSelection>b__31_0 () (at Assets/Schema/Editor/Window/QuickSearch.cs:298) Schema.Utilities.CacheDictionary2[T1,T2].GetOrCreate (T1 key, System.Func`1[TResult] default) (at Assets/Schema/Utilities/CacheDictionary.cs:13)
QuickSearch.CorrectSelection (System.Int32 selected) (at Assets/Schema/Editor/Window/QuickSearch.cs:298)
QuickSearch.Focus () (at Assets/Schema/Editor/Window/QuickSearch.cs:286)
QuickSearch.OnGUI (System.Int32 id) (at Assets/Schema/Editor/Window/QuickSearch.cs:65)
UnityEngine.GUI.CallWindowDelegate (UnityEngine.GUI+WindowFunction func, System.Int32 id, System.Int32 instanceID, UnityEngine.GUISkin _skin, System.Int32 forceRect, System.Single width, System.Single height, UnityEngine.GUIStyle style) (at :0)
UnityEditor.EditorWindow:EndWindows()
SchemaEditor.Internal.ComponentSystem.Components.WindowComponent:OnGUI() (at Assets/Schema/Editor/Canvas/Components/WindowComponent.cs:61)
SchemaEditor.Internal.ComponentCanvas:Draw() (at Assets/Schema/Editor/Canvas/ComponentCanvas.cs:265)
SchemaEditor.NodeEditor:OnGUI() (at Assets/Schema/Editor/Window/NodeEditorGUI.cs:45)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

Documentation is not clear on Conditional aborts

The documentation currently only addresses Conditional aborts in passing. It would be worth it to expound upon what they are and how they work, since they are pretty important for any mildly complex behavior tree.

Conditionals do not abort lower priority nodes on failure

It looks like there is an issue with Conditional aborts as detailed in issue #6. It looks like a logical error in the ExecutableNode.RunDynamicConditionals method. It might be helpful to refactor the boolean logic here, since it's pretty messy and difficult to parse.

Node execution in parallel

It might be helpful for users to be able to run nodes in parallel, allowing more detailed logic without the need for writing custom nodes or conditionals. Behavior Designer does something similar.

Conditional is evaluated even if corresponding node is not running

Hi @acdamiani

how to reproduce?
image

In this example I would expect that only two checks are made since the tree should never reach this node:
image

But unfortunately all three conditionals are checked.
Only when a conditional has abort conditions.

If this is intended I would like to understand the advantage.

Best,
Christian

OverlapSphere does not check against Internal Types

Hey guys,

I guess I've found an error.

In Schema.Builtin.Nodes.OverlapSphere inside Tick method there are made checks against GameObject and Transform. But these are Unity GameObject and Transform Classes.

None of the 4 if statements returns true.

But if I change the code to:

public override NodeStatus Tick(object nodeMemory, SchemaAgent agent)
{
    Collider[] colliders =
        Physics.OverlapSphere(position.value, radius.value, layerMask, queryTriggerInteraction);

    if (colliders.Length == 0)
        return NodeStatus.Failure;

    if (hit.entryType == typeof(Schema.Internal.Types.GameObject) || hit.isDynamic)
        hit.value = colliders[0].gameObject;
    else if (hit.entryType == typeof(List<Schema.Internal.Types.GameObject>))
        hit.value = colliders.Select(collider => collider.gameObject).ToList();
    else if (hit.entryType == typeof(Schema.Internal.Types.Transform))
        hit.value = colliders[0].transform;
    else if (hit.entryType == typeof(List<Schema.Internal.Types.Transform>))
        hit.value = colliders.Select(collider => collider.transform).ToList();

    return NodeStatus.Success;
}

It works perfectly.

I'm using Unity 2022.3.16f1 (LTS).

Am I using it wrong or does that have to do something with the Unity Version ?

Thx in Advance

RotateTowardsVector resets references when I hit play

In Edit mode:
image

After I hit play:
image

Maybe the new statement is the bad guy here.

public class RotateTowardsVector : Action
{
    [Tooltip("Current managed vector")] public BlackboardEntrySelector current = new BlackboardEntrySelector(); // <-- this one

    [Tooltip("Target vector")] public BlackboardEntrySelector target = new BlackboardEntrySelector(); // <-- this one

    [Tooltip("The maximum angle in radians allowed for this rotation")]
    public BlackboardEntrySelector<float> maxRadiansDelta;

    [Tooltip("The maximum allowed change in vector magnitude for this rotation")]
    public BlackboardEntrySelector<float> maxMagnitudeDelta;

    [Tooltip("Blackboard variable to store the new rotated vector in"), WriteOnly] 
    public BlackboardEntrySelector rotated = new BlackboardEntrySelector(); // <-- this one

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.