Compare commits
14 Commits
b4d58b9dca
...
8a2dac5b6b
Author | SHA1 | Date |
---|---|---|
Wilson E. Alvarez | 8a2dac5b6b | |
Serhii Snitsaruk | e9eec23c3e | |
Serhii Snitsaruk | d0fcea5574 | |
Serhii Snitsaruk | e059429760 | |
Serhii Snitsaruk | 918095622c | |
Serhii Snitsaruk | 23c19c11e6 | |
Wilson E. Alvarez | 8f684f4169 | |
Wilson E. Alvarez | 5258506e12 | |
Wilson E. Alvarez | 2f0468bb00 | |
Wilson E. Alvarez | 2c740e7741 | |
Wilson E. Alvarez | 606b5a9276 | |
Wilson E. Alvarez | fa1fd7f55f | |
Wilson E. Alvarez | 127696e5ac | |
Wilson E. Alvarez | 5e5f849208 |
|
@ -11,9 +11,9 @@ runs:
|
|||
shell: bash
|
||||
run: |
|
||||
# ! Settings:
|
||||
TOOLCHAIN_64_URL=https://downloads.tuxfamily.org/godotengine/toolchains/linux/2021-02-11/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
|
||||
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://downloads.tuxfamily.org/godotengine/toolchains/linux/2021-02-11/i686-godot-linux-gnu_sdk-buildroot.tar.bz2
|
||||
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
|
||||
|
|
|
@ -72,6 +72,10 @@ 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.
|
||||
|
||||
## 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
|
||||
|
||||
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).
|
||||
|
@ -93,6 +97,7 @@ LimboAI can be used as either a C++ module or as a GDExtension shared library. G
|
|||
## Using the plugin
|
||||
|
||||
- [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)
|
||||
- [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)
|
||||
|
|
|
@ -237,7 +237,7 @@ BBVariable BlackboardPlan::get_var(const StringName &p_name) {
|
|||
Pair<StringName, BBVariable> BlackboardPlan::get_var_by_index(int p_index) {
|
||||
Pair<StringName, BBVariable> ret;
|
||||
ERR_FAIL_INDEX_V(p_index, (int)var_map.size(), ret);
|
||||
return var_list[p_index];
|
||||
return var_list.get(p_index);
|
||||
}
|
||||
|
||||
PackedStringArray BlackboardPlan::list_vars() const {
|
||||
|
|
|
@ -34,6 +34,44 @@ the other any time. For more information on this topic, see :ref:`gdextension`.
|
|||
|
||||
**🛈 Note:** Class reference is available in the side bar.
|
||||
|
||||
|
||||
First steps
|
||||
-----------
|
||||
|
||||
Choose the version you'd like to use. The module version provides better editor
|
||||
experience and performance, while the GDExtension version is more convenient to use.
|
||||
If you're unsure, start with the GDExtension version.
|
||||
You can change your decision at any time - both versions are fully compatible.
|
||||
For more information, see :ref:`gdextension`.
|
||||
|
||||
With GDExtension version
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Make sure you're using the latest stable version of the Godot editor.
|
||||
2. Create a new project for your experiments with LimboAI.
|
||||
3. In Godot, click AssetLib tab at the top of the screen and search for LimboAI. Download it. LimboAI plugin will be downloaded with the demo project files. Don't mind the errors printed at this point, this is due to the extension library not being loaded just yet.
|
||||
4. Reload your project with `Project -> Reload project`. There shouldn't be any errors printed now.
|
||||
5. In the project files, locate a scene file called `showcase.tscn` and run it. It's the demo's entry point.
|
||||
|
||||
With module version
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. In `GitHub releases <https://github.com/limbonaut/limboai/releases/>`_, download the latest pre-compiled release build for your platform.
|
||||
2. Download the demo project archive from the same release.
|
||||
3. Extract the pre-compiled editor and the demo project files.
|
||||
4. Launch the pre-compiled editor binary, import and open the demo project.
|
||||
5. Run the project.
|
||||
|
||||
Creating your own behavior trees
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Make a scene file for your agent, or open an existing scene.
|
||||
2. Add a :ref:`BTPlayer<class_BTPlayer>` node to your scene.
|
||||
3. Select :ref:`BTPlayer<class_BTPlayer>`, and create a new behavior tree in the inspector.
|
||||
4. Optionally, you can save the behavior tree to a file using the property's context menu.
|
||||
5. Click the behavior tree property to open it in the LimboAI editor.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "../util/limbo_string_names.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/button.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "editor/editor_interface.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/resources/style_box_flat.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
|
|
@ -26,7 +26,7 @@ Array BehaviorTreeData::serialize(const Ref<BTTask> &p_tree_instance, const Node
|
|||
List<Ref<BTTask>> stack;
|
||||
stack.push_back(p_tree_instance);
|
||||
while (stack.size()) {
|
||||
Ref<BTTask> task = stack[0];
|
||||
Ref<BTTask> task = stack.front()->get();
|
||||
stack.pop_front();
|
||||
|
||||
int num_children = task->get_child_count();
|
||||
|
@ -87,7 +87,7 @@ Ref<BehaviorTreeData> BehaviorTreeData::create_from_tree_instance(const Ref<BTTa
|
|||
List<Ref<BTTask>> stack;
|
||||
stack.push_back(p_tree_instance);
|
||||
while (stack.size()) {
|
||||
Ref<BTTask> task = stack[0];
|
||||
Ref<BTTask> task = stack.front()->get();
|
||||
stack.pop_front();
|
||||
|
||||
int num_children = task->get_child_count();
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include "core/object/callable_method_pointer.h"
|
||||
#include "core/os/time.h"
|
||||
#include "core/typedefs.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/resources/style_box.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
||||
|
@ -111,7 +111,7 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
|||
selected_id = item_get_task_id(tree->get_selected());
|
||||
}
|
||||
|
||||
if (last_root_id != 0 && p_data->tasks.size() > 0 && last_root_id == (uint64_t)p_data->tasks[0].id) {
|
||||
if (last_root_id != 0 && p_data->tasks.size() > 0 && last_root_id == (uint64_t)p_data->tasks.front()->get().id) {
|
||||
// * Update tree.
|
||||
// ! Update routine is built on assumption that the behavior tree does NOT mutate. With little work it could detect mutations.
|
||||
|
||||
|
@ -120,29 +120,29 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
|||
while (item) {
|
||||
ERR_FAIL_COND(idx >= p_data->tasks.size());
|
||||
|
||||
const BTTask::Status current_status = (BTTask::Status)p_data->tasks[idx].status;
|
||||
const BTTask::Status current_status = (BTTask::Status)p_data->tasks.get(idx).status;
|
||||
const BTTask::Status last_status = item_get_task_status(item);
|
||||
const bool status_changed = last_status != p_data->tasks[idx].status;
|
||||
const bool status_changed = last_status != p_data->tasks.get(idx).status;
|
||||
|
||||
if (status_changed) {
|
||||
item->set_metadata(1, current_status);
|
||||
if (current_status == BTTask::SUCCESS) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_success_status));
|
||||
item->set_icon(1, theme_cache.icon_success);
|
||||
} else if (current_status == BTTask::FAILURE) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_failure_status));
|
||||
item->set_icon(1, theme_cache.icon_failure);
|
||||
} else if (current_status == BTTask::RUNNING) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_running_status));
|
||||
item->set_icon(1, theme_cache.icon_running);
|
||||
} else {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_fresh));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_fresh));
|
||||
item->set_icon(1, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (status_changed || current_status == BTTask::RUNNING) {
|
||||
_item_set_elapsed_time(item, p_data->tasks[idx].elapsed_time);
|
||||
_item_set_elapsed_time(item, p_data->tasks.get(idx).elapsed_time);
|
||||
}
|
||||
|
||||
if (item->get_first_child()) {
|
||||
|
@ -165,7 +165,7 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
|||
} else {
|
||||
// * Create new tree.
|
||||
|
||||
last_root_id = p_data->tasks.size() > 0 ? p_data->tasks[0].id : 0;
|
||||
last_root_id = p_data->tasks.size() > 0 ? p_data->tasks.front()->get().id : 0;
|
||||
|
||||
tree->clear();
|
||||
TreeItem *parent = nullptr;
|
||||
|
@ -174,7 +174,7 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
|||
// Figure out parent.
|
||||
parent = nullptr;
|
||||
if (parents.size()) {
|
||||
Pair<TreeItem *, int> &p = parents[0];
|
||||
Pair<TreeItem *, int> &p = parents.front()->get();
|
||||
parent = p.first;
|
||||
if (!(--p.second)) {
|
||||
// No children left, remove it.
|
||||
|
@ -204,13 +204,13 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
|||
item->set_icon_max_width(0, 16 * _get_editor_scale()); // Force user icon size.
|
||||
|
||||
if (task_data.status == BTTask::SUCCESS) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_success_status));
|
||||
item->set_icon(1, theme_cache.icon_success);
|
||||
} else if (task_data.status == BTTask::FAILURE) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_failure_status));
|
||||
item->set_icon(1, theme_cache.icon_failure);
|
||||
} else if (task_data.status == BTTask::RUNNING) {
|
||||
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
||||
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_running_status));
|
||||
item->set_icon(1, theme_cache.icon_running);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@
|
|||
#include "core/variant/array.h"
|
||||
#include "editor/editor_interface.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/filesystem_dock.h"
|
||||
#include "editor/plugins/editor_debugger_plugin.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/item_list.h"
|
||||
|
|
|
@ -34,12 +34,13 @@
|
|||
#include "editor/editor_file_system.h"
|
||||
#include "editor/editor_help.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "editor/gui/editor_bottom_panel.h"
|
||||
#include "editor/inspector_dock.h"
|
||||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "editor/project_settings_editor.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
@ -682,7 +683,7 @@ void LimboAIEditor::_misc_option_selected(int p_id) {
|
|||
LimboDebuggerPlugin::get_singleton()->get_first_session_window()->set_window_enabled(true);
|
||||
} else {
|
||||
#ifdef LIMBOAI_MODULE
|
||||
EditorNode::get_singleton()->make_bottom_panel_item_visible(EditorDebuggerNode::get_singleton());
|
||||
EditorNode::get_bottom_panel()->make_item_visible(EditorDebuggerNode::get_singleton());
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->switch_to_debugger(
|
||||
LimboDebuggerPlugin::get_singleton()->get_first_session_tab_index());
|
||||
#elif LIMBOAI_GDEXTENSION
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "core/object/object.h"
|
||||
#include "core/templates/hash_set.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
#include "editor/gui/editor_spin_slider.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/control.h"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "editor/editor_help.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_paths.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "scene/gui/check_box.h"
|
||||
#endif // LIMBO_MODULE
|
||||
|
@ -60,7 +60,7 @@ void TaskButton::_bind_methods() {
|
|||
Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
||||
#ifdef LIMBOAI_MODULE
|
||||
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
||||
help_bit->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 1));
|
||||
help_bit->set_content_height_limits(1, 360 * EDSCALE);
|
||||
|
||||
String help_text;
|
||||
if (!p_text.is_empty()) {
|
||||
|
@ -69,7 +69,7 @@ Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
|||
help_text = "[i]" + TTR("No description.") + "[/i]";
|
||||
}
|
||||
|
||||
help_bit->set_text(help_text);
|
||||
help_bit->set_custom_text(String(), String(), help_text);
|
||||
|
||||
return help_bit;
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/object/script_language.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
||||
#ifdef LIMBOAI_GDEXTENSION
|
||||
|
@ -50,7 +50,7 @@ void TaskTree::_update_item(TreeItem *p_item) {
|
|||
if (p_item->get_parent()) {
|
||||
Ref<BTProbabilitySelector> sel = p_item->get_parent()->get_metadata(0);
|
||||
if (sel.is_valid() && sel->has_probability(p_item->get_index())) {
|
||||
p_item->set_custom_draw(0, this, LW_NAME(_draw_probability));
|
||||
p_item->set_custom_draw_callback(0, callable_mp(this, &TaskTree::_draw_probability));
|
||||
p_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,6 @@
|
|||
LimboStringNames *LimboStringNames::singleton = nullptr;
|
||||
|
||||
LimboStringNames::LimboStringNames() {
|
||||
_draw_failure_status = SN("_draw_failure_status");
|
||||
_draw_fresh = SN("_draw_fresh");
|
||||
_draw_probability = SN("_draw_probability");
|
||||
_draw_running_status = SN("_draw_running_status");
|
||||
_draw_success_status = SN("_draw_success_status");
|
||||
_enter = SN("_enter");
|
||||
_exit = SN("_exit");
|
||||
_generate_name = SN("_generate_name");
|
||||
|
|
|
@ -43,11 +43,6 @@ class LimboStringNames {
|
|||
public:
|
||||
_FORCE_INLINE_ static LimboStringNames *get_singleton() { return singleton; }
|
||||
|
||||
StringName _draw_failure_status;
|
||||
StringName _draw_fresh;
|
||||
StringName _draw_probability;
|
||||
StringName _draw_running_status;
|
||||
StringName _draw_success_status;
|
||||
StringName _enter;
|
||||
StringName _exit;
|
||||
StringName _generate_name;
|
||||
|
|
|
@ -515,6 +515,7 @@ PackedInt32Array LimboUtility::get_property_hints_allowed_for_type(Variant::Type
|
|||
case Variant::Type::PACKED_STRING_ARRAY:
|
||||
case Variant::Type::PACKED_VECTOR2_ARRAY:
|
||||
case Variant::Type::PACKED_VECTOR3_ARRAY:
|
||||
case Variant::Type::PACKED_VECTOR4_ARRAY:
|
||||
case Variant::Type::PACKED_COLOR_ARRAY:
|
||||
case Variant::Type::VARIANT_MAX: {
|
||||
} break;
|
||||
|
|
Loading…
Reference in New Issue