Skip to content

Fix "Create Custom Bone2D(s) from Node(s)" to create working bone chains #107797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Joey-Einerhand
Copy link
Contributor

@Joey-Einerhand Joey-Einerhand commented Jun 21, 2025

before the new bone- and IK system in 4.0, the "Create Custom Bone2D(s) from Node(s)" editor button created an out-of-the-box working chain of bones. This can be seen in the pre-4.0 docs. Since 4.0, that has been broken.

This pull request aims to bring back that functionality.
When using the "Create Custom Bone2D(s) from Node(s)" button, the selected nodes should be used to create a correctly setup Bone2D chain, where Bone2Ds without Bone2D children or siblings should connect to an 'end' marker2D.

godot_createbonesbutton_comparison

Fixes #92227


This is my first 'real' pull request to the Godot engine. I did my best to follow the docs. Please be really critical of my changes.

Notes:

  • Because the reparenting the nodes needs to happen sequentially, I've changed around some register_action() and commit_action() . To undo the "Create Custom Bone2D(s) from Node(s)" action, requires 4 undos. The way I did it is wrong. If you know of a better way, please tell me.
  • I'm pretty sure I got Clang to reformat my code, but please give the code style another pass.
  • Testers: I've added a minimum project to this PR so you don't have to start from scratch. make-bone-2d-mrp.zip
  • This does not fix the 'Bone lacks REST pose' warning. Should I include a fix for that in this PR, or does that need a seperate issue?
  • When using the 'Fixed' scenario, the angle constraint gizmos are drawn behind the sprites. Should I include a fix in this PR, or does that need a seperate issue?

@AThousandShips AThousandShips changed the title Fixed "Create Custom Bone2D(s) from Node(s)" to create working bone chains Fix "Create Custom Bone2D(s) from Node(s)" to create working bone chains Jun 21, 2025
@Joey-Einerhand Joey-Einerhand force-pushed the master branch 2 times, most recently from 10fc8d2 to f3606c0 Compare June 22, 2025 09:34
@KoBeWi
Copy link
Member

KoBeWi commented Jun 27, 2025

I'm getting a crash in the MRP from #92227:

VectorWriteProxy<Variant>::operator[](__int64 p_index) Line 54 (c:\godot_source\core\templates\vector.h:54)
Array::operator[](int p_idx) Line 106 (c:\godot_source\core\variant\array.cpp:106)
CanvasItemEditor::_popup_callback(int p_op) Line 4923 (c:\godot_source\editor\plugins\canvas_item_editor_plugin.cpp:4923)
call_with_variant_args_helper<CanvasItemEditor,int,0>(CanvasItemEditor * p_instance, void(CanvasItemEditor::*)(int) p_method, const Variant * * p_args, Callable::CallError & r_error, IndexSequence<0> __formal) Line 228 (c:\godot_source\core\variant\binder_common.h:228)
call_with_variant_args<CanvasItemEditor,int>(CanvasItemEditor * p_instance, void(CanvasItemEditor::*)(int) p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 338 (c:\godot_source\core\variant\binder_common.h:338)
CallableCustomMethodPointer<CanvasItemEditor,void,int>::call(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 107 (c:\godot_source\core\object\callable_method_pointer.h:107)
Callable::callp(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 58 (c:\godot_source\core\variant\callable.cpp:58)
Object::emit_signalp(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 1288 (c:\godot_source\core\object\object.cpp:1288)
Node::emit_signalp(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 4130 (c:\godot_source\scene\main\node.cpp:4130)
Object::emit_signal<int>(const StringName & p_name, int <p_args_0>) Line 941 (c:\godot_source\core\object\object.h:941)
PopupMenu::activate_item(int p_idx) Line 2744 (c:\godot_source\scene\gui\popup_menu.cpp:2744)
PopupMenu::_input_from_window_internal(const Ref<InputEvent> & p_event) Line 686 (c:\godot_source\scene\gui\popup_menu.cpp:686)
PopupMenu::_input_from_window(const Ref<InputEvent> & p_event) Line 468 (c:\godot_source\scene\gui\popup_menu.cpp:468)
Window::_window_input(const Ref<InputEvent> & p_ev) Line 1793 (c:\godot_source\scene\main\window.cpp:1793)
call_with_variant_args_helper<Window,Ref<InputEvent> const &,0>(Window * p_instance, void(Window::*)(const Ref<InputEvent> &) p_method, const Variant * * p_args, Callable::CallError & r_error, IndexSequence<0> __formal) Line 223 (c:\godot_source\core\variant\binder_common.h:223)
call_with_variant_args<Window,Ref<InputEvent> const &>(Window * p_instance, void(Window::*)(const Ref<InputEvent> &) p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 338 (c:\godot_source\core\variant\binder_common.h:338)
CallableCustomMethodPointer<Window,void,Ref<InputEvent> const &>::call(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 107 (c:\godot_source\core\object\callable_method_pointer.h:107)
Callable::callp(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 58 (c:\godot_source\core\variant\callable.cpp:58)
Callable::call<Ref<InputEvent>>(Ref<InputEvent> <p_args_0>) Line 953 (c:\godot_source\core\variant\variant.h:953)
DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> & p_event) Line 4412 (c:\godot_source\platform\windows\display_server_windows.cpp:4412)
DisplayServerWindows::_dispatch_input_events(const Ref<InputEvent> & p_event) Line 4383 (c:\godot_source\platform\windows\display_server_windows.cpp:4383)
Input::_parse_input_event_impl(const Ref<InputEvent> & p_event, bool p_is_emulated) Line 907 (c:\godot_source\core\input\input.cpp:907)
Input::flush_buffered_events() Line 1188 (c:\godot_source\core\input\input.cpp:1188)
DisplayServerWindows::process_events() Line 3802 (c:\godot_source\platform\windows\display_server_windows.cpp:3802)
OS_Windows::run() Line 2252 (c:\godot_source\platform\windows\os_windows.cpp:2252)
widechar_main(int argc, wchar_t * * argv) Line 97 (c:\godot_source\platform\windows\godot_windows.cpp:97)
_main() Line 122 (c:\godot_source\platform\windows\godot_windows.cpp:122)
main(int argc, char * * argv) Line 136 (c:\godot_source\platform\windows\godot_windows.cpp:136)
WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 150 (c:\godot_source\platform\windows\godot_windows.cpp:150)

Seems like you are using wrong index in the for loop. You could change it to range loop, to avoid this problem altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Broken: (Make Bone2D Nodes from Nodes)
3 participants