Compare commits

..

8 Commits

Author SHA1 Message Date
Wilson E. Alvarez 8f684f4169
Fix List<T> access
Due to upstream change:

	955d5affa8
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 5258506e12
Fix GCC warning for unhandled 'PACKED_VECTOR4_ARRAY' in switch
Due to upstream change:

	f9b488508c
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 2f0468bb00
Update EditorPlugin header location
Due to upstream change:

	1bcbbe96c4
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 2c740e7741
Update EditorHelpBit calls
Due to upstream change:

	a714cb9f65
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 606b5a9276
Add missing MarginContainer header
Due to upstream change:

	7884d63281
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez fa1fd7f55f
Fix bottom panel visbility calls
Due to upstream change:

	eb6ca91ba6
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 127696e5ac
Migrate to Tree::set_custom_draw_callback
Due to upstream change:

	a32a2eaedc
2024-05-07 09:41:30 -04:00
Wilson E. Alvarez 5e5f849208
Fix upstream EditorScale header locations
Due to upstream change:

	4b55c81eba
2024-05-07 09:41:30 -04:00
150 changed files with 509 additions and 2227 deletions

View File

@ -1,64 +0,0 @@
name: Bug report
description: Report a bug in LimboAI
labels:
- bug
body:
- type: markdown
attributes:
value: |
- Write a descriptive title above.
- Search [open](https://github.com/limbonaut/limboai/issues) and [closed](https://github.com/limbonaut/limboai/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported.
- type: input
attributes:
label: Godot version
description: |
- Specify the Godot version and hardware information if relevant.
- You can copy the version info by clicking on it in the Godot status bar.
- Alternatively, you can copy the version and hardware info in Godot using the main menu command "Help -> Copy System Info".
placeholder: v4.2.2.limboai+v1.1.0.gha [15073afe3]
validations:
required: true
- type: input
attributes:
label: LimboAI version
description: |
- Specify the LimboAI version.
- You can copy the version info by clicking on it in the toolbar of the LimboAI editor (top-right corner).
placeholder: v1.1.0 [8fa609e]
validations:
required: true
- type: dropdown
id: variant
attributes:
label: LimboAI variant
description: Which variant of our plugin are you running?
options:
- GDExtension / AssetLib
- Module (custom editor or template build)
default: 0
validations:
required: true
- type: textarea
attributes:
label: Issue description
description: |
- Describe your issue in detail. What doesn't work and how do you expect it to work instead?
- Provide screenshots and/or a console output if it helps to convey the problem.
validations:
required: true
- type: textarea
attributes:
label: How to reproduce
description: |
- Provide a list of steps or sample code that reproduces the issue.
- You can provide a small Godot project which reproduces the issue, with no unnecessary files included.
- Drag and drop a ZIP archive to upload it (10Mb limit).
- Don't include the `.godot` folder in the archive.
- Redroduction project helps to find the bug more quickly!
validations:
required: true

View File

@ -1,14 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Documentation
url: https://limboai.readthedocs.io/en/stable/
about: Please see our documentation for more information.
- name: Discussions
url: https://github.com/limbonaut/limboai/discussions
about: Need help? Ask questions in Discussions or on our Discord server.
- name: Discord Server
url: https://discord.gg/N5MGC95GpP
about: Share your experience or get help on our Discord server.

View File

@ -1,38 +0,0 @@
name: Feature or improvement proposal
description: Propose a new feature to be added or improved in LimboAI
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
- Write a descriptive title above.
- Search [open](https://github.com/limbonaut/limboai/issues) and [closed](https://github.com/limbonaut/limboai/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported.
- type: textarea
attributes:
label: Problem statement
description: |
- Describe the problem or limitation you're currently facing with the LimboAI plugin.
- If it helps, describe the project you're working on and how it relates to the problem or limitation.
validations:
required: true
- type: textarea
attributes:
label: Proposed solution
description: |
- Describe your proposed solution and how it helps to overcome the problem or limitation.
- If it helps, show how it will work with code, pseudo-code, mock-ups, and/or diagrams.
- You can include any images or videos with drag'n'drop, and sample code blocks with <code>```</code> tags.
validations:
required: true
- type: textarea
attributes:
label: Alternatives
description: |
- Describe alternative solutions and features you've considered.
- If this enhancement will not be used often, can it be worked around with a few clicks or lines of code?
validations:
required: true

View File

@ -1,47 +0,0 @@
name: Setup Linux toolchain
inputs:
arch:
required: true
runs:
using: "composite"
steps:
- name: Set up environment
shell: bash
run: |
# ! Settings:
TOOLCHAIN_64_URL=https://github.com/godotengine/buildroot/releases/download/godot-2020.11.x-2/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
TOOLCHAIN_64_SHA=16c8302fcb676c1f0fb9df73d6cff250ba1f4286
TOOLCHAIN_32_URL=https://github.com/godotengine/buildroot/releases/download/godot-2020.11.x-2/i686-godot-linux-gnu_sdk-buildroot.tar.bz2
TOOLCHAIN_32_SHA=6171652abc54ef219e5187bc53660ee4e2f796f4
# ! Export variables:
if [[ "${{ inputs.arch }}" == "x86_64" ]]; then
echo "TOOLCHAIN_URL=${TOOLCHAIN_64_URL}" >> "$GITHUB_ENV"
echo "TOOLCHAIN_SHA=${TOOLCHAIN_64_SHA}" >> "$GITHUB_ENV"
elif [[ "${{ inputs.arch }}" == "x86_32" ]]; then
echo "TOOLCHAIN_URL=${TOOLCHAIN_32_URL}" >> "$GITHUB_ENV"
echo "TOOLCHAIN_SHA=${TOOLCHAIN_32_SHA}" >> "$GITHUB_ENV"
fi
- name: Cache buildroot
id: cache-buildroot
uses: actions/cache@v4
with:
path: buildroot
key: ${{env.TOOLCHAIN_SHA}}
- name: Set up buildroot
if: steps.cache-buildroot.outputs.cache-hit != 'true'
shell: bash
run: |
mkdir buildroot
wget ${TOOLCHAIN_URL} -O buildroot/buildroot.tar.bz2
cd buildroot
echo "${TOOLCHAIN_SHA} buildroot.tar.bz2"
echo "${TOOLCHAIN_SHA} buildroot.tar.bz2" | shasum --check
tar -xjf buildroot.tar.bz2 --strip-components=1
ls -l
rm buildroot.tar.bz2
./relocate-sdk.sh
cd ..

View File

@ -36,7 +36,6 @@ env:
SCONSFLAGS: dev_build=no debug_symbols=no SCONSFLAGS: dev_build=no debug_symbols=no
EM_VERSION: 3.1.45 EM_VERSION: 3.1.45
EM_CACHE_FOLDER: "emsdk-cache" EM_CACHE_FOLDER: "emsdk-cache"
GODOT_VERSION: 4.2-stable
jobs: jobs:
gdextension: gdextension:
@ -95,70 +94,14 @@ jobs:
platform: web platform: web
target: template_release target: template_release
arch: wasm32 arch: wasm32
should-build: ${{ !inputs.test-build }} should-build: true
- name: 🌐 Web (wasm32, debug) - name: 🌐 Web (wasm32, debug)
runner: ubuntu-20.04 runner: ubuntu-20.04
platform: web platform: web
target: template_debug target: template_debug
arch: wasm32 arch: wasm32
should-build: ${{ !inputs.test-build }} should-build: true
- name: 🤖 Android (arm64, release)
runner: ubuntu-20.04
platform: android
target: template_release
arch: arm64
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (arm64, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
arch: arm64
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (arm32, release)
runner: ubuntu-20.04
platform: android
target: template_release
arch: arm32
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (arm32, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
arch: arm32
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (x86_64, release)
runner: ubuntu-20.04
platform: android
target: template_release
arch: x86_64
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (x86_64, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
arch: x86_64
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (x86_32, release)
runner: ubuntu-20.04
platform: android
target: template_release
arch: x86_32
should-build: ${{ !inputs.test-build }}
- name: 🤖 Android (x86_32, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
arch: x86_32
should-build: ${{ !inputs.test-build }}
exclude: exclude:
- { opts: { should-build: false } } - { opts: { should-build: false } }
@ -189,11 +132,25 @@ jobs:
id: output-name-prefix id: output-name-prefix
run: echo "name-prefix=${NAME_PREFIX}" >> $GITHUB_OUTPUT run: echo "name-prefix=${NAME_PREFIX}" >> $GITHUB_OUTPUT
- name: Setup Linux toolchain - name: Set up Linux buildroot x86_64
if: matrix.opts.platform == 'linux' if: matrix.opts.platform == 'linux' && matrix.opts.arch == 'x86_64'
uses: ./limboai/.github/actions/setup-linux-toolchain run: |
with: wget https://download.tuxfamily.org/godotengine/toolchains/linux/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
arch: ${{matrix.opts.arch}} tar -xjf x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
mv x86_64-godot-linux-gnu_sdk-buildroot buildroot
cd buildroot
./relocate-sdk.sh
cd ..
- name: Set up Linux buildroot x86_32
if: matrix.opts.platform == 'linux' && matrix.opts.arch == 'x86_32'
run: |
wget https://download.tuxfamily.org/godotengine/toolchains/linux/i686-godot-linux-gnu_sdk-buildroot.tar.bz2
tar -xjf i686-godot-linux-gnu_sdk-buildroot.tar.bz2
mv i686-godot-linux-gnu_sdk-buildroot buildroot
cd buildroot
./relocate-sdk.sh
cd ..
- name: Set up Python 3.x - name: Set up Python 3.x
if: matrix.opts.platform == 'windows' || matrix.opts.platform == 'macos' if: matrix.opts.platform == 'windows' || matrix.opts.platform == 'macos'
@ -222,27 +179,13 @@ jobs:
emcc -v emcc -v
- name: Set up scons - name: Set up scons
if: matrix.opts.platform != 'linux' if: matrix.opts.platform == 'windows' || matrix.opts.platform == 'macos' || matrix.opts.platform == 'web'
run: | run: |
python -c "import sys; print(sys.version)" python -c "import sys; print(sys.version)"
python -m pip install scons==4.4.0 python -m pip install scons==4.4.0
python --version python --version
scons --version scons --version
- name: Set up Java 17
if: matrix.opts.platform == 'android'
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- uses: nttld/setup-ndk@v1
if: matrix.opts.platform == 'android'
id: setup-ndk
with:
ndk-version: r23c
link-to-sdk: true
- name: Set up MSVC problem matcher on Windows - name: Set up MSVC problem matcher on Windows
if: matrix.opts.platform == 'windows' if: matrix.opts.platform == 'windows'
uses: ammaraskar/msvc-problem-matcher@master uses: ammaraskar/msvc-problem-matcher@master
@ -288,7 +231,7 @@ jobs:
ls -R out/ ls -R out/
- name: Strip lib - name: Strip lib
if: matrix.opts.platform != 'windows' && matrix.opts.platform != 'web' && (matrix.opts.platform != 'android' || startsWith(matrix.opts.arch, 'x86')) if: matrix.opts.platform != 'windows' && matrix.opts.platform != 'web'
run: | run: |
ls -l -R out/addons/limboai/bin/ ls -l -R out/addons/limboai/bin/
echo "---" echo "---"
@ -308,8 +251,8 @@ jobs:
name: ${{ env.NAME }} name: ${{ env.NAME }}
path: out/* path: out/*
package-extension: merge-artifacts:
name: 📦 Package extension name: Merge artifacts
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: gdextension needs: gdextension
@ -320,48 +263,3 @@ jobs:
name: ${{needs.gdextension.outputs.name-prefix}} name: ${{needs.gdextension.outputs.name-prefix}}
pattern: tmp-gdextension.* pattern: tmp-gdextension.*
delete-merged: true delete-merged: true
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{needs.gdextension.outputs.name-prefix}}
path: out/
- name: Setup Godot
shell: bash
run: |
echo "Downloading Godot ${GODOT_VERSION}"
mkdir bin
cd bin
wget "https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
unzip godot.zip
rm godot.zip
mv Godot_* godot
chmod u+x godot
ls -l
cd ..
./bin/godot --version
- name: Generate icon .import files
shell: bash
run: |
touch out/project.godot
timeout 20s ./bin/godot --headless --editor --path ./out/ || /bin/true
rm out/project.godot
rm -rf out/.godot/
- name: Change editor icon import settings
shell: bash
run: |
echo "--- Listing icons dir:"
ls out/addons/limboai/icons/
echo "--- (end of listing)"
sed -i 's|editor/scale_with_editor_scale=false|editor/scale_with_editor_scale=true|' out/addons/limboai/icons/*.import
sed -i 's|editor/convert_colors_with_editor_theme=false|editor/convert_colors_with_editor_theme=true|' out/addons/limboai/icons/*.import
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{needs.gdextension.outputs.name-prefix}}
path: out/*
overwrite: true

View File

@ -139,10 +139,27 @@ jobs:
# Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables. # Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
- uses: ./modules/limboai/.github/actions/init-version - uses: ./modules/limboai/.github/actions/init-version
- name: Set up Linux toolchain # About sed see: https://github.com/godotengine/buildroot/issues/6
uses: ./modules/limboai/.github/actions/setup-linux-toolchain - name: Set up buildroot x86_64
with: if: matrix.opts.arch == 'x86_64'
arch: ${{matrix.opts.arch}} run: |
wget https://download.tuxfamily.org/godotengine/toolchains/linux/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
tar -xjf x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
mv x86_64-godot-linux-gnu_sdk-buildroot buildroot
cd buildroot
sed -i x86_64-godot-linux-gnu/sysroot/usr/lib/pkgconfig/dbus-1.pc -e "s@/lib@/lib64@g"
./relocate-sdk.sh
cd ..
- name: Set up buildroot x86_32
if: matrix.opts.arch == 'x86_32'
run: |
wget https://download.tuxfamily.org/godotengine/toolchains/linux/i686-godot-linux-gnu_sdk-buildroot.tar.bz2
tar -xjf i686-godot-linux-gnu_sdk-buildroot.tar.bz2
mv i686-godot-linux-gnu_sdk-buildroot buildroot
cd buildroot
./relocate-sdk.sh
cd ..
- name: Set up scons cache - name: Set up scons cache
uses: actions/cache@v4 uses: actions/cache@v4

View File

@ -26,8 +26,8 @@ concurrency:
# Global Settings. # Global Settings.
env: env:
GODOT_REF: "master" GODOT_REF: "4.2"
GODOT_CPP_REF: "master" GODOT_CPP_REF: "4.2"
jobs: jobs:
unit-tests: unit-tests:
@ -52,10 +52,16 @@ jobs:
with: with:
path: modules/limboai path: modules/limboai
- name: Set up Linux toolchain # About sed see: https://github.com/godotengine/buildroot/issues/6
uses: ./modules/limboai/.github/actions/setup-linux-toolchain - name: Set up buildroot x86_64
with: run: |
arch: x86_64 wget https://download.tuxfamily.org/godotengine/toolchains/linux/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
tar -xjf x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
mv x86_64-godot-linux-gnu_sdk-buildroot buildroot
cd buildroot
sed -i x86_64-godot-linux-gnu/sysroot/usr/lib/pkgconfig/dbus-1.pc -e "s@/lib@/lib64@g"
./relocate-sdk.sh
cd ..
- name: Set up scons cache - name: Set up scons cache
uses: actions/cache@v4 uses: actions/cache@v4

View File

@ -29,14 +29,13 @@ Behavior Trees are powerful hierarchical structures used to model and control th
![Charger from Demo](doc/images/demo_charger.gif) ![Charger from Demo](doc/images/demo_charger.gif)
>**🛈 Demo project** lives in the `demo` folder and is available separately in [**Releases**](https://github.com/limbonaut/limboai/releases).
> Run `demo/scenes/showcase.tscn` to get started.
> It also includes a tutorial that introduces behavior trees through illustrative examples.
### Videos ### Videos
<a href="https://www.youtube.com/watch?v=NWaMArUg7mY"><img src="https://img.youtube.com/vi/NWaMArUg7mY/0.jpg" width=410></a> [![Demonstration](https://img.youtube.com/vi/NWaMArUg7mY/0.jpg)](https://www.youtube.com/watch?v=NWaMArUg7mY)
<a href="https://www.youtube.com/watch?v=aP0Aacdxmno"><img src="https://img.youtube.com/vi/aP0Aacdxmno/0.jpg" width=410></a>
>**🛈 Demo project** lives in the `demo` folder and is available separately in [**Releases**](https://github.com/limbonaut/limboai/releases).
> Run `demo/scenes/showcase.tscn` to get started.
> It also contains a tutorial that introduces behavior trees using examples.
## Features ## Features
@ -73,10 +72,6 @@ Behavior Trees are powerful hierarchical structures used to model and control th
- **Demo + Tutorial:** Check out our extensive demo project, which includes an introduction to behavior trees using examples. - **Demo + Tutorial:** Check out our extensive demo project, which includes an introduction to behavior trees using examples.
## First steps
Follow the [First steps](https://limboai.readthedocs.io/en/latest/index.html#first-steps) guide to learn how to get started with LimboAI and the demo project.
## Getting LimboAI ## Getting LimboAI
LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/latest/getting-started/gdextension.html). LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/latest/getting-started/gdextension.html).
@ -98,7 +93,6 @@ LimboAI can be used as either a C++ module or as a GDExtension shared library. G
## Using the plugin ## Using the plugin
- [Online Documentation](https://limboai.readthedocs.io/en/latest/index.html) - [Online Documentation](https://limboai.readthedocs.io/en/latest/index.html)
- [First steps](https://limboai.readthedocs.io/en/latest/index.html#first-steps)
- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/latest/getting-started/introduction.html) - [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/latest/getting-started/introduction.html)
- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/latest/getting-started/custom-tasks.html) - [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/latest/getting-started/custom-tasks.html)
- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/latest/getting-started/using-blackboard.html) - [Sharing data using Blackboard](https://limboai.readthedocs.io/en/latest/getting-started/using-blackboard.html)
@ -120,6 +114,18 @@ Need help? We have a Discord server: https://discord.gg/N5MGC95GpP
I write about LimboAI development on Mastodon: https://mastodon.gamedev.place/@limbo. I write about LimboAI development on Mastodon: https://mastodon.gamedev.place/@limbo.
## Roadmap
Features and improvements that may be implemented in the future:
- ~~Providing precompiled builds for download.~~ 🗸
- ~~Tests and CI.~~ 🗸
- ~~GDExtension support.~~ 🗸
- ~~Extensive demo project.~~ 🗸
- Expanding the library of commonly useful tasks.
- Exploring the execution history of behavior trees in the visual debugger.
- Per-project ignore list for tasks that users may want to hide in the task palette.
- GUI editor for state machines.
## License ## License
Use of this source code is governed by an MIT-style license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT. Use of this source code is governed by an MIT-style license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.

4
SCsub
View File

@ -7,10 +7,6 @@ module_env = env.Clone()
module_env.Append(CPPDEFINES=["LIMBOAI_MODULE"]) module_env.Append(CPPDEFINES=["LIMBOAI_MODULE"])
import limboai_version
limboai_version.generate_module_version_header()
module_env.add_source_files(env.modules_sources, "*.cpp") module_env.add_source_files(env.modules_sources, "*.cpp")
module_env.add_source_files(env.modules_sources, "blackboard/*.cpp") module_env.add_source_files(env.modules_sources, "blackboard/*.cpp")
module_env.add_source_files(env.modules_sources, "blackboard/bb_param/*.cpp") module_env.add_source_files(env.modules_sources, "blackboard/bb_param/*.cpp")

View File

@ -18,8 +18,6 @@ class BBAabb : public BBParam {
GDCLASS(BBAabb, BBParam); GDCLASS(BBAabb, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::AABB; } virtual Variant::Type get_type() const override { return Variant::AABB; }
}; };

View File

@ -18,8 +18,6 @@ class BBArray : public BBParam {
GDCLASS(BBArray, BBParam); GDCLASS(BBArray, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::ARRAY; } virtual Variant::Type get_type() const override { return Variant::ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBBasis : public BBParam {
GDCLASS(BBBasis, BBParam); GDCLASS(BBBasis, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::BASIS; } virtual Variant::Type get_type() const override { return Variant::BASIS; }
}; };

View File

@ -18,8 +18,6 @@ class BBBool : public BBParam {
GDCLASS(BBBool, BBParam); GDCLASS(BBBool, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::BOOL; } virtual Variant::Type get_type() const override { return Variant::BOOL; }
}; };

View File

@ -18,8 +18,6 @@ class BBByteArray : public BBParam {
GDCLASS(BBByteArray, BBParam); GDCLASS(BBByteArray, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_BYTE_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_BYTE_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBColor : public BBParam {
GDCLASS(BBColor, BBParam); GDCLASS(BBColor, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::COLOR; } virtual Variant::Type get_type() const override { return Variant::COLOR; }
}; };

View File

@ -18,8 +18,6 @@ class BBColorArray : public BBParam {
GDCLASS(BBColorArray, BBParam); GDCLASS(BBColorArray, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_COLOR_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_COLOR_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBDictionary : public BBParam {
GDCLASS(BBDictionary, BBParam); GDCLASS(BBDictionary, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::DICTIONARY; } virtual Variant::Type get_type() const override { return Variant::DICTIONARY; }
}; };

View File

@ -18,8 +18,6 @@ class BBFloat : public BBParam {
GDCLASS(BBFloat, BBParam); GDCLASS(BBFloat, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::FLOAT; } virtual Variant::Type get_type() const override { return Variant::FLOAT; }
}; };

View File

@ -18,8 +18,6 @@ class BBFloat32Array : public BBParam {
GDCLASS(BBFloat32Array, BBParam); GDCLASS(BBFloat32Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_FLOAT32_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_FLOAT32_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBFloat64Array : public BBParam {
GDCLASS(BBFloat64Array, BBParam); GDCLASS(BBFloat64Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_FLOAT64_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_FLOAT64_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBInt : public BBParam {
GDCLASS(BBInt, BBParam); GDCLASS(BBInt, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::INT; } virtual Variant::Type get_type() const override { return Variant::INT; }
}; };

View File

@ -18,8 +18,6 @@ class BBInt32Array : public BBParam {
GDCLASS(BBInt32Array, BBParam); GDCLASS(BBInt32Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_INT32_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_INT32_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBInt64Array : public BBParam {
GDCLASS(BBInt64Array, BBParam); GDCLASS(BBInt64Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_INT64_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_INT64_ARRAY; }
}; };

View File

@ -20,9 +20,9 @@
#include <godot_cpp/classes/node.hpp> #include <godot_cpp/classes/node.hpp>
#endif // LIMBOAI_GDEXTENSION #endif // LIMBOAI_GDEXTENSION
Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default) { Variant BBNode::get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard, const Variant &p_default) {
ERR_FAIL_NULL_V_MSG(p_scene_root, Variant(), "BBNode: get_value() failed - scene_root is null."); ERR_FAIL_COND_V(p_agent == nullptr, Variant());
ERR_FAIL_NULL_V_MSG(p_blackboard, Variant(), "BBNode: get_value() failed - blackboard is null."); ERR_FAIL_COND_V(!p_blackboard.is_valid(), Variant());
Variant val; Variant val;
if (get_value_source() == SAVED_VALUE) { if (get_value_source() == SAVED_VALUE) {
@ -32,7 +32,9 @@ Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboar
} }
if (val.get_type() == Variant::NODE_PATH) { if (val.get_type() == Variant::NODE_PATH) {
return p_scene_root->get_node_or_null(val); Node *agent = Object::cast_to<Node>(p_agent);
ERR_FAIL_COND_V_MSG(agent == nullptr, Variant(), "BBNode: p_agent must be a Node.");
return agent->get_node_or_null(val);
} else { } else {
Object *obj = val; Object *obj = val;
if (unlikely(obj == nullptr && val.get_type() != Variant::NIL)) { if (unlikely(obj == nullptr && val.get_type() != Variant::NIL)) {

View File

@ -18,11 +18,10 @@ class BBNode : public BBParam {
GDCLASS(BBNode, BBParam); GDCLASS(BBNode, BBParam);
protected: protected:
static void _bind_methods() {} virtual Variant::Type get_type() const override { return Variant::NODE_PATH; }
public: public:
virtual Variant::Type get_type() const override { return Variant::NODE_PATH; } virtual Variant get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant()) override;
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant()) override;
}; };
#endif // BB_NODE_H #endif // BB_NODE_H

View File

@ -75,7 +75,7 @@ String BBParam::_to_string() {
} }
} }
Variant BBParam::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default) { Variant BBParam::get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard, const Variant &p_default) {
ERR_FAIL_COND_V(!p_blackboard.is_valid(), p_default); ERR_FAIL_COND_V(!p_blackboard.is_valid(), p_default);
if (value_source == SAVED_VALUE) { if (value_source == SAVED_VALUE) {
@ -105,7 +105,7 @@ void BBParam::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_variable", "variable_name"), &BBParam::set_variable); ClassDB::bind_method(D_METHOD("set_variable", "variable_name"), &BBParam::set_variable);
ClassDB::bind_method(D_METHOD("get_variable"), &BBParam::get_variable); ClassDB::bind_method(D_METHOD("get_variable"), &BBParam::get_variable);
ClassDB::bind_method(D_METHOD("get_type"), &BBParam::get_type); ClassDB::bind_method(D_METHOD("get_type"), &BBParam::get_type);
ClassDB::bind_method(D_METHOD("get_value", "scene_root", "blackboard", "default"), &BBParam::get_value, Variant()); ClassDB::bind_method(D_METHOD("get_value", "agent", "blackboard", "default"), &BBParam::get_value, Variant());
ADD_PROPERTY(PropertyInfo(Variant::INT, "value_source", PROPERTY_HINT_ENUM, "Saved Value,Blackboard Var"), "set_value_source", "get_value_source"); ADD_PROPERTY(PropertyInfo(Variant::INT, "value_source", PROPERTY_HINT_ENUM, "Saved Value,Blackboard Var"), "set_value_source", "get_value_source");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "variable", PROPERTY_HINT_NONE, "", 0), "set_variable", "get_variable"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "variable", PROPERTY_HINT_NONE, "", 0), "set_variable", "get_variable");

View File

@ -49,6 +49,8 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
public: public:
virtual Variant::Type get_type() const { return Variant::NIL; }
void set_value_source(ValueSource p_value); void set_value_source(ValueSource p_value);
ValueSource get_value_source() const { return value_source; } ValueSource get_value_source() const { return value_source; }
@ -64,9 +66,7 @@ public:
virtual String _to_string(); virtual String _to_string();
#endif #endif
virtual Variant::Type get_type() const { return Variant::NIL; } virtual Variant get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant());
virtual Variant::Type get_variable_expected_type() const { return get_type(); }
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant());
BBParam(); BBParam();
}; };

View File

@ -18,8 +18,6 @@ class BBPlane : public BBParam {
GDCLASS(BBPlane, BBParam); GDCLASS(BBPlane, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PLANE; } virtual Variant::Type get_type() const override { return Variant::PLANE; }
}; };

View File

@ -18,8 +18,6 @@ class BBProjection : public BBParam {
GDCLASS(BBProjection, BBParam); GDCLASS(BBProjection, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PROJECTION; } virtual Variant::Type get_type() const override { return Variant::PROJECTION; }
}; };

View File

@ -18,8 +18,6 @@ class BBQuaternion : public BBParam {
GDCLASS(BBQuaternion, BBParam); GDCLASS(BBQuaternion, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::QUATERNION; } virtual Variant::Type get_type() const override { return Variant::QUATERNION; }
}; };

View File

@ -18,8 +18,6 @@ class BBRect2 : public BBParam {
GDCLASS(BBRect2, BBParam); GDCLASS(BBRect2, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::RECT2; } virtual Variant::Type get_type() const override { return Variant::RECT2; }
}; };

View File

@ -18,8 +18,6 @@ class BBRect2i : public BBParam {
GDCLASS(BBRect2i, BBParam); GDCLASS(BBRect2i, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::RECT2I; } virtual Variant::Type get_type() const override { return Variant::RECT2I; }
}; };

View File

@ -18,8 +18,6 @@ class BBString : public BBParam {
GDCLASS(BBString, BBParam); GDCLASS(BBString, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::STRING; } virtual Variant::Type get_type() const override { return Variant::STRING; }
}; };

View File

@ -18,8 +18,6 @@ class BBStringArray : public BBParam {
GDCLASS(BBStringArray, BBParam); GDCLASS(BBStringArray, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_STRING_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_STRING_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBStringName : public BBParam {
GDCLASS(BBStringName, BBParam); GDCLASS(BBStringName, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::STRING_NAME; } virtual Variant::Type get_type() const override { return Variant::STRING_NAME; }
}; };

View File

@ -18,8 +18,6 @@ class BBTransform2D : public BBParam {
GDCLASS(BBTransform2D, BBParam); GDCLASS(BBTransform2D, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::TRANSFORM2D; } virtual Variant::Type get_type() const override { return Variant::TRANSFORM2D; }
}; };

View File

@ -18,8 +18,6 @@ class BBTransform3D : public BBParam {
GDCLASS(BBTransform3D, BBParam); GDCLASS(BBTransform3D, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::TRANSFORM3D; } virtual Variant::Type get_type() const override { return Variant::TRANSFORM3D; }
}; };

View File

@ -27,8 +27,6 @@ public:
virtual Variant::Type get_type() const override; virtual Variant::Type get_type() const override;
void set_type(Variant::Type p_type); void set_type(Variant::Type p_type);
virtual Variant::Type get_variable_expected_type() const override { return Variant::NIL; }
BBVariant(const Variant &p_value); BBVariant(const Variant &p_value);
BBVariant(); BBVariant();
}; };

View File

@ -18,8 +18,6 @@ class BBVector2 : public BBParam {
GDCLASS(BBVector2, BBParam); GDCLASS(BBVector2, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR2; } virtual Variant::Type get_type() const override { return Variant::VECTOR2; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector2Array : public BBParam {
GDCLASS(BBVector2Array, BBParam); GDCLASS(BBVector2Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_VECTOR2_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_VECTOR2_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector2i : public BBParam {
GDCLASS(BBVector2i, BBParam); GDCLASS(BBVector2i, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR2I; } virtual Variant::Type get_type() const override { return Variant::VECTOR2I; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector3 : public BBParam {
GDCLASS(BBVector3, BBParam); GDCLASS(BBVector3, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR3; } virtual Variant::Type get_type() const override { return Variant::VECTOR3; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector3Array : public BBParam {
GDCLASS(BBVector3Array, BBParam); GDCLASS(BBVector3Array, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::PACKED_VECTOR3_ARRAY; } virtual Variant::Type get_type() const override { return Variant::PACKED_VECTOR3_ARRAY; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector3i : public BBParam {
GDCLASS(BBVector3i, BBParam); GDCLASS(BBVector3i, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR3I; } virtual Variant::Type get_type() const override { return Variant::VECTOR3I; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector4 : public BBParam {
GDCLASS(BBVector4, BBParam); GDCLASS(BBVector4, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR4; } virtual Variant::Type get_type() const override { return Variant::VECTOR4; }
}; };

View File

@ -18,8 +18,6 @@ class BBVector4i : public BBParam {
GDCLASS(BBVector4i, BBParam); GDCLASS(BBVector4i, BBParam);
protected: protected:
static void _bind_methods() {}
virtual Variant::Type get_type() const override { return Variant::VECTOR4I; } virtual Variant::Type get_type() const override { return Variant::VECTOR4I; }
}; };

View File

@ -64,36 +64,6 @@ void Blackboard::erase_var(const StringName &p_name) {
data.erase(p_name); data.erase(p_name);
} }
TypedArray<StringName> Blackboard::list_vars() const {
TypedArray<StringName> var_names;
var_names.resize(data.size());
int idx = 0;
for (const KeyValue<StringName, BBVariable> &kv : data) {
var_names[idx] = kv.key;
idx += 1;
}
return var_names;
}
Dictionary Blackboard::get_vars_as_dict() const {
Dictionary dict;
for (const KeyValue<StringName, BBVariable> &kv : data) {
dict[kv.key] = kv.value.get_value();
}
return dict;
}
void Blackboard::populate_from_dict(const Dictionary &p_dictionary) {
Array keys = p_dictionary.keys();
for (int i = 0; i < keys.size(); i++) {
if (keys[i].get_type() == Variant::STRING_NAME || keys[i].get_type() == Variant::STRING) {
set_var(keys[i], p_dictionary[keys[i]]);
} else {
ERR_PRINT("Blackboard: Invalid key type in dictionary to populate blackboard. Must be StringName or String.");
}
}
}
void Blackboard::bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create) { void Blackboard::bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create) {
if (!data.has(p_name)) { if (!data.has(p_name)) {
if (p_create) { if (p_create) {
@ -106,7 +76,7 @@ void Blackboard::bind_var_to_property(const StringName &p_name, Object *p_object
} }
void Blackboard::unbind_var(const StringName &p_name) { void Blackboard::unbind_var(const StringName &p_name) {
ERR_FAIL_COND_MSG(!data.has(p_name), "Blackboard: Can't unbind variable that doesn't exist (var: " + p_name + ")."); ERR_FAIL_COND_MSG(data.has(p_name), "Blackboard: Can't unbind variable that doesn't exist (var: " + p_name + ").");
data[p_name].unbind(); data[p_name].unbind();
} }
@ -128,16 +98,12 @@ void Blackboard::link_var(const StringName &p_name, const Ref<Blackboard> &p_tar
} }
void Blackboard::_bind_methods() { void Blackboard::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_var", "var_name", "default", "complain"), &Blackboard::get_var, DEFVAL(Variant()), DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_var", "var_name", "default", "complain"), &Blackboard::get_var, Variant(), true);
ClassDB::bind_method(D_METHOD("set_var", "var_name", "value"), &Blackboard::set_var); ClassDB::bind_method(D_METHOD("set_var", "var_name", "value"), &Blackboard::set_var);
ClassDB::bind_method(D_METHOD("has_var", "var_name"), &Blackboard::has_var); ClassDB::bind_method(D_METHOD("has_var", "var_name"), &Blackboard::has_var);
ClassDB::bind_method(D_METHOD("set_parent", "blackboard"), &Blackboard::set_parent); ClassDB::bind_method(D_METHOD("set_parent", "blackboard"), &Blackboard::set_parent);
ClassDB::bind_method(D_METHOD("get_parent"), &Blackboard::get_parent); ClassDB::bind_method(D_METHOD("get_parent"), &Blackboard::get_parent);
ClassDB::bind_method(D_METHOD("erase_var", "var_name"), &Blackboard::erase_var); ClassDB::bind_method(D_METHOD("erase_var", "var_name"), &Blackboard::erase_var);
ClassDB::bind_method(D_METHOD("clear"), &Blackboard::clear);
ClassDB::bind_method(D_METHOD("list_vars"), &Blackboard::list_vars);
ClassDB::bind_method(D_METHOD("get_vars_as_dict"), &Blackboard::get_vars_as_dict);
ClassDB::bind_method(D_METHOD("populate_from_dict", "dictionary"), &Blackboard::populate_from_dict);
ClassDB::bind_method(D_METHOD("top"), &Blackboard::top); ClassDB::bind_method(D_METHOD("top"), &Blackboard::top);
ClassDB::bind_method(D_METHOD("bind_var_to_property", "var_name", "object", "property", "create"), &Blackboard::bind_var_to_property, DEFVAL(false)); ClassDB::bind_method(D_METHOD("bind_var_to_property", "var_name", "object", "property", "create"), &Blackboard::bind_var_to_property, DEFVAL(false));
ClassDB::bind_method(D_METHOD("unbind_var", "var_name"), &Blackboard::unbind_var); ClassDB::bind_method(D_METHOD("unbind_var", "var_name"), &Blackboard::unbind_var);

View File

@ -46,15 +46,10 @@ public:
Ref<Blackboard> top() const; Ref<Blackboard> top() const;
Variant get_var(const StringName &p_name, const Variant &p_default = Variant(), bool p_complain = true) const; Variant get_var(const StringName &p_name, const Variant &p_default, bool p_complain = true) const;
void set_var(const StringName &p_name, const Variant &p_value); void set_var(const StringName &p_name, const Variant &p_value);
bool has_var(const StringName &p_name) const; bool has_var(const StringName &p_name) const;
void erase_var(const StringName &p_name); void erase_var(const StringName &p_name);
void clear() { data.clear(); }
TypedArray<StringName> list_vars() const;
Dictionary get_vars_as_dict() const;
void populate_from_dict(const Dictionary &p_dictionary);
void bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create = false); void bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create = false);
void unbind_var(const StringName &p_name); void unbind_var(const StringName &p_name);
@ -62,6 +57,8 @@ public:
void assign_var(const StringName &p_name, const BBVariable &p_var); void assign_var(const StringName &p_name, const BBVariable &p_var);
void link_var(const StringName &p_name, const Ref<Blackboard> &p_target_blackboard, const StringName &p_target_var, bool p_create = false); void link_var(const StringName &p_name, const Ref<Blackboard> &p_target_blackboard, const StringName &p_target_var, bool p_create = false);
// TODO: Add serialization API.
}; };
#endif // BLACKBOARD_H #endif // BLACKBOARD_H

View File

@ -11,8 +11,6 @@
#include "blackboard_plan.h" #include "blackboard_plan.h"
#include "../util/limbo_utility.h"
bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) { bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
String name_str = p_name; String name_str = p_name;
@ -27,28 +25,6 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
return true; return true;
} }
// * Mapping
if (name_str.begins_with("mapping/")) {
StringName mapped_var_name = name_str.get_slicec('/', 1);
StringName value = p_value;
bool properties_changed = false;
if (value == StringName()) {
if (parent_scope_mapping.has(mapped_var_name)) {
properties_changed = true;
parent_scope_mapping.erase(mapped_var_name);
}
} else {
if (!parent_scope_mapping.has(mapped_var_name)) {
properties_changed = true;
}
parent_scope_mapping[mapped_var_name] = value;
}
if (properties_changed) {
notify_property_list_changed();
}
return true;
}
// * Storage // * Storage
if (name_str.begins_with("var/")) { if (name_str.begins_with("var/")) {
StringName var_name = name_str.get_slicec('/', 1); StringName var_name = name_str.get_slicec('/', 1);
@ -80,23 +56,7 @@ bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
// * Editor // * Editor
if (var_map.has(p_name)) { if (var_map.has(p_name)) {
if (has_mapping(p_name)) {
r_ret = "Mapped to " + LimboUtility::get_singleton()->decorate_var(parent_scope_mapping[p_name]);
} else {
r_ret = var_map[p_name].get_value(); r_ret = var_map[p_name].get_value();
}
return true;
}
// * Mapping
if (name_str.begins_with("mapping/")) {
StringName mapped_var_name = name_str.get_slicec('/', 1);
ERR_FAIL_COND_V(mapped_var_name == StringName(), false);
if (parent_scope_mapping.has(mapped_var_name)) {
r_ret = parent_scope_mapping[mapped_var_name];
} else {
r_ret = StringName();
}
return true; return true;
} }
@ -104,6 +64,7 @@ bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
if (!name_str.begins_with("var/")) { if (!name_str.begins_with("var/")) {
return false; return false;
} }
StringName var_name = name_str.get_slicec('/', 1); StringName var_name = name_str.get_slicec('/', 1);
String what = name_str.get_slicec('/', 2); String what = name_str.get_slicec('/', 2);
ERR_FAIL_COND_V(!var_map.has(var_name), false); ERR_FAIL_COND_V(!var_map.has(var_name), false);
@ -129,49 +90,29 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
// * Editor // * Editor
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) { if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
if (has_mapping(var_name)) {
p_list->push_back(PropertyInfo(Variant::STRING, var_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
} else {
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR)); p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
} }
}
// * Storage
if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) { if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) {
// Don't store variable if it's not modified in a derived plan. // Don't store variable if it's not modified in a derived plan.
// Variable is considered modified when it's marked as changed and its value is different from the base plan. // Variable is considered modified when it's marked as changed and its value is different from the base plan.
continue; continue;
} }
// * Storage
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(var.get_type(), "var/" + var_name + "/value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(var.get_type(), "var/" + var_name + "/value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/hint_string", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/hint_string", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
} }
// * Mapping
if (is_mapping_enabled()) {
p_list->push_back(PropertyInfo(Variant::NIL, "Mapping", PROPERTY_HINT_NONE, "mapping/", PROPERTY_USAGE_GROUP));
for (const Pair<StringName, BBVariable> &p : var_list) {
// Serialize only non-empty mappings.
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
}
}
} }
bool BlackboardPlan::_property_can_revert(const StringName &p_name) const { bool BlackboardPlan::_property_can_revert(const StringName &p_name) const {
if (String(p_name).begins_with("mapping/")) {
return true;
}
return base.is_valid() && base->var_map.has(p_name); return base.is_valid() && base->var_map.has(p_name);
} }
bool BlackboardPlan::_property_get_revert(const StringName &p_name, Variant &r_property) const { bool BlackboardPlan::_property_get_revert(const StringName &p_name, Variant &r_property) const {
if (String(p_name).begins_with("mapping/")) {
r_property = StringName();
return true;
}
if (base->var_map.has(p_name)) { if (base->var_map.has(p_name)) {
r_property = base->var_map[p_name].get_value(); r_property = base->var_map[p_name].get_value();
return true; return true;
@ -190,15 +131,6 @@ void BlackboardPlan::set_base_plan(const Ref<BlackboardPlan> &p_base) {
notify_property_list_changed(); notify_property_list_changed();
} }
void BlackboardPlan::set_parent_scope_plan_provider(const Callable &p_parent_scope_plan_provider) {
parent_scope_plan_provider = p_parent_scope_plan_provider;
notify_property_list_changed();
}
bool BlackboardPlan::has_mapping(const StringName &p_name) const {
return is_mapping_enabled() && parent_scope_mapping.has(p_name) && parent_scope_mapping[p_name] != StringName();
}
void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) { void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) {
prefetch_nodepath_vars = p_enable; prefetch_nodepath_vars = p_enable;
emit_changed(); emit_changed();
@ -240,8 +172,8 @@ Pair<StringName, BBVariable> BlackboardPlan::get_var_by_index(int p_index) {
return var_list.get(p_index); return var_list.get(p_index);
} }
TypedArray<StringName> BlackboardPlan::list_vars() const { PackedStringArray BlackboardPlan::list_vars() const {
TypedArray<StringName> ret; PackedStringArray ret;
for (const Pair<StringName, BBVariable> &p : var_list) { for (const Pair<StringName, BBVariable> &p : var_list) {
ret.append(p.first); ret.append(p.first);
} }
@ -282,11 +214,6 @@ void BlackboardPlan::rename_var(const StringName &p_name, const StringName &p_ne
var_map.erase(p_name); var_map.erase(p_name);
var_map.insert(p_new_name, var); var_map.insert(p_new_name, var);
if (parent_scope_mapping.has(p_name)) {
parent_scope_mapping[p_new_name] = parent_scope_mapping[p_name];
parent_scope_mapping.erase(p_name);
}
notify_property_list_changed(); notify_property_list_changed();
emit_changed(); emit_changed();
} }
@ -408,11 +335,12 @@ inline void bb_add_var_dup_with_prefetch(const Ref<Blackboard> &p_blackboard, co
} }
} }
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node, const Ref<Blackboard> &p_parent_scope) { Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node) {
ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard)); ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
Ref<Blackboard> bb = memnew(Blackboard); Ref<Blackboard> bb = memnew(Blackboard);
bb->set_parent(p_parent_scope); for (const Pair<StringName, BBVariable> &p : var_list) {
populate_blackboard(bb, true, p_node); bb_add_var_dup_with_prefetch(bb, p.first, p.second, prefetch_nodepath_vars, p_node);
}
return bb; return bb;
} }
@ -423,13 +351,6 @@ void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bo
continue; continue;
} }
bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, prefetch_nodepath_vars, p_node); bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, prefetch_nodepath_vars, p_node);
if (parent_scope_mapping.has(p.first)) {
StringName target_var = parent_scope_mapping[p.first];
if (target_var != StringName()) {
ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable $%s to parent scope because the parent scope is not set.", p.first));
p_blackboard->link_var(p.first, p_blackboard->get_parent(), target_var);
}
}
} }
} }
@ -441,9 +362,7 @@ void BlackboardPlan::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_base_plan"), &BlackboardPlan::get_base_plan); ClassDB::bind_method(D_METHOD("get_base_plan"), &BlackboardPlan::get_base_plan);
ClassDB::bind_method(D_METHOD("is_derived"), &BlackboardPlan::is_derived); ClassDB::bind_method(D_METHOD("is_derived"), &BlackboardPlan::is_derived);
ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan); ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan);
ClassDB::bind_method(D_METHOD("set_parent_scope_plan_provider", "callable"), &BlackboardPlan::set_parent_scope_plan_provider); ClassDB::bind_method(D_METHOD("create_blackboard", "node"), &BlackboardPlan::create_blackboard);
ClassDB::bind_method(D_METHOD("get_parent_scope_plan_provider"), &BlackboardPlan::get_parent_scope_plan_provider);
ClassDB::bind_method(D_METHOD("create_blackboard", "node", "parent_scope"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()));
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard); ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard);
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class. // To avoid cluttering the member namespace, we do not export unnecessary properties in this class.

View File

@ -36,13 +36,6 @@ private:
// and only the values can be different in those variables. // and only the values can be different in those variables.
Ref<BlackboardPlan> base; Ref<BlackboardPlan> base;
// Mapping between variables in this plan and their parent scope names.
// Used for linking variables to their parent scope counterparts upon Blackboard creation/population.
HashMap<StringName, StringName> parent_scope_mapping;
// Fetcher function for the parent scope plan. Funtion should return a Ref<BlackboardPlan>.
// Used in the inspector. When set, mapping feature becomes available.
Callable parent_scope_plan_provider;
// If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population). // If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population).
bool prefetch_nodepath_vars = true; bool prefetch_nodepath_vars = true;
@ -59,12 +52,6 @@ public:
void set_base_plan(const Ref<BlackboardPlan> &p_base); void set_base_plan(const Ref<BlackboardPlan> &p_base);
Ref<BlackboardPlan> get_base_plan() const { return base; } Ref<BlackboardPlan> get_base_plan() const { return base; }
void set_parent_scope_plan_provider(const Callable &p_parent_scope_plan_provider);
Callable get_parent_scope_plan_provider() const { return parent_scope_plan_provider; }
bool is_mapping_enabled() const { return parent_scope_plan_provider.is_valid() && (parent_scope_plan_provider.call() != Ref<BlackboardPlan>()); }
bool has_mapping(const StringName &p_name) const;
void set_prefetch_nodepath_vars(bool p_enable); void set_prefetch_nodepath_vars(bool p_enable);
bool is_prefetching_nodepath_vars() const; bool is_prefetching_nodepath_vars() const;
@ -76,7 +63,7 @@ public:
_FORCE_INLINE_ bool is_empty() const { return var_map.is_empty(); } _FORCE_INLINE_ bool is_empty() const { return var_map.is_empty(); }
int get_var_count() const { return var_map.size(); } int get_var_count() const { return var_map.size(); }
TypedArray<StringName> list_vars() const; PackedStringArray list_vars() const;
StringName get_var_name(const BBVariable &p_var) const; StringName get_var_name(const BBVariable &p_var) const;
bool is_valid_var_name(const StringName &p_name) const; bool is_valid_var_name(const StringName &p_name) const;
void rename_var(const StringName &p_name, const StringName &p_new_name); void rename_var(const StringName &p_name, const StringName &p_new_name);
@ -85,7 +72,7 @@ public:
void sync_with_base_plan(); void sync_with_base_plan();
_FORCE_INLINE_ bool is_derived() const { return base.is_valid(); } _FORCE_INLINE_ bool is_derived() const { return base.is_valid(); }
Ref<Blackboard> create_blackboard(Node *p_agent, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>()); Ref<Blackboard> create_blackboard(Node *p_agent);
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node); void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node);
BlackboardPlan(); BlackboardPlan();

View File

@ -52,13 +52,7 @@ void BehaviorTree::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
} }
void BehaviorTree::set_root_task(const Ref<BTTask> &p_value) { void BehaviorTree::set_root_task(const Ref<BTTask> &p_value) {
#ifdef TOOLS_ENABLED
_unset_editor_behavior_tree_hint();
#endif // TOOLS_ENABLED
root_task = p_value; root_task = p_value;
#ifdef TOOLS_ENABLED
_set_editor_behavior_tree_hint();
#endif // TOOLS_ENABLED
emit_changed(); emit_changed();
} }
@ -77,12 +71,10 @@ void BehaviorTree::copy_other(const Ref<BehaviorTree> &p_other) {
root_task = p_other->get_root_task(); root_task = p_other->get_root_task();
} }
Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const { Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const {
ERR_FAIL_COND_V_MSG(root_task == nullptr, memnew(BTTask), "Trying to instance a behavior tree with no valid root task."); ERR_FAIL_COND_V_MSG(root_task == nullptr, memnew(BTTask), "Trying to instance a behavior tree with no valid root task.");
ERR_FAIL_NULL_V_MSG(p_agent, memnew(BTTask), "Trying to instance a behavior tree with no valid agent.");
ERR_FAIL_NULL_V_MSG(p_scene_root, memnew(BTTask), "Trying to instance a behavior tree with no valid scene root.");
Ref<BTTask> inst = root_task->clone(); Ref<BTTask> inst = root_task->clone();
inst->initialize(p_agent, p_blackboard, p_scene_root); inst->initialize(p_agent, p_blackboard);
return inst; return inst;
} }
@ -91,22 +83,6 @@ void BehaviorTree::_plan_changed() {
emit_changed(); emit_changed();
} }
#ifdef TOOLS_ENABLED
void BehaviorTree::_set_editor_behavior_tree_hint() {
if (root_task.is_valid()) {
root_task->data.behavior_tree_id = this->get_instance_id();
}
}
void BehaviorTree::_unset_editor_behavior_tree_hint() {
if (root_task.is_valid()) {
root_task->data.behavior_tree_id = ObjectID();
}
}
#endif // TOOLS_ENABLED
void BehaviorTree::_bind_methods() { void BehaviorTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_description", "description"), &BehaviorTree::set_description); ClassDB::bind_method(D_METHOD("set_description", "description"), &BehaviorTree::set_description);
ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description); ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description);
@ -116,7 +92,7 @@ void BehaviorTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_root_task"), &BehaviorTree::get_root_task); ClassDB::bind_method(D_METHOD("get_root_task"), &BehaviorTree::get_root_task);
ClassDB::bind_method(D_METHOD("clone"), &BehaviorTree::clone); ClassDB::bind_method(D_METHOD("clone"), &BehaviorTree::clone);
ClassDB::bind_method(D_METHOD("copy_other", "other"), &BehaviorTree::copy_other); ClassDB::bind_method(D_METHOD("copy_other", "other"), &BehaviorTree::copy_other);
ClassDB::bind_method(D_METHOD("instantiate", "agent", "blackboard", "scene_root"), &BehaviorTree::instantiate); ClassDB::bind_method(D_METHOD("instantiate", "agent", "blackboard"), &BehaviorTree::instantiate);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_plan", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardPlan", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_blackboard_plan", "get_blackboard_plan"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_plan", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardPlan", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_blackboard_plan", "get_blackboard_plan");

View File

@ -34,11 +34,6 @@ private:
void _plan_changed(); void _plan_changed();
#ifdef TOOLS_ENABLED
void _set_editor_behavior_tree_hint();
void _unset_editor_behavior_tree_hint();
#endif // TOOLS_ENABLED
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -58,7 +53,7 @@ public:
Ref<BehaviorTree> clone() const; Ref<BehaviorTree> clone() const;
void copy_other(const Ref<BehaviorTree> &p_other); void copy_other(const Ref<BehaviorTree> &p_other);
Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const; Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const;
BehaviorTree(); BehaviorTree();
~BehaviorTree(); ~BehaviorTree();

View File

@ -50,13 +50,9 @@ void BTPlayer::_load_tree() {
} }
#endif #endif
tree_instance.unref(); tree_instance.unref();
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree."); ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Needs a valid behavior tree.");
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task."); ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Behavior tree has no valid root task.");
Node *agent = GET_NODE(this, agent_node); tree_instance = behavior_tree->instantiate(get_owner(), blackboard);
ERR_FAIL_NULL_MSG(agent, vformat("BTPlayer: Initialization failed - can't get agent with path '%s'.", agent_node));
Node *scene_root = get_owner();
ERR_FAIL_NULL_MSG(scene_root, "BTPlayer: Initialization failed - can't get scene root (make sure the BTPlayer's owner property is set).");
tree_instance = behavior_tree->instantiate(agent, blackboard, scene_root);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (IS_DEBUGGER_ACTIVE()) { if (IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
@ -93,13 +89,6 @@ void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
} }
} }
void BTPlayer::set_agent_node(const NodePath &p_agent_node) {
agent_node = p_agent_node;
if (tree_instance.is_valid()) {
ERR_PRINT("BTPlayer: Agent node cannot be set after the behavior tree is instantiated. This change will not affect the behavior tree instance.");
}
}
void BTPlayer::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) { void BTPlayer::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
blackboard_plan = p_plan; blackboard_plan = p_plan;
_update_blackboard_plan(); _update_blackboard_plan();
@ -153,31 +142,21 @@ void BTPlayer::restart() {
void BTPlayer::_set_monitor_performance(bool p_monitor_performance) { void BTPlayer::_set_monitor_performance(bool p_monitor_performance) {
monitor_performance = p_monitor_performance; monitor_performance = p_monitor_performance;
if (!get_owner() && monitor_performance) { if (!get_owner()) {
// Don't add custom monitor if not in scene.
return; return;
} }
Performance *perf = Performance::get_singleton();
if (monitor_performance) { if (monitor_performance) {
_add_custom_monitor();
} else {
_remove_custom_monitor();
}
}
void BTPlayer::_add_custom_monitor() {
if (monitor_id == StringName()) { if (monitor_id == StringName()) {
monitor_id = vformat("LimboAI/update_ms|%s_%s_%s", get_owner()->get_name(), get_name(), monitor_id = vformat("limboai/update_ms|%s_%s_%s", get_owner()->get_name(), get_name(),
String(itos(get_instance_id())).md5_text().substr(0, 4)); String(itos(get_instance_id())).md5_text().substr(0, 4));
} }
if (!Performance::get_singleton()->has_custom_monitor(monitor_id)) { if (!perf->has_custom_monitor(monitor_id)) {
PERFORMANCE_ADD_CUSTOM_MONITOR(monitor_id, callable_mp(this, &BTPlayer::_get_mean_update_time_msec)); PERFORMANCE_ADD_CUSTOM_MONITOR(monitor_id, callable_mp(this, &BTPlayer::_get_mean_update_time_msec));
} }
} } else if (monitor_id != StringName() && perf->has_custom_monitor(monitor_id)) {
perf->remove_custom_monitor(monitor_id);
void BTPlayer::_remove_custom_monitor() {
if (monitor_id != StringName() && Performance::get_singleton()->has_custom_monitor(monitor_id)) {
Performance::get_singleton()->remove_custom_monitor(monitor_id);
} }
} }
@ -215,6 +194,9 @@ void BTPlayer::_notification(int p_notification) {
_load_tree(); _load_tree();
} }
set_active(active); set_active(active);
#ifdef DEBUG_ENABLED
_set_monitor_performance(monitor_performance);
#endif
} else { } else {
_update_blackboard_plan(); _update_blackboard_plan();
} }
@ -224,9 +206,6 @@ void BTPlayer::_notification(int p_notification) {
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
} }
if (monitor_performance) {
_add_custom_monitor();
}
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
@ -234,9 +213,6 @@ void BTPlayer::_notification(int p_notification) {
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
} }
if (monitor_performance) {
_remove_custom_monitor();
}
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
if (Engine::get_singleton()->is_editor_hint()) { if (Engine::get_singleton()->is_editor_hint()) {
@ -244,6 +220,7 @@ void BTPlayer::_notification(int p_notification) {
behavior_tree->disconnect(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan)); behavior_tree->disconnect(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan));
} }
} }
} break; } break;
} }
} }
@ -251,8 +228,6 @@ void BTPlayer::_notification(int p_notification) {
void BTPlayer::_bind_methods() { void BTPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_behavior_tree", "behavior_tree"), &BTPlayer::set_behavior_tree); ClassDB::bind_method(D_METHOD("set_behavior_tree", "behavior_tree"), &BTPlayer::set_behavior_tree);
ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTPlayer::get_behavior_tree); ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTPlayer::get_behavior_tree);
ClassDB::bind_method(D_METHOD("set_agent_node", "agent_node"), &BTPlayer::set_agent_node);
ClassDB::bind_method(D_METHOD("get_agent_node"), &BTPlayer::get_agent_node);
ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &BTPlayer::set_update_mode); ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &BTPlayer::set_update_mode);
ClassDB::bind_method(D_METHOD("get_update_mode"), &BTPlayer::get_update_mode); ClassDB::bind_method(D_METHOD("get_update_mode"), &BTPlayer::get_update_mode);
ClassDB::bind_method(D_METHOD("set_active", "active"), &BTPlayer::set_active); ClassDB::bind_method(D_METHOD("set_active", "active"), &BTPlayer::set_active);
@ -270,7 +245,6 @@ void BTPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tree_instance"), &BTPlayer::get_tree_instance); ClassDB::bind_method(D_METHOD("get_tree_instance"), &BTPlayer::get_tree_instance);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent_node"), "set_agent_node", "get_agent_node");
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,Manual"), "set_update_mode", "get_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,Manual"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "get_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "get_active");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_NONE, "Blackboard", 0), "set_blackboard", "get_blackboard"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_NONE, "Blackboard", 0), "set_blackboard", "get_blackboard");
@ -292,7 +266,6 @@ void BTPlayer::_bind_methods() {
BTPlayer::BTPlayer() { BTPlayer::BTPlayer() {
blackboard = Ref<Blackboard>(memnew(Blackboard)); blackboard = Ref<Blackboard>(memnew(Blackboard));
agent_node = LW_NAME(node_pp);
} }
BTPlayer::~BTPlayer() { BTPlayer::~BTPlayer() {

View File

@ -37,7 +37,6 @@ public:
private: private:
Ref<BehaviorTree> behavior_tree; Ref<BehaviorTree> behavior_tree;
NodePath agent_node;
Ref<BlackboardPlan> blackboard_plan; Ref<BlackboardPlan> blackboard_plan;
UpdateMode update_mode = UpdateMode::PHYSICS; UpdateMode update_mode = UpdateMode::PHYSICS;
bool active = true; bool active = true;
@ -58,9 +57,6 @@ public:
void set_behavior_tree(const Ref<BehaviorTree> &p_tree); void set_behavior_tree(const Ref<BehaviorTree> &p_tree);
Ref<BehaviorTree> get_behavior_tree() const { return behavior_tree; }; Ref<BehaviorTree> get_behavior_tree() const { return behavior_tree; };
void set_agent_node(const NodePath &p_agent_node);
NodePath get_agent_node() const { return agent_node; }
void set_blackboard_plan(const Ref<BlackboardPlan> &p_plan); void set_blackboard_plan(const Ref<BlackboardPlan> &p_plan);
Ref<BlackboardPlan> get_blackboard_plan() const { return blackboard_plan; } Ref<BlackboardPlan> get_blackboard_plan() const { return blackboard_plan; }
@ -92,10 +88,6 @@ private:
void _set_monitor_performance(bool p_monitor_performance); void _set_monitor_performance(bool p_monitor_performance);
bool _get_monitor_performance() const { return monitor_performance; } bool _get_monitor_performance() const { return monitor_performance; }
void _add_custom_monitor();
void _remove_custom_monitor();
double _get_mean_update_time_msec(); double _get_mean_update_time_msec();
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED

View File

@ -32,10 +32,10 @@ void BTState::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
p_tree->connect(LW_NAME(plan_changed), callable_mp(this, &BTState::_update_blackboard_plan)); p_tree->connect(LW_NAME(plan_changed), callable_mp(this, &BTState::_update_blackboard_plan));
} }
behavior_tree = p_tree; behavior_tree = p_tree;
_update_blackboard_plan();
} else { } else {
behavior_tree = p_tree; behavior_tree = p_tree;
} }
_update_blackboard_plan();
} }
void BTState::_update_blackboard_plan() { void BTState::_update_blackboard_plan() {
@ -52,9 +52,8 @@ void BTState::_update_blackboard_plan() {
void BTState::_setup() { void BTState::_setup() {
LimboState::_setup(); LimboState::_setup();
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned."); ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
Node *scene_root = get_owner(); // TODO: BBNode relies on agent to be scene owner, so if the user provides anything else, the behavior tree can break.
ERR_FAIL_NULL_MSG(scene_root, "BTState: Initialization failed - can't get scene root (make sure the BTState's owner property is set)."); tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard());
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), scene_root);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
@ -74,7 +73,7 @@ void BTState::_exit() {
void BTState::_update(double p_delta) { void BTState::_update(double p_delta) {
VCALL_ARGS(_update, p_delta); VCALL_ARGS(_update, p_delta);
if (!is_active()) { if (!active) {
// Bail out if a transition happened in the meantime. // Bail out if a transition happened in the meantime.
return; return;
} }

View File

@ -57,7 +57,7 @@ BT::Status BTCheckVar::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(!get_blackboard()->has_var(variable), FAILURE, vformat("BTCheckVar: Blackboard variable doesn't exist: \"%s\". Returning FAILURE.", variable)); ERR_FAIL_COND_V_MSG(!get_blackboard()->has_var(variable), FAILURE, vformat("BTCheckVar: Blackboard variable doesn't exist: \"%s\". Returning FAILURE.", variable));
Variant left_value = get_blackboard()->get_var(variable, Variant()); Variant left_value = get_blackboard()->get_var(variable, Variant());
Variant right_value = value->get_value(get_scene_root(), get_blackboard()); Variant right_value = value->get_value(get_agent(), get_blackboard());
return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE; return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE;
} }

View File

@ -26,7 +26,7 @@ BT::Status BTSetVar::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTSetVar: `value` is not set."); ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTSetVar: `value` is not set.");
Variant result; Variant result;
Variant error_result = LW_NAME(error_value); Variant error_result = LW_NAME(error_value);
Variant right_value = value->get_value(get_scene_root(), get_blackboard(), error_result); Variant right_value = value->get_value(get_agent(), get_blackboard(), error_result);
ERR_FAIL_COND_V_MSG(right_value == error_result, FAILURE, "BTSetVar: Failed to get parameter value. Returning FAILURE."); ERR_FAIL_COND_V_MSG(right_value == error_result, FAILURE, "BTSetVar: Failed to get parameter value. Returning FAILURE.");
if (operation == LimboUtility::OPERATION_NONE) { if (operation == LimboUtility::OPERATION_NONE) {
result = right_value; result = right_value;

View File

@ -17,9 +17,6 @@
class BTAction : public BTTask { class BTAction : public BTTask {
GDCLASS(BTAction, BTTask); GDCLASS(BTAction, BTTask);
protected:
static void _bind_methods() {}
public: public:
virtual PackedStringArray get_configuration_warnings() override; virtual PackedStringArray get_configuration_warnings() override;
}; };

View File

@ -18,9 +18,6 @@ class BTComment : public BTTask {
GDCLASS(BTComment, BTTask); GDCLASS(BTComment, BTTask);
TASK_CATEGORY(Utility); TASK_CATEGORY(Utility);
protected:
static void _bind_methods() {}
public: public:
virtual Ref<BTTask> clone() const override; virtual Ref<BTTask> clone() const override;
virtual PackedStringArray get_configuration_warnings() override; virtual PackedStringArray get_configuration_warnings() override;

View File

@ -17,9 +17,6 @@
class BTComposite : public BTTask { class BTComposite : public BTTask {
GDCLASS(BTComposite, BTTask); GDCLASS(BTComposite, BTTask);
protected:
static void _bind_methods() {}
public: public:
virtual PackedStringArray get_configuration_warnings() override; virtual PackedStringArray get_configuration_warnings() override;
}; };

View File

@ -17,9 +17,6 @@
class BTCondition : public BTTask { class BTCondition : public BTTask {
GDCLASS(BTCondition, BTTask); GDCLASS(BTCondition, BTTask);
protected:
static void _bind_methods() {}
public: public:
virtual PackedStringArray get_configuration_warnings() override; virtual PackedStringArray get_configuration_warnings() override;
}; };

View File

@ -18,8 +18,6 @@ class BTDecorator : public BTTask {
GDCLASS(BTDecorator, BTTask) GDCLASS(BTDecorator, BTTask)
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
public: public:

View File

@ -14,7 +14,6 @@
#include "../../blackboard/blackboard.h" #include "../../blackboard/blackboard.h"
#include "../../util/limbo_string_names.h" #include "../../util/limbo_string_names.h"
#include "../../util/limbo_utility.h" #include "../../util/limbo_utility.h"
#include "../behavior_tree.h"
#include "bt_comment.h" #include "bt_comment.h"
#ifdef LIMBOAI_MODULE #ifdef LIMBOAI_MODULE
@ -118,31 +117,31 @@ bool BTTask::is_displayed_collapsed() const {
} }
String BTTask::get_task_name() { String BTTask::get_task_name() {
if (!data.custom_name.is_empty()) { if (data.custom_name.is_empty()) {
return data.custom_name; #ifdef LIMBOAI_MODULE
} if (get_script_instance() && get_script_instance()->has_method(LW_NAME(_generate_name))) {
if (unlikely(!get_script_instance()->get_script()->is_tool())) {
Ref<Script> task_script = get_script(); ERR_PRINT(vformat("BTTask: Task script should be a \"tool\" script!"));
} else {
if (task_script.is_valid()) { return get_script_instance()->call(LimboStringNames::get_singleton()->_generate_name);
bool has_generate_method = has_method(LW_NAME(_generate_name));
ERR_FAIL_COND_V_MSG(has_generate_method && !task_script->is_tool(), _generate_name(), vformat("BTTask: @tool annotation is required if _generate_name is defined: %s", task_script->get_path()));
if (task_script->is_tool() && has_generate_method) {
String call_result;
VCALL_V(_generate_name, call_result);
if (call_result.is_empty() || call_result == "<null>") {
// Force reset script instance.
set_script(Variant());
set_script(task_script);
// Retry.
VCALL_V(_generate_name, call_result);
}
ERR_FAIL_COND_V_MSG(call_result.is_empty() || call_result == "<null>", _generate_name(), vformat("BTTask: _generate_name() failed to return a proper name string (%s)", task_script->get_path()));
return call_result;
} }
} }
return _generate_name(); return _generate_name();
#elif LIMBOAI_GDEXTENSION
Ref<Script> task_script = get_script();
if (task_script.is_valid() && task_script->is_tool()) {
Variant call_result;
VCALL_OR_NATIVE_V(_generate_name, Variant, call_result);
ERR_FAIL_COND_V(call_result.get_type() == Variant::NIL, _generate_name());
String task_name = call_result;
ERR_FAIL_COND_V(task_name.is_empty(), _generate_name());
return task_name;
} else {
return _generate_name();
}
#endif
}
return data.custom_name;
} }
Ref<BTTask> BTTask::get_root() const { Ref<BTTask> BTTask::get_root() const {
@ -160,15 +159,13 @@ void BTTask::set_custom_name(const String &p_name) {
} }
}; };
void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) { void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_NULL(p_agent); ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_NULL(p_blackboard); ERR_FAIL_COND(p_blackboard == nullptr);
ERR_FAIL_NULL(p_scene_root);
data.agent = p_agent; data.agent = p_agent;
data.blackboard = p_blackboard; data.blackboard = p_blackboard;
data.scene_root = p_scene_root;
for (int i = 0; i < data.children.size(); i++) { for (int i = 0; i < data.children.size(); i++) {
get_child(i)->initialize(p_agent, p_blackboard, p_scene_root); get_child(i)->initialize(p_agent, p_blackboard);
} }
VCALL_OR_NATIVE(_setup); VCALL_OR_NATIVE(_setup);
@ -377,27 +374,11 @@ void BTTask::print_tree(int p_initial_tabs) {
} }
} }
#ifdef TOOLS_ENABLED
Ref<BehaviorTree> BTTask::editor_get_behavior_tree() {
BTTask *task = this;
while (task->data.behavior_tree_id.is_null() && task->get_parent().is_valid()) {
task = task->data.parent;
}
return Object::cast_to<BehaviorTree>(ObjectDB::get_instance(task->data.behavior_tree_id));
}
void BTTask::editor_set_behavior_tree(const Ref<BehaviorTree> &p_bt) {
data.behavior_tree_id = p_bt->get_instance_id();
}
#endif // TOOLS_ENABLED
void BTTask::_bind_methods() { void BTTask::_bind_methods() {
// Public Methods. // Public Methods.
ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root); ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root);
ClassDB::bind_method(D_METHOD("get_root"), &BTTask::get_root); ClassDB::bind_method(D_METHOD("get_root"), &BTTask::get_root);
ClassDB::bind_method(D_METHOD("initialize", "agent", "blackboard", "scene_root"), &BTTask::initialize); ClassDB::bind_method(D_METHOD("initialize", "agent", "blackboard"), &BTTask::initialize);
ClassDB::bind_method(D_METHOD("clone"), &BTTask::clone); ClassDB::bind_method(D_METHOD("clone"), &BTTask::clone);
ClassDB::bind_method(D_METHOD("execute", "delta"), &BTTask::execute); ClassDB::bind_method(D_METHOD("execute", "delta"), &BTTask::execute);
ClassDB::bind_method(D_METHOD("get_child", "idx"), &BTTask::get_child); ClassDB::bind_method(D_METHOD("get_child", "idx"), &BTTask::get_child);
@ -414,14 +395,10 @@ void BTTask::_bind_methods() {
ClassDB::bind_method(D_METHOD("print_tree", "initial_tabs"), &BTTask::print_tree, Variant(0)); ClassDB::bind_method(D_METHOD("print_tree", "initial_tabs"), &BTTask::print_tree, Variant(0));
ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name); ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name);
ClassDB::bind_method(D_METHOD("abort"), &BTTask::abort); ClassDB::bind_method(D_METHOD("abort"), &BTTask::abort);
#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("editor_get_behavior_tree"), &BTTask::editor_get_behavior_tree);
#endif // TOOLS_ENABLED
// Properties, setters and getters. // Properties, setters and getters.
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent); ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
ClassDB::bind_method(D_METHOD("set_agent", "agent"), &BTTask::set_agent); ClassDB::bind_method(D_METHOD("set_agent", "agent"), &BTTask::set_agent);
ClassDB::bind_method(D_METHOD("get_scene_root"), &BTTask::get_scene_root);
ClassDB::bind_method(D_METHOD("_get_children"), &BTTask::_get_children); ClassDB::bind_method(D_METHOD("_get_children"), &BTTask::_get_children);
ClassDB::bind_method(D_METHOD("_set_children", "children"), &BTTask::_set_children); ClassDB::bind_method(D_METHOD("_set_children", "children"), &BTTask::_set_children);
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTTask::get_blackboard); ClassDB::bind_method(D_METHOD("get_blackboard"), &BTTask::get_blackboard);
@ -433,7 +410,6 @@ void BTTask::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_name"), "set_custom_name", "get_custom_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_name"), "set_custom_name", "get_custom_name");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_agent", "get_agent"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_agent", "get_agent");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene_root", PROPERTY_HINT_NODE_TYPE, "Node", PROPERTY_USAGE_NONE), "", "get_scene_root");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", PROPERTY_USAGE_NONE), "", "get_blackboard"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", PROPERTY_USAGE_NONE), "", "get_blackboard");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_children", "_get_children"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_children", "_get_children");
ADD_PROPERTY(PropertyInfo(Variant::INT, "status", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_status"); ADD_PROPERTY(PropertyInfo(Variant::INT, "status", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_status");

View File

@ -42,8 +42,6 @@
using namespace godot; using namespace godot;
#endif // LIMBOAI_GDEXTENSION #endif // LIMBOAI_GDEXTENSION
class BehaviorTree;
/** /**
* Base class for BTTask. * Base class for BTTask.
* Note: In order to properly return Status in the _tick virtual method (GDVIRTUAL1R...) * Note: In order to properly return Status in the _tick virtual method (GDVIRTUAL1R...)
@ -77,16 +75,12 @@ private:
int index = -1; int index = -1;
String custom_name; String custom_name;
Node *agent = nullptr; Node *agent = nullptr;
Node *scene_root = nullptr;
Ref<Blackboard> blackboard; Ref<Blackboard> blackboard;
BTTask *parent = nullptr; BTTask *parent = nullptr;
Vector<Ref<BTTask>> children; Vector<Ref<BTTask>> children;
Status status = FRESH; Status status = FRESH;
double elapsed = 0.0; double elapsed = 0.0;
bool display_collapsed = false; bool display_collapsed = false;
#ifdef TOOLS_ENABLED
ObjectID behavior_tree_id;
#endif
} data; } data;
Array _get_children() const; Array _get_children() const;
@ -122,8 +116,6 @@ public:
_FORCE_INLINE_ Node *get_agent() const { return data.agent; } _FORCE_INLINE_ Node *get_agent() const { return data.agent; }
void set_agent(Node *p_agent) { data.agent = p_agent; } void set_agent(Node *p_agent) { data.agent = p_agent; }
_FORCE_INLINE_ Node *get_scene_root() const { return data.scene_root; }
void set_display_collapsed(bool p_display_collapsed); void set_display_collapsed(bool p_display_collapsed);
bool is_displayed_collapsed() const; bool is_displayed_collapsed() const;
@ -134,7 +126,7 @@ public:
Ref<BTTask> get_root() const; Ref<BTTask> get_root() const;
virtual Ref<BTTask> clone() const; virtual Ref<BTTask> clone() const;
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root); virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard);
virtual PackedStringArray get_configuration_warnings(); // ! Native version. virtual PackedStringArray get_configuration_warnings(); // ! Native version.
Status execute(double p_delta); Status execute(double p_delta);
@ -167,11 +159,6 @@ public:
void print_tree(int p_initial_tabs = 0); void print_tree(int p_initial_tabs = 0);
#ifdef TOOLS_ENABLED
Ref<BehaviorTree> editor_get_behavior_tree();
void editor_set_behavior_tree(const Ref<BehaviorTree> &p_bt);
#endif
BTTask(); BTTask();
~BTTask(); ~BTTask();
}; };

View File

@ -22,8 +22,6 @@ private:
int last_running_idx = 0; int last_running_idx = 0;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -22,8 +22,6 @@ private:
int last_running_idx = 0; int last_running_idx = 0;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -23,8 +23,6 @@ private:
Array indicies; Array indicies;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -23,8 +23,6 @@ private:
Array indicies; Array indicies;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -22,8 +22,6 @@ private:
int last_running_idx = 0; int last_running_idx = 0;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -22,8 +22,6 @@ private:
int last_running_idx = 0; int last_running_idx = 0;
protected: protected:
static void _bind_methods() {}
virtual void _enter() override; virtual void _enter() override;
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -19,8 +19,6 @@ class BTAlwaysFail : public BTDecorator {
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -19,8 +19,6 @@ class BTAlwaysSucceed : public BTDecorator {
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -54,7 +54,7 @@ String BTCooldown::_generate_name() {
void BTCooldown::_setup() { void BTCooldown::_setup() {
if (cooldown_state_var == StringName()) { if (cooldown_state_var == StringName()) {
cooldown_state_var = vformat("cooldown_%d", get_instance_id()); cooldown_state_var = vformat("cooldown_%d", rand());
} }
get_blackboard()->set_var(cooldown_state_var, false); get_blackboard()->set_var(cooldown_state_var, false);
if (start_cooled) { if (start_cooled) {

View File

@ -19,8 +19,6 @@ class BTInvert : public BTDecorator {
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -11,46 +11,29 @@
#include "bt_new_scope.h" #include "bt_new_scope.h"
#include "../../behavior_tree.h"
void BTNewScope::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) { void BTNewScope::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
blackboard_plan = p_plan; blackboard_plan = p_plan;
if (blackboard_plan.is_null()) { if (blackboard_plan.is_null()) {
blackboard_plan.instantiate(); blackboard_plan.instantiate();
} }
_update_blackboard_plan(); _update_blackboard_plan();
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
callable_mp(this, &BTNewScope::_set_parent_scope_plan_from_bt).call_deferred();
}
#endif // TOOLS_ENABLED
emit_changed(); emit_changed();
} }
#ifdef TOOLS_ENABLED void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
void BTNewScope::_set_parent_scope_plan_from_bt() {
ERR_FAIL_NULL(get_blackboard_plan());
Ref<BehaviorTree> bt = get_root()->editor_get_behavior_tree();
ERR_FAIL_NULL(bt);
get_blackboard_plan()->set_parent_scope_plan_provider(callable_mp(bt.ptr(), &BehaviorTree::get_blackboard_plan));
}
#endif // TOOLS_ENABLED
void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
ERR_FAIL_COND(p_agent == nullptr); ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND(p_blackboard == nullptr); ERR_FAIL_COND(p_blackboard == nullptr);
Ref<Blackboard> bb; Ref<Blackboard> bb;
if (blackboard_plan.is_valid()) { if (blackboard_plan.is_valid()) {
bb = blackboard_plan->create_blackboard(p_agent, p_blackboard); bb = blackboard_plan->create_blackboard(p_agent);
} else { } else {
bb = Ref<Blackboard>(memnew(Blackboard)); bb = Ref<Blackboard>(memnew(Blackboard));
bb->set_parent(p_blackboard);
} }
BTDecorator::initialize(p_agent, bb, p_scene_root);
bb->set_parent(p_blackboard);
BTDecorator::initialize(p_agent, bb);
} }
BT::Status BTNewScope::_tick(double p_delta) { BT::Status BTNewScope::_tick(double p_delta) {

View File

@ -23,10 +23,6 @@ class BTNewScope : public BTDecorator {
private: private:
Ref<BlackboardPlan> blackboard_plan; Ref<BlackboardPlan> blackboard_plan;
#ifdef TOOLS_ENABLED
void _set_parent_scope_plan_from_bt();
#endif // TOOLS_ENABLED
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -38,7 +34,7 @@ protected:
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
public: public:
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) override; virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
}; };
#endif // BT_NEW_SCOPE_H #endif // BT_NEW_SCOPE_H

View File

@ -19,8 +19,6 @@ class BTRepeatUntilFailure : public BTDecorator {
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -19,8 +19,6 @@ class BTRepeatUntilSuccess : public BTDecorator {
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -44,14 +44,14 @@ String BTSubtree::_generate_name() {
return vformat("Subtree %s", s); return vformat("Subtree %s", s);
} }
void BTSubtree::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) { void BTSubtree::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND_MSG(!subtree.is_valid(), "Subtree is not assigned."); ERR_FAIL_COND_MSG(!subtree.is_valid(), "Subtree is not assigned.");
ERR_FAIL_COND_MSG(!subtree->get_root_task().is_valid(), "Subtree root task is not valid."); ERR_FAIL_COND_MSG(!subtree->get_root_task().is_valid(), "Subtree root task is not valid.");
ERR_FAIL_COND_MSG(get_child_count() != 0, "Subtree task shouldn't have children during initialization."); ERR_FAIL_COND_MSG(get_child_count() != 0, "Subtree task shouldn't have children during initialization.");
add_child(subtree->get_root_task()->clone()); add_child(subtree->get_root_task()->clone());
BTNewScope::initialize(p_agent, p_blackboard, p_scene_root); BTNewScope::initialize(p_agent, p_blackboard);
} }
BT::Status BTSubtree::_tick(double p_delta) { BT::Status BTSubtree::_tick(double p_delta) {

View File

@ -35,7 +35,7 @@ public:
void set_subtree(const Ref<BehaviorTree> &p_value); void set_subtree(const Ref<BehaviorTree> &p_value);
Ref<BehaviorTree> get_subtree() const { return subtree; } Ref<BehaviorTree> get_subtree() const { return subtree; }
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) override; virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
virtual PackedStringArray get_configuration_warnings() override; virtual PackedStringArray get_configuration_warnings() override;
BTSubtree() = default; BTSubtree() = default;

View File

@ -62,7 +62,7 @@ String BTAwaitAnimation::_generate_name() {
void BTAwaitAnimation::_setup() { void BTAwaitAnimation::_setup() {
setup_failed = true; setup_failed = true;
ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTAwaitAnimation: AnimationPlayer parameter is not set."); ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTAwaitAnimation: AnimationPlayer parameter is not set.");
animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_scene_root(), get_blackboard())); animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_agent(), get_blackboard()));
ERR_FAIL_COND_MSG(animation_player == nullptr, "BTAwaitAnimation: Failed to get AnimationPlayer."); ERR_FAIL_COND_MSG(animation_player == nullptr, "BTAwaitAnimation: Failed to get AnimationPlayer.");
ERR_FAIL_COND_MSG(animation_name == StringName(), "BTAwaitAnimation: Animation Name is not set."); ERR_FAIL_COND_MSG(animation_name == StringName(), "BTAwaitAnimation: Animation Name is not set.");
ERR_FAIL_COND_MSG(!animation_player->has_animation(animation_name), vformat("BTAwaitAnimation: Animation not found: %s", animation_name)); ERR_FAIL_COND_MSG(!animation_player->has_animation(animation_name), vformat("BTAwaitAnimation: Animation not found: %s", animation_name));

View File

@ -62,7 +62,7 @@ BT::Status BTCheckAgentProperty::_tick(double p_delta) {
Variant left_value = get_agent()->get(property); Variant left_value = get_agent()->get(property);
#endif #endif
Variant right_value = value->get_value(get_scene_root(), get_blackboard()); Variant right_value = value->get_value(get_agent(), get_blackboard());
return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE; return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE;
} }

View File

@ -44,7 +44,7 @@ String BTPauseAnimation::_generate_name() {
void BTPauseAnimation::_setup() { void BTPauseAnimation::_setup() {
setup_failed = true; setup_failed = true;
ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTPauseAnimation: AnimationPlayer parameter is not set."); ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTPauseAnimation: AnimationPlayer parameter is not set.");
animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_scene_root(), get_blackboard())); animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_agent(), get_blackboard()));
ERR_FAIL_COND_MSG(animation_player == nullptr, "BTPauseAnimation: Failed to get AnimationPlayer."); ERR_FAIL_COND_MSG(animation_player == nullptr, "BTPauseAnimation: Failed to get AnimationPlayer.");
setup_failed = false; setup_failed = false;
} }

View File

@ -77,7 +77,7 @@ String BTPlayAnimation::_generate_name() {
void BTPlayAnimation::_setup() { void BTPlayAnimation::_setup() {
setup_failed = true; setup_failed = true;
ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTPlayAnimation: AnimationPlayer parameter is not set."); ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTPlayAnimation: AnimationPlayer parameter is not set.");
animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_scene_root(), get_blackboard())); animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_agent(), get_blackboard()));
ERR_FAIL_COND_MSG(animation_player == nullptr, "BTPlayAnimation: Failed to get AnimationPlayer."); ERR_FAIL_COND_MSG(animation_player == nullptr, "BTPlayAnimation: Failed to get AnimationPlayer.");
ERR_FAIL_COND_MSG(animation_name != StringName() && !animation_player->has_animation(animation_name), vformat("BTPlayAnimation: Animation not found: %s", animation_name)); ERR_FAIL_COND_MSG(animation_name != StringName() && !animation_player->has_animation(animation_name), vformat("BTPlayAnimation: Animation not found: %s", animation_name));
if (animation_name == StringName() && await_completion > 0.0) { if (animation_name == StringName() && await_completion > 0.0) {

View File

@ -55,7 +55,7 @@ BT::Status BTSetAgentProperty::_tick(double p_delta) {
Variant result; Variant result;
StringName error_value = LW_NAME(error_value); StringName error_value = LW_NAME(error_value);
Variant right_value = value->get_value(get_scene_root(), get_blackboard(), error_value); Variant right_value = value->get_value(get_agent(), get_blackboard(), error_value);
ERR_FAIL_COND_V_MSG(right_value == Variant(error_value), FAILURE, "BTSetAgentProperty: Couldn't get value of value-parameter."); ERR_FAIL_COND_V_MSG(right_value == Variant(error_value), FAILURE, "BTSetAgentProperty: Couldn't get value of value-parameter.");
bool r_valid; bool r_valid;
if (operation == LimboUtility::OPERATION_NONE) { if (operation == LimboUtility::OPERATION_NONE) {

View File

@ -56,7 +56,7 @@ String BTStopAnimation::_generate_name() {
void BTStopAnimation::_setup() { void BTStopAnimation::_setup() {
setup_failed = true; setup_failed = true;
ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTStopAnimation: AnimationPlayer parameter is not set."); ERR_FAIL_COND_MSG(animation_player_param.is_null(), "BTStopAnimation: AnimationPlayer parameter is not set.");
animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_scene_root(), get_blackboard())); animation_player = Object::cast_to<AnimationPlayer>(animation_player_param->get_value(get_agent(), get_blackboard()));
ERR_FAIL_COND_MSG(animation_player == nullptr, "BTStopAnimation: Failed to get AnimationPlayer."); ERR_FAIL_COND_MSG(animation_player == nullptr, "BTStopAnimation: Failed to get AnimationPlayer.");
if (animation_name != StringName()) { if (animation_name != StringName()) {
ERR_FAIL_COND_MSG(!animation_player->has_animation(animation_name), vformat("BTStopAnimation: Animation not found: %s", animation_name)); ERR_FAIL_COND_MSG(!animation_player->has_animation(animation_name), vformat("BTStopAnimation: Animation not found: %s", animation_name));

View File

@ -83,7 +83,7 @@ String BTCallMethod::_generate_name() {
BT::Status BTCallMethod::_tick(double p_delta) { BT::Status BTCallMethod::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(method == StringName(), FAILURE, "BTCallMethod: Method Name is not set."); ERR_FAIL_COND_V_MSG(method == StringName(), FAILURE, "BTCallMethod: Method Name is not set.");
ERR_FAIL_COND_V_MSG(node_param.is_null(), FAILURE, "BTCallMethod: Node parameter is not set."); ERR_FAIL_COND_V_MSG(node_param.is_null(), FAILURE, "BTCallMethod: Node parameter is not set.");
Object *obj = node_param->get_value(get_scene_root(), get_blackboard()); Object *obj = node_param->get_value(get_agent(), get_blackboard());
ERR_FAIL_COND_V_MSG(obj == nullptr, FAILURE, "BTCallMethod: Failed to get object: " + node_param->to_string()); ERR_FAIL_COND_V_MSG(obj == nullptr, FAILURE, "BTCallMethod: Failed to get object: " + node_param->to_string());
Variant result; Variant result;
@ -101,7 +101,7 @@ BT::Status BTCallMethod::_tick(double p_delta) {
} }
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
Ref<BBVariant> param = args[i]; Ref<BBVariant> param = args[i];
call_args.push_back(param->get_value(get_scene_root(), get_blackboard())); call_args.push_back(param->get_value(get_agent(), get_blackboard()));
argptrs[i + int(include_delta)] = &call_args[i]; argptrs[i + int(include_delta)] = &call_args[i];
} }
} }
@ -117,7 +117,7 @@ BT::Status BTCallMethod::_tick(double p_delta) {
} }
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
Ref<BBVariant> param = args[i]; Ref<BBVariant> param = args[i];
call_args.push_back(param->get_value(get_scene_root(), get_blackboard())); call_args.push_back(param->get_value(get_agent(), get_blackboard()));
} }
// TODO: Unsure how to detect call error, so we return SUCCESS for now... // TODO: Unsure how to detect call error, so we return SUCCESS for now...

View File

@ -107,7 +107,7 @@ String BTEvaluateExpression::_generate_name() {
BT::Status BTEvaluateExpression::_tick(double p_delta) { BT::Status BTEvaluateExpression::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(expression_string.is_empty(), FAILURE, "BTEvaluateExpression: Expression String is not set."); ERR_FAIL_COND_V_MSG(expression_string.is_empty(), FAILURE, "BTEvaluateExpression: Expression String is not set.");
ERR_FAIL_COND_V_MSG(node_param.is_null(), FAILURE, "BTEvaluateExpression: Node parameter is not set."); ERR_FAIL_COND_V_MSG(node_param.is_null(), FAILURE, "BTEvaluateExpression: Node parameter is not set.");
Object *obj = node_param->get_value(get_scene_root(), get_blackboard()); Object *obj = node_param->get_value(get_agent(), get_blackboard());
ERR_FAIL_COND_V_MSG(obj == nullptr, FAILURE, "BTEvaluateExpression: Failed to get object: " + node_param->to_string()); ERR_FAIL_COND_V_MSG(obj == nullptr, FAILURE, "BTEvaluateExpression: Failed to get object: " + node_param->to_string());
ERR_FAIL_COND_V_MSG(is_parsed != Error::OK, FAILURE, "BTEvaluateExpression: Failed to parse expression: " + expression.get_error_text()); ERR_FAIL_COND_V_MSG(is_parsed != Error::OK, FAILURE, "BTEvaluateExpression: Failed to parse expression: " + expression.get_error_text());
@ -116,7 +116,7 @@ BT::Status BTEvaluateExpression::_tick(double p_delta) {
} }
for (int i = 0; i < input_values.size(); ++i) { for (int i = 0; i < input_values.size(); ++i) {
const Ref<BBVariant> &bb_variant = input_values[i]; const Ref<BBVariant> &bb_variant = input_values[i];
processed_input_values[i + int(input_include_delta)] = bb_variant->get_value(get_scene_root(), get_blackboard()); processed_input_values[i + int(input_include_delta)] = bb_variant->get_value(get_agent(), get_blackboard());
} }
Variant result = expression.execute(processed_input_values, obj, false); Variant result = expression.execute(processed_input_values, obj, false);

View File

@ -19,8 +19,6 @@ class BTFail : public BTAction {
TASK_CATEGORY(Utility); TASK_CATEGORY(Utility);
protected: protected:
static void _bind_methods() {}
virtual Status _tick(double p_delta) override; virtual Status _tick(double p_delta) override;
}; };

View File

@ -67,6 +67,7 @@ func _init_state_machine() -> void:
hsm.initialize(self) hsm.initialize(self)
hsm.set_active(true) hsm.set_active(true)
hsm.set_guard(_can_dodge)
func _init_input_events() -> void: func _init_input_events() -> void:

View File

@ -49,11 +49,11 @@ Methods
.. table:: .. table::
:widths: auto :widths: auto
+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Variant.Type<enum_@GlobalScope_Variant.Type>` | :ref:`get_type<class_BBParam_method_get_type>` **(** **)** |const| | | :ref:`Variant.Type<enum_@GlobalScope_Variant.Type>` | :ref:`get_type<class_BBParam_method_get_type>` **(** **)** |const| |
+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Variant | :ref:`get_value<class_BBParam_method_get_value>` **(** Node scene_root, :ref:`Blackboard<class_Blackboard>` blackboard, Variant default=null **)** | | Variant | :ref:`get_value<class_BBParam_method_get_value>` **(** Object agent, :ref:`Blackboard<class_Blackboard>` blackboard, Variant default=null **)** |
+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator .. rst-class:: classref-section-separator
@ -167,7 +167,7 @@ Returns the expected data type of the parameter.
.. rst-class:: classref-method .. rst-class:: classref-method
Variant **get_value** **(** Node scene_root, :ref:`Blackboard<class_Blackboard>` blackboard, Variant default=null **)** Variant **get_value** **(** Object agent, :ref:`Blackboard<class_Blackboard>` blackboard, Variant default=null **)**
Returns the value of the parameter. Returns the value of the parameter.

View File

@ -55,17 +55,17 @@ Methods
.. table:: .. table::
:widths: auto :widths: auto
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`clone<class_BehaviorTree_method_clone>` **(** **)** |const| | | :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`clone<class_BehaviorTree_method_clone>` **(** **)** |const| |
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`copy_other<class_BehaviorTree_method_copy_other>` **(** :ref:`BehaviorTree<class_BehaviorTree>` other **)** | | void | :ref:`copy_other<class_BehaviorTree_method_copy_other>` **(** :ref:`BehaviorTree<class_BehaviorTree>` other **)** |
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BehaviorTree_method_get_root_task>` **(** **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BehaviorTree_method_get_root_task>` **(** **)** |const| |
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`instantiate<class_BehaviorTree_method_instantiate>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`instantiate<class_BehaviorTree_method_instantiate>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard **)** |const| |
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_root_task<class_BehaviorTree_method_set_root_task>` **(** :ref:`BTTask<class_BTTask>` task **)** | | void | :ref:`set_root_task<class_BehaviorTree_method_set_root_task>` **(** :ref:`BTTask<class_BTTask>` task **)** |
+-----------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator .. rst-class:: classref-section-separator
@ -172,9 +172,9 @@ Returns the root task of the BehaviorTree resource.
.. rst-class:: classref-method .. rst-class:: classref-method
:ref:`BTTask<class_BTTask>` **instantiate** **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** |const| :ref:`BTTask<class_BTTask>` **instantiate** **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard **)** |const|
Instantiates the behavior tree and returns the root :ref:`BTTask<class_BTTask>`. ``scene_root`` should be the root node of the scene that the Behavior Tree will be used in (e.g., the owner of the node that contains the behavior tree). Instantiates the Behavior Tree and returns the root :ref:`BTTask<class_BTTask>`.
.. rst-class:: classref-item-separator .. rst-class:: classref-item-separator

View File

@ -33,35 +33,27 @@ Methods
.. table:: .. table::
:widths: auto :widths: auto
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`bind_var_to_property<class_Blackboard_method_bind_var_to_property>` **(** StringName var_name, Object object, StringName property, bool create=false **)** | | void | :ref:`bind_var_to_property<class_Blackboard_method_bind_var_to_property>` **(** StringName var_name, Object object, StringName property, bool create **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`clear<class_Blackboard_method_clear>` **(** **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`erase_var<class_Blackboard_method_erase_var>` **(** StringName var_name **)** | | void | :ref:`erase_var<class_Blackboard_method_erase_var>` **(** StringName var_name **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`get_parent<class_Blackboard_method_get_parent>` **(** **)** |const| | | :ref:`Blackboard<class_Blackboard>` | :ref:`get_parent<class_Blackboard_method_get_parent>` **(** **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variant | :ref:`get_var<class_Blackboard_method_get_var>` **(** StringName var_name, Variant default=null, bool complain=true **)** |const| | | Variant | :ref:`get_var<class_Blackboard_method_get_var>` **(** StringName var_name, Variant default=null, bool complain=true **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Dictionary | :ref:`get_vars_as_dict<class_Blackboard_method_get_vars_as_dict>` **(** **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`has_var<class_Blackboard_method_has_var>` **(** StringName var_name **)** |const| | | bool | :ref:`has_var<class_Blackboard_method_has_var>` **(** StringName var_name **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`link_var<class_Blackboard_method_link_var>` **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var, bool create=false **)** | | void | :ref:`link_var<class_Blackboard_method_link_var>` **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var, bool create **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| StringName[] | :ref:`list_vars<class_Blackboard_method_list_vars>` **(** **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`populate_from_dict<class_Blackboard_method_populate_from_dict>` **(** Dictionary dictionary **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_parent<class_Blackboard_method_set_parent>` **(** :ref:`Blackboard<class_Blackboard>` blackboard **)** | | void | :ref:`set_parent<class_Blackboard_method_set_parent>` **(** :ref:`Blackboard<class_Blackboard>` blackboard **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_var<class_Blackboard_method_set_var>` **(** StringName var_name, Variant value **)** | | void | :ref:`set_var<class_Blackboard_method_set_var>` **(** StringName var_name, Variant value **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`top<class_Blackboard_method_top>` **(** **)** |const| | | :ref:`Blackboard<class_Blackboard>` | :ref:`top<class_Blackboard_method_top>` **(** **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`unbind_var<class_Blackboard_method_unbind_var>` **(** StringName var_name **)** | | void | :ref:`unbind_var<class_Blackboard_method_unbind_var>` **(** StringName var_name **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator .. rst-class:: classref-section-separator
@ -76,7 +68,7 @@ Method Descriptions
.. rst-class:: classref-method .. rst-class:: classref-method
void **bind_var_to_property** **(** StringName var_name, Object object, StringName property, bool create=false **)** void **bind_var_to_property** **(** StringName var_name, Object object, StringName property, bool create **)**
Establish a binding between a variable and the object's property specified by ``property`` and ``object``. Changes to the variable update the property, and vice versa. If ``create`` is ``true``, the variable will be created if it doesn't exist. Establish a binding between a variable and the object's property specified by ``property`` and ``object``. Changes to the variable update the property, and vice versa. If ``create`` is ``true``, the variable will be created if it doesn't exist.
@ -84,18 +76,6 @@ Establish a binding between a variable and the object's property specified by ``
---- ----
.. _class_Blackboard_method_clear:
.. rst-class:: classref-method
void **clear** **(** **)**
Removes all variables from the Blackboard. Parent scopes are not affected.
.. rst-class:: classref-item-separator
----
.. _class_Blackboard_method_erase_var: .. _class_Blackboard_method_erase_var:
.. rst-class:: classref-method .. rst-class:: classref-method
@ -132,18 +112,6 @@ Returns variable value or ``default`` if variable doesn't exist. If ``complain``
---- ----
.. _class_Blackboard_method_get_vars_as_dict:
.. rst-class:: classref-method
Dictionary **get_vars_as_dict** **(** **)** |const|
Returns all variables in the Blackboard as a dictionary. Keys are the variable names, values are the variable values. Parent scopes are not included.
.. rst-class:: classref-item-separator
----
.. _class_Blackboard_method_has_var: .. _class_Blackboard_method_has_var:
.. rst-class:: classref-method .. rst-class:: classref-method
@ -160,7 +128,7 @@ Returns ``true`` if the Blackboard contains the ``var_name`` variable, including
.. rst-class:: classref-method .. rst-class:: classref-method
void **link_var** **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var, bool create=false **)** void **link_var** **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var, bool create **)**
Links a variable to another Blackboard variable. If a variable is linked to another variable, their state will always be identical, and any change to one will be reflected in the other. If ``create`` is ``true``, the variable will be created if it doesn't exist. Links a variable to another Blackboard variable. If a variable is linked to another variable, their state will always be identical, and any change to one will be reflected in the other. If ``create`` is ``true``, the variable will be created if it doesn't exist.
@ -170,30 +138,6 @@ You can use this method to link a variable in the current scope to a variable in
---- ----
.. _class_Blackboard_method_list_vars:
.. rst-class:: classref-method
StringName[] **list_vars** **(** **)** |const|
Returns all variable names in the Blackboard. Parent scopes are not included.
.. rst-class:: classref-item-separator
----
.. _class_Blackboard_method_populate_from_dict:
.. rst-class:: classref-method
void **populate_from_dict** **(** Dictionary dictionary **)**
Fills the Blackboard with multiple variables from a dictionary. The dictionary keys must be variable names and the dictionary values must be variable values. Keys must be StringName or String.
.. rst-class:: classref-item-separator
----
.. _class_Blackboard_method_set_parent: .. _class_Blackboard_method_set_parent:
.. rst-class:: classref-method .. rst-class:: classref-method

View File

@ -35,20 +35,16 @@ Methods
:widths: auto :widths: auto
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`create_blackboard<class_BlackboardPlan_method_create_blackboard>` **(** Node node, :ref:`Blackboard<class_Blackboard>` parent_scope=null **)** | | :ref:`Blackboard<class_Blackboard>` | :ref:`create_blackboard<class_BlackboardPlan_method_create_blackboard>` **(** Node node **)** |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`get_base_plan<class_BlackboardPlan_method_get_base_plan>` **(** **)** |const| | | :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`get_base_plan<class_BlackboardPlan_method_get_base_plan>` **(** **)** |const| |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Callable | :ref:`get_parent_scope_plan_provider<class_BlackboardPlan_method_get_parent_scope_plan_provider>` **(** **)** |const| |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`is_derived<class_BlackboardPlan_method_is_derived>` **(** **)** |const| | | bool | :ref:`is_derived<class_BlackboardPlan_method_is_derived>` **(** **)** |const| |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`populate_blackboard<class_BlackboardPlan_method_populate_blackboard>` **(** :ref:`Blackboard<class_Blackboard>` blackboard, bool overwrite, Node node **)** | | void | :ref:`populate_blackboard<class_BlackboardPlan_method_populate_blackboard>` **(** :ref:`Blackboard<class_Blackboard>` blackboard, bool overwrite, Node node **)** |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_base_plan<class_BlackboardPlan_method_set_base_plan>` **(** :ref:`BlackboardPlan<class_BlackboardPlan>` blackboard_plan **)** | | void | :ref:`set_base_plan<class_BlackboardPlan_method_set_base_plan>` **(** :ref:`BlackboardPlan<class_BlackboardPlan>` blackboard_plan **)** |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_parent_scope_plan_provider<class_BlackboardPlan_method_set_parent_scope_plan_provider>` **(** Callable callable **)** |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`sync_with_base_plan<class_BlackboardPlan_method_sync_with_base_plan>` **(** **)** | | void | :ref:`sync_with_base_plan<class_BlackboardPlan_method_sync_with_base_plan>` **(** **)** |
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -87,7 +83,7 @@ Method Descriptions
.. rst-class:: classref-method .. rst-class:: classref-method
:ref:`Blackboard<class_Blackboard>` **create_blackboard** **(** Node node, :ref:`Blackboard<class_Blackboard>` parent_scope=null **)** :ref:`Blackboard<class_Blackboard>` **create_blackboard** **(** Node node **)**
Constructs a new instance of a :ref:`Blackboard<class_Blackboard>` using this plan. If ``NodePath`` prefetching is enabled, ``node`` will be used to retrieve node instances for ``NodePath`` variables and substitute their values. Constructs a new instance of a :ref:`Blackboard<class_Blackboard>` using this plan. If ``NodePath`` prefetching is enabled, ``node`` will be used to retrieve node instances for ``NodePath`` variables and substitute their values.
@ -107,18 +103,6 @@ Returns the base plan. See :ref:`is_derived<class_BlackboardPlan_method_is_deriv
---- ----
.. _class_BlackboardPlan_method_get_parent_scope_plan_provider:
.. rst-class:: classref-method
Callable **get_parent_scope_plan_provider** **(** **)** |const|
Returns the parent scope plan provider - a callable that returns a **BlackboardPlan**.
.. rst-class:: classref-item-separator
----
.. _class_BlackboardPlan_method_is_derived: .. _class_BlackboardPlan_method_is_derived:
.. rst-class:: classref-method .. rst-class:: classref-method
@ -157,18 +141,6 @@ Use with caution, as it will remove variables not present in the base plan. Only
---- ----
.. _class_BlackboardPlan_method_set_parent_scope_plan_provider:
.. rst-class:: classref-method
void **set_parent_scope_plan_provider** **(** Callable callable **)**
Sets the parent scope plan provider - a callable that returns a **BlackboardPlan**. Used to provide hints in the inspector. When set, mapping feature becomes available.
.. rst-class:: classref-item-separator
----
.. _class_BlackboardPlan_method_sync_with_base_plan: .. _class_BlackboardPlan_method_sync_with_base_plan:
.. rst-class:: classref-method .. rst-class:: classref-method

View File

@ -19,7 +19,7 @@ Player of :ref:`BehaviorTree<class_BehaviorTree>` resources.
Description Description
----------- -----------
**BTPlayer** node is used to instantiate and play :ref:`BehaviorTree<class_BehaviorTree>` resources at runtime. During initialization, the behavior tree instance is given references to the agent, the :ref:`blackboard<class_BTPlayer_property_blackboard>`, and the current scene root. The agent can be specified by the :ref:`agent_node<class_BTPlayer_property_agent_node>` property (defaults to the BTPlayer's parent node). BTPlayer node is used for the instantiation and playback of :ref:`BehaviorTree<class_BehaviorTree>` resources at runtime. During instantiation, the behavior tree instance is initialized with a reference to the agent and the :ref:`blackboard<class_BTPlayer_property_blackboard>`. Agent is the owner of the BTPlayer node (see :ref:`Node.owner<class_Node_member_owner>`).
For an introduction to behavior trees, see :ref:`BehaviorTree<class_BehaviorTree>`. For an introduction to behavior trees, see :ref:`BehaviorTree<class_BehaviorTree>`.
@ -31,21 +31,19 @@ Properties
.. table:: .. table::
:widths: auto :widths: auto
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| bool | :ref:`active<class_BTPlayer_property_active>` | ``true`` | | bool | :ref:`active<class_BTPlayer_property_active>` | ``true`` |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| NodePath | :ref:`agent_node<class_BTPlayer_property_agent_node>` | ``NodePath("..")`` |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`behavior_tree<class_BTPlayer_property_behavior_tree>` | | | :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`behavior_tree<class_BTPlayer_property_behavior_tree>` | |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`blackboard<class_BTPlayer_property_blackboard>` | | | :ref:`Blackboard<class_Blackboard>` | :ref:`blackboard<class_BTPlayer_property_blackboard>` | |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`blackboard_plan<class_BTPlayer_property_blackboard_plan>` | | | :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`blackboard_plan<class_BTPlayer_property_blackboard_plan>` | |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| bool | :ref:`monitor_performance<class_BTPlayer_property_monitor_performance>` | ``false`` | | bool | :ref:`monitor_performance<class_BTPlayer_property_monitor_performance>` | ``false`` |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`UpdateMode<enum_BTPlayer_UpdateMode>` | :ref:`update_mode<class_BTPlayer_property_update_mode>` | ``1`` | | :ref:`UpdateMode<enum_BTPlayer_UpdateMode>` | :ref:`update_mode<class_BTPlayer_property_update_mode>` | ``1`` |
+---------------------------------------------+-------------------------------------------------------------------------+--------------------+ +---------------------------------------------+-------------------------------------------------------------------------+-----------+
.. rst-class:: classref-reftable-group .. rst-class:: classref-reftable-group
@ -163,23 +161,6 @@ If ``true``, the behavior tree will be executed during update.
---- ----
.. _class_BTPlayer_property_agent_node:
.. rst-class:: classref-property
NodePath **agent_node** = ``NodePath("..")``
.. rst-class:: classref-property-setget
- void **set_agent_node** **(** NodePath value **)**
- NodePath **get_agent_node** **(** **)**
Path to the node that will be used as the agent. Setting it after instantiation will have no effect.
.. rst-class:: classref-item-separator
----
.. _class_BTPlayer_property_behavior_tree: .. _class_BTPlayer_property_behavior_tree:
.. rst-class:: classref-property .. rst-class:: classref-property

View File

@ -23,8 +23,6 @@ BTSubtree instantiates a :ref:`BehaviorTree<class_BehaviorTree>` and includes it
Returns the status of the subtree's execution. Returns the status of the subtree's execution.
Subtree blackboard variables can be mapped to the main tree blackboard plan variables. Check out mapping section in the inspector.
Note: BTSubTree is designed as a simpler loader, and does not support updating :ref:`subtree<class_BTSubtree_property_subtree>` at runtime. A custom subtree decorator is better suited and `somewhat trivial <https://github.com/limbonaut/limboai/issues/94#issuecomment-2068833610>`__ to implement. Note: BTSubTree is designed as a simpler loader, and does not support updating :ref:`subtree<class_BTSubtree_property_subtree>` at runtime. A custom subtree decorator is better suited and `somewhat trivial <https://github.com/limbonaut/limboai/issues/94#issuecomment-2068833610>`__ to implement.
.. rst-class:: classref-reftable-group .. rst-class:: classref-reftable-group

View File

@ -46,8 +46,6 @@ Properties
+-------------------------------------+---------------------------------------------------------+--------+ +-------------------------------------+---------------------------------------------------------+--------+
| float | :ref:`elapsed_time<class_BTTask_property_elapsed_time>` | | | float | :ref:`elapsed_time<class_BTTask_property_elapsed_time>` | |
+-------------------------------------+---------------------------------------------------------+--------+ +-------------------------------------+---------------------------------------------------------+--------+
| Node | :ref:`scene_root<class_BTTask_property_scene_root>` | |
+-------------------------------------+---------------------------------------------------------+--------+
| :ref:`Status<enum_BT_Status>` | :ref:`status<class_BTTask_property_status>` | | | :ref:`Status<enum_BT_Status>` | :ref:`status<class_BTTask_property_status>` | |
+-------------------------------------+---------------------------------------------------------+--------+ +-------------------------------------+---------------------------------------------------------+--------+
@ -59,61 +57,59 @@ Methods
.. table:: .. table::
:widths: auto :widths: auto
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`_enter<class_BTTask_private_method__enter>` **(** **)** |virtual| | | void | :ref:`_enter<class_BTTask_private_method__enter>` **(** **)** |virtual| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`_exit<class_BTTask_private_method__exit>` **(** **)** |virtual| | | void | :ref:`_exit<class_BTTask_private_method__exit>` **(** **)** |virtual| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| String | :ref:`_generate_name<class_BTTask_private_method__generate_name>` **(** **)** |virtual| |const| | | String | :ref:`_generate_name<class_BTTask_private_method__generate_name>` **(** **)** |virtual| |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| PackedStringArray | :ref:`_get_configuration_warnings<class_BTTask_private_method__get_configuration_warnings>` **(** **)** |virtual| |const| | | PackedStringArray | :ref:`_get_configuration_warnings<class_BTTask_private_method__get_configuration_warnings>` **(** **)** |virtual| |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`_setup<class_BTTask_private_method__setup>` **(** **)** |virtual| | | void | :ref:`_setup<class_BTTask_private_method__setup>` **(** **)** |virtual| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`Status<enum_BT_Status>` | :ref:`_tick<class_BTTask_private_method__tick>` **(** float delta **)** |virtual| | | :ref:`Status<enum_BT_Status>` | :ref:`_tick<class_BTTask_private_method__tick>` **(** float delta **)** |virtual| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`abort<class_BTTask_method_abort>` **(** **)** | | void | :ref:`abort<class_BTTask_method_abort>` **(** **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`add_child<class_BTTask_method_add_child>` **(** :ref:`BTTask<class_BTTask>` task **)** | | void | :ref:`add_child<class_BTTask_method_add_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`add_child_at_index<class_BTTask_method_add_child_at_index>` **(** :ref:`BTTask<class_BTTask>` task, int idx **)** | | void | :ref:`add_child_at_index<class_BTTask_method_add_child_at_index>` **(** :ref:`BTTask<class_BTTask>` task, int idx **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`clone<class_BTTask_method_clone>` **(** **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`clone<class_BTTask_method_clone>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`editor_get_behavior_tree<class_BTTask_method_editor_get_behavior_tree>` **(** **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Status<enum_BT_Status>` | :ref:`execute<class_BTTask_method_execute>` **(** float delta **)** | | :ref:`Status<enum_BT_Status>` | :ref:`execute<class_BTTask_method_execute>` **(** float delta **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`get_child<class_BTTask_method_get_child>` **(** int idx **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`get_child<class_BTTask_method_get_child>` **(** int idx **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| int | :ref:`get_child_count<class_BTTask_method_get_child_count>` **(** **)** |const| | | int | :ref:`get_child_count<class_BTTask_method_get_child_count>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| int | :ref:`get_child_count_excluding_comments<class_BTTask_method_get_child_count_excluding_comments>` **(** **)** |const| | | int | :ref:`get_child_count_excluding_comments<class_BTTask_method_get_child_count_excluding_comments>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| int | :ref:`get_index<class_BTTask_method_get_index>` **(** **)** |const| | | int | :ref:`get_index<class_BTTask_method_get_index>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`get_parent<class_BTTask_method_get_parent>` **(** **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`get_parent<class_BTTask_method_get_parent>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`get_root<class_BTTask_method_get_root>` **(** **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`get_root<class_BTTask_method_get_root>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| String | :ref:`get_task_name<class_BTTask_method_get_task_name>` **(** **)** | | String | :ref:`get_task_name<class_BTTask_method_get_task_name>` **(** **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`has_child<class_BTTask_method_has_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| | | bool | :ref:`has_child<class_BTTask_method_has_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`initialize<class_BTTask_method_initialize>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** | | void | :ref:`initialize<class_BTTask_method_initialize>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`is_descendant_of<class_BTTask_method_is_descendant_of>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| | | bool | :ref:`is_descendant_of<class_BTTask_method_is_descendant_of>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`is_root<class_BTTask_method_is_root>` **(** **)** |const| | | bool | :ref:`is_root<class_BTTask_method_is_root>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| :ref:`BTTask<class_BTTask>` | :ref:`next_sibling<class_BTTask_method_next_sibling>` **(** **)** |const| | | :ref:`BTTask<class_BTTask>` | :ref:`next_sibling<class_BTTask_method_next_sibling>` **(** **)** |const| |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`print_tree<class_BTTask_method_print_tree>` **(** int initial_tabs=0 **)** | | void | :ref:`print_tree<class_BTTask_method_print_tree>` **(** int initial_tabs=0 **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`remove_child<class_BTTask_method_remove_child>` **(** :ref:`BTTask<class_BTTask>` task **)** | | void | :ref:`remove_child<class_BTTask_method_remove_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`remove_child_at_index<class_BTTask_method_remove_child_at_index>` **(** int idx **)** | | void | :ref:`remove_child_at_index<class_BTTask_method_remove_child_at_index>` **(** int idx **)** |
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------+---------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator .. rst-class:: classref-section-separator
@ -135,7 +131,7 @@ Node **agent**
- void **set_agent** **(** Node value **)** - void **set_agent** **(** Node value **)**
- Node **get_agent** **(** **)** - Node **get_agent** **(** **)**
The agent is the contextual object for the :ref:`BehaviorTree<class_BehaviorTree>` instance. This is usually the parent of the :ref:`BTPlayer<class_BTPlayer>` node that utilizes the :ref:`BehaviorTree<class_BehaviorTree>` resource. The agent is a contextual object for the task's :ref:`BehaviorTree<class_BehaviorTree>` instance. Usually, agent is the owner of the :ref:`BTPlayer<class_BTPlayer>` node containing the :ref:`BehaviorTree<class_BehaviorTree>` resource.
.. rst-class:: classref-item-separator .. rst-class:: classref-item-separator
@ -194,33 +190,6 @@ Returns ``0`` when task is not ``RUNNING``.
---- ----
.. _class_BTTask_property_scene_root:
.. rst-class:: classref-property
Node **scene_root**
.. rst-class:: classref-property-setget
- Node **get_scene_root** **(** **)**
Root node of the scene the behavior tree is used in (e.g., the owner of the :ref:`BTPlayer<class_BTPlayer>` node). Can be uses to retrieve ``NodePath`` references.
\ **Example:**\
::
extends BTAction
@export var node_path: NodePath
func _setup():
var node: Node = scene_root.get_node(node_path)
.. rst-class:: classref-item-separator
----
.. _class_BTTask_property_status: .. _class_BTTask_property_status:
.. rst-class:: classref-property .. rst-class:: classref-property
@ -368,18 +337,6 @@ Duplicates the task and its children, copying the exported members. Sub-resource
---- ----
.. _class_BTTask_method_editor_get_behavior_tree:
.. rst-class:: classref-method
:ref:`BehaviorTree<class_BehaviorTree>` **editor_get_behavior_tree** **(** **)**
Returns the behavior tree that owns this task. This is only available in the editor.
.. rst-class:: classref-item-separator
----
.. _class_BTTask_method_execute: .. _class_BTTask_method_execute:
.. rst-class:: classref-method .. rst-class:: classref-method
@ -500,11 +457,11 @@ Returns ``true`` if ``task`` is a child of this task.
.. rst-class:: classref-method .. rst-class:: classref-method
void **initialize** **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** void **initialize** **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard **)**
Initilizes the task. Assigns :ref:`agent<class_BTTask_property_agent>` and :ref:`blackboard<class_BTTask_property_blackboard>`, and calls :ref:`_setup<class_BTTask_private_method__setup>` for the task and its children. Initilizes the task. Assigns :ref:`agent<class_BTTask_property_agent>` and :ref:`blackboard<class_BTTask_property_blackboard>`, and calls :ref:`_setup<class_BTTask_private_method__setup>` for the task and its children.
The method is called recursively for each child task. ``scene_root`` should be the root node of the scene the behavior tree is used in (e.g., the owner of the node that contains the behavior tree). The method is called recursively for each child task.
.. rst-class:: classref-item-separator .. rst-class:: classref-item-separator

View File

@ -3,10 +3,9 @@
Accessing nodes in the scene tree Accessing nodes in the scene tree
================================= =================================
There are several ways to access nodes in the agent's scene tree from a :ref:`BTTask<class_BTTask>`. There are several ways to access nodes in the agent's scene tree.
**🛈 Note:** The root node of the agent's scene tree can be accessed with the **🛈 Note:** Agent is the owner of :ref:`BTPlayer<class_BTPlayer>` node.
:ref:`scene_root<class_BTTask_property_scene_root>` property.
With ``BBNode`` property With ``BBNode`` property
@ -17,7 +16,7 @@ With ``BBNode`` property
@export var cast_param: BBNode @export var cast_param: BBNode
func _tick(delta) -> Status: func _tick(delta) -> Status:
var node: ShapeCast3D = cast_param.get_value(scene_root, blackboard) var node: ShapeCast3D = cast_param.get_value(agent, blackboard)
With ``NodePath`` property With ``NodePath`` property
@ -28,16 +27,14 @@ With ``NodePath`` property
@export var cast_path: NodePath @export var cast_path: NodePath
func _tick(delta) -> Status: func _tick(delta) -> Status:
var node: ShapeCast3D = scene_root.get_node(cast_path) var node: ShapeCast3D = agent.get_node(cast_path)
Using blackboard plan Using blackboard plan
--------------------- ---------------------
You can :ref:`create a blackboard variable<editing_plan>` in the editor with the type ``NodePath`` You can :ref:`create a blackboard variable<editing_plan>` in the editor with the type ``NodePath``
and point it to the proper node in the :ref:`BTPlayer<class_BTPlayer>` blackboard plan. By default, and point it to the proper node in the :ref:`BTPlayer<class_BTPlayer>` blackboard plan.
any ``NodePath`` variable will be replaced with the node instance when the blackboard is instantiated
at runtime (see :ref:`BlackboardPlan.prefetch_nodepath_vars<class_BlackboardPlan_property_prefetch_nodepath_vars>`).
.. code:: gdscript .. code:: gdscript

View File

@ -92,7 +92,7 @@ Example 1: A simple action
# Called each time this task is ticked (aka executed). # Called each time this task is ticked (aka executed).
func _tick(p_delta: float) -> Status: func _tick(p_delta: float) -> Status:
var n: CanvasItem = scene_root.get_node_or_null(node_path) var n: CanvasItem = agent.get_node_or_null(node_path)
if is_instance_valid(n): if is_instance_valid(n):
n.visible = visible n.visible = visible
return SUCCESS return SUCCESS

View File

@ -91,7 +91,7 @@ Usage example:
@export var speed: BBFloat @export var speed: BBFloat
func _tick(delta: float) -> Status: func _tick(delta: float) -> Status:
var current_speed: float = speed.get_value(scene_root, blackboard, 0.0) var current_speed: float = speed.get_value(agent, blackboard, 0.0)
... ...
Advanced topic: Blackboard scopes Advanced topic: Blackboard scopes

Some files were not shown because too many files have changed in this diff Show More