diff options
-rw-r--r-- | core/extension/gdnative_interface.cpp | 2 | ||||
-rw-r--r-- | core/extension/gdnative_interface.h | 2 | ||||
-rw-r--r-- | core/extension/native_extension.cpp | 21 | ||||
-rw-r--r-- | core/extension/native_extension.h | 2 | ||||
-rw-r--r-- | doc/classes/Resource.xml | 3 | ||||
-rw-r--r-- | doc/classes/Tween.xml | 18 | ||||
-rw-r--r-- | editor/code_editor.cpp | 6 | ||||
-rw-r--r-- | editor/inspector_dock.cpp | 128 | ||||
-rw-r--r-- | editor/inspector_dock.h | 8 | ||||
-rw-r--r-- | editor/plugins/material_editor_plugin.cpp | 12 | ||||
-rw-r--r-- | platform/javascript/display_server_javascript.cpp | 11 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 3 | ||||
-rw-r--r-- | scene/animation/tween.cpp | 11 | ||||
-rw-r--r-- | scene/animation/tween.h | 4 |
14 files changed, 178 insertions, 53 deletions
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index a65bdd16dc..77229a784d 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -1005,6 +1005,8 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { gdni.classdb_register_extension_class_method = nullptr; gdni.classdb_register_extension_class_integer_constant = nullptr; gdni.classdb_register_extension_class_property = nullptr; + gdni.classdb_register_extension_class_property_group = nullptr; + gdni.classdb_register_extension_class_property_subgroup = nullptr; gdni.classdb_register_extension_class_signal = nullptr; gdni.classdb_unregister_extension_class = nullptr; } diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 30346f233f..13aa273bc5 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -438,6 +438,8 @@ typedef struct { void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value); void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter); + void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix); + void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */ } GDNativeInterface; diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index a3cd7ca14c..635e53fa9c 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -184,6 +184,7 @@ void NativeExtension::_register_extension_class_integer_constant(const GDNativeE ClassDB::bind_integer_constant(class_name, p_enum_name, p_constant_name, p_constant_value); } + void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter) { NativeExtension *self = (NativeExtension *)p_library; @@ -202,6 +203,24 @@ void NativeExtension::_register_extension_class_property(const GDNativeExtension ClassDB::add_property(class_name, pinfo, p_setter, p_getter); } +void NativeExtension::_register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix) { + NativeExtension *self = (NativeExtension *)p_library; + + StringName class_name = p_class_name; + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + String(p_group_name) + "' for unexisting class '" + class_name + "'."); + + ClassDB::add_property_group(class_name, p_group_name, p_prefix); +} + +void NativeExtension::_register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix) { + NativeExtension *self = (NativeExtension *)p_library; + + StringName class_name = p_class_name; + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + String(p_subgroup_name) + "' for unexisting class '" + class_name + "'."); + + ClassDB::add_property_subgroup(class_name, p_subgroup_name, p_prefix); +} + void NativeExtension::_register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count) { NativeExtension *self = (NativeExtension *)p_library; @@ -325,6 +344,8 @@ void NativeExtension::initialize_native_extensions() { gdnative_interface.classdb_register_extension_class_method = _register_extension_class_method; gdnative_interface.classdb_register_extension_class_integer_constant = _register_extension_class_integer_constant; gdnative_interface.classdb_register_extension_class_property = _register_extension_class_property; + gdnative_interface.classdb_register_extension_class_property_group = _register_extension_class_property_group; + gdnative_interface.classdb_register_extension_class_property_subgroup = _register_extension_class_property_subgroup; gdnative_interface.classdb_register_extension_class_signal = _register_extension_class_signal; gdnative_interface.classdb_unregister_extension_class = _unregister_extension_class; } diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h index 9b1ebe0ed7..52e869ad4d 100644 --- a/core/extension/native_extension.h +++ b/core/extension/native_extension.h @@ -50,6 +50,8 @@ class NativeExtension : public Resource { static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value); static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter); + static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix); + static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 65dedf5280..efb0339aa7 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -16,7 +16,8 @@ <return type="Resource" /> <argument index="0" name="subresources" type="bool" default="false" /> <description> - Duplicates the resource, returning a new resource. By default, sub-resources are shared between resource copies for efficiency. This can be changed by passing [code]true[/code] to the [code]subresources[/code] argument which will copy the subresources. + Duplicates the resource, returning a new resource with the exported members copied. [b]Note:[/b] To duplicate the resource the constructor is called without arguments. This method will error when the constructor doesn't have default values. + By default, sub-resources are shared between resource copies for efficiency. This can be changed by passing [code]true[/code] to the [code]subresources[/code] argument which will copy the subresources. [b]Note:[/b] If [code]subresources[/code] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared. [b]Note:[/b] When duplicating a resource, only [code]export[/code]ed properties are copied. Other properties will be set to their default value in the new resource. </description> diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index 372a6e7ebf..ede6e2fdd5 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -58,8 +58,8 @@ [codeblock] var tween = create_tween().set_parallel(true) tween.tween_property(...) - tween.tween_property(...) #will run parallelly with above - tween.chain().tween_property(...) #will run after two above are finished + tween.tween_property(...) # Will run parallelly with above. + tween.chain().tween_property(...) # Will run after two above are finished. [/codeblock] </description> </method> @@ -215,11 +215,9 @@ Creates and appends an [IntervalTweener]. This method can be used to create delays in the tween animation, as an alternative for using the delay in other [Tweener]s or when there's no animation (in which case the [Tween] acts as a timer). [code]time[/code] is the length of the interval, in seconds. Example: creating an interval in code execution. [codeblock] - #... some code - var tween = create_tween() - tween.tween_interval(2) - await tween.finished - #... more code + # ... some code + await create_tween().tween_interval(2).finished + # ... more code [/codeblock] Example: creating an object that moves back and forth and jumps every few seconds. [codeblock] @@ -236,15 +234,15 @@ <method name="tween_method"> <return type="MethodTweener" /> <argument index="0" name="method" type="Callable" /> - <argument index="1" name="from" type="float" /> - <argument index="2" name="to" type="float" /> + <argument index="1" name="from" type="Variant" /> + <argument index="2" name="to" type="Variant" /> <argument index="3" name="duration" type="float" /> <description> Creates and appends a [MethodTweener]. This method is similar to a combination of [method tween_callback] and [method tween_property]. It calls a method over time with a tweened value provided as an argument. The value is tweened between [code]from[/code] and [code]to[/code] over the time specified by [code]duration[/code], in seconds. Use [method Callable.bind] to bind additional arguments for the call. You can use [method MethodTweener.set_ease] and [method MethodTweener.set_trans] to tweak the easing and transition of the value or [method MethodTweener.set_delay] to delay the tweening. Example: making a 3D object look from one point to another point. [codeblock] var tween = create_tween() - tween.tween_method(look_at.bind(Vector3.UP), Vector3(-1, 0, -1), Vector3(1, 0, -1), 1) #the look_at() method takes up vector as second argument + tween.tween_method(look_at.bind(Vector3.UP), Vector3(-1, 0, -1), Vector3(1, 0, -1), 1) # The look_at() method takes up vector as second argument. [/codeblock] Example: setting a text of a [Label], using an intermediate method and after a delay. [codeblock] diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 5599076c40..0c49a7169d 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -834,11 +834,9 @@ void CodeTextEditor::_line_col_changed() { } StringBuilder sb; - sb.append("("); - sb.append(itos(text_editor->get_caret_line() + 1).lpad(3)); - sb.append(","); + sb.append(itos(text_editor->get_caret_line() + 1).lpad(4)); + sb.append(" : "); sb.append(itos(positional_column + 1).lpad(3)); - sb.append(")"); line_and_col_txt->set_text(sb.as_string()); } diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 778046f45c..04ddf3552b 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -30,11 +30,22 @@ #include "inspector_dock.h" -#include "editor/editor_node.h" -#include "editor/editor_settings.h" +#include "editor/editor_scale.h" #include "editor/plugins/animation_player_editor_plugin.h" void InspectorDock::_menu_option(int p_option) { + _menu_option_confirm(p_option, false); +} + +void InspectorDock::_menu_confirm_current() { + _menu_option_confirm(current_option, true); +} + +void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { + if (!p_confirmed) { + current_option = p_option; + } + switch (p_option) { case EXPAND_ALL: { _menu_expandall(); @@ -82,39 +93,81 @@ void InspectorDock::_menu_option(int p_option) { } break; case OBJECT_UNIQUE_RESOURCES: { - editor_data->apply_changes_in_editors(); - if (current) { - List<PropertyInfo> props; - current->get_property_list(&props); - Map<RES, RES> duplicates; - for (const PropertyInfo &E : props) { - if (!(E.usage & PROPERTY_USAGE_STORAGE)) { - continue; - } + if (!p_confirmed) { + Vector<String> resource_propnames; - Variant v = current->get(E.name); - if (v.is_ref()) { + if (current) { + List<PropertyInfo> props; + current->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = current->get(E->get().name); REF ref = v; - if (ref.is_valid()) { - RES res = ref; - if (res.is_valid()) { - if (!duplicates.has(res)) { - duplicates[res] = res->duplicate(); - } - res = duplicates[res]; + RES res = ref; + if (v.is_ref() && ref.is_valid() && res.is_valid()) { + // Valid resource which would be duplicated if action is confirmed. + resource_propnames.append(E->get().name); + } + } + } + + if (resource_propnames.size()) { + unique_resources_list_tree->clear(); + TreeItem *root = unique_resources_list_tree->create_item(); - current->set(E.name, res); - editor->get_inspector()->update_property(E.name); + for (int i = 0; i < resource_propnames.size(); i++) { + String propname = resource_propnames[i].replace("/", " / "); + + TreeItem *ti = unique_resources_list_tree->create_item(root); + ti->set_text(0, bool(EDITOR_GET("interface/inspector/capitalize_properties")) ? propname.capitalize() : propname); + } + + unique_resources_confirmation->popup_centered(); + } else { + unique_resources_confirmation->set_text(TTR("This object has no resources.")); + current_option = -1; + unique_resources_confirmation->popup_centered(); + } + } else { + editor_data->apply_changes_in_editors(); + + if (current) { + List<PropertyInfo> props; + current->get_property_list(&props); + Map<RES, RES> duplicates; + for (const PropertyInfo &prop_info : props) { + if (!(prop_info.usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = current->get(prop_info.name); + if (v.is_ref()) { + REF ref = v; + if (ref.is_valid()) { + RES res = ref; + if (res.is_valid()) { + if (!duplicates.has(res)) { + duplicates[res] = res->duplicate(); + } + res = duplicates[res]; + + current->set(prop_info.name, res); + editor->get_inspector()->update_property(prop_info.name); + } } } } } - } - editor_data->get_undo_redo().clear_history(); + editor_data->get_undo_redo().clear_history(); - editor->get_editor_plugins_over()->edit(nullptr); - editor->get_editor_plugins_over()->edit(current); + editor->get_editor_plugins_over()->edit(nullptr); + editor->get_editor_plugins_over()->edit(current); + } } break; @@ -619,6 +672,29 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { warning->hide(); warning->connect("pressed", callable_mp(this, &InspectorDock::_warning_pressed)); + unique_resources_confirmation = memnew(ConfirmationDialog); + add_child(unique_resources_confirmation); + + VBoxContainer *container = memnew(VBoxContainer); + unique_resources_confirmation->add_child(container); + + Label *top_label = memnew(Label); + top_label->set_text(TTR("The following resources will be duplicated and embedded within this resource/object.")); + container->add_child(top_label); + + unique_resources_list_tree = memnew(Tree); + unique_resources_list_tree->set_hide_root(true); + unique_resources_list_tree->set_columns(1); + unique_resources_list_tree->set_column_title(0, TTR("Property")); + unique_resources_list_tree->set_custom_minimum_size(Size2(0, 200 * EDSCALE)); + container->add_child(unique_resources_list_tree); + + Label *bottom_label = memnew(Label); + bottom_label->set_text(TTR("This cannot be undone. Are you sure?")); + container->add_child(bottom_label); + + unique_resources_confirmation->connect("confirmed", callable_mp(this, &InspectorDock::_menu_confirm_current)); + warning_dialog = memnew(AcceptDialog); editor->get_gui_base()->add_child(warning_dialog); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 6615845b66..5bf6a34617 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -40,8 +40,6 @@ #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/control.h" -#include "scene/gui/label.h" -#include "scene/gui/popup_menu.h" class EditorNode; @@ -92,7 +90,13 @@ class InspectorDock : public VBoxContainer { Button *warning; AcceptDialog *warning_dialog; + int current_option = -1; + ConfirmationDialog *unique_resources_confirmation; + Tree *unique_resources_list_tree; + void _menu_option(int p_option); + void _menu_confirm_current(); + void _menu_option_confirm(int p_option, bool p_confirmed); void _new_resource(); void _load_resource(const String &p_type = ""); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 94966d4fe6..30945826bb 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -278,6 +278,8 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -315,6 +317,8 @@ Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_ } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -352,6 +356,8 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -389,6 +395,8 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -426,6 +434,8 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> & } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -463,5 +473,7 @@ Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> & } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index b43614eb99..be4d2cba20 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -497,9 +497,10 @@ EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const Emscript ev->set_button_mask(MouseButton(input->get_mouse_button_mask() | button_flag)); input->parse_input_event(ev); - ev->set_pressed(false); - ev->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag)); - input->parse_input_event(ev); + Ref<InputEventMouseButton> release = ev->duplicate(); + release->set_pressed(false); + release->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag)); + input->parse_input_event(release); return true; } @@ -508,7 +509,6 @@ EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const Emscript EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) { DisplayServerJavaScript *display = get_singleton(); Ref<InputEventScreenTouch> ev; - ev.instantiate(); int lowest_id_index = -1; for (int i = 0; i < p_event->numTouches; ++i) { const EmscriptenTouchPoint &touch = p_event->touches[i]; @@ -516,6 +516,7 @@ EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const Em lowest_id_index = i; if (!touch.isChanged) continue; + ev.instantiate(); ev->set_index(touch.identifier); ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY)); display->touches[i] = ev->get_position(); @@ -534,7 +535,6 @@ EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const Em EM_BOOL DisplayServerJavaScript::touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) { DisplayServerJavaScript *display = get_singleton(); Ref<InputEventScreenDrag> ev; - ev.instantiate(); int lowest_id_index = -1; for (int i = 0; i < p_event->numTouches; ++i) { const EmscriptenTouchPoint &touch = p_event->touches[i]; @@ -542,6 +542,7 @@ EM_BOOL DisplayServerJavaScript::touchmove_callback(int p_event_type, const Emsc lowest_id_index = i; if (!touch.isChanged) continue; + ev.instantiate(); ev->set_index(touch.identifier); ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY)); Point2 &prev = display->touches[i]; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index a39941339a..5c6824cf44 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -3614,7 +3614,8 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + "Please update your drivers or if you have a very old or integrated GPU, upgrade it.\n" + "If you have updated your graphics drivers recently, try rebooting.", "Unable to initialize Video driver"); } return ds; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 3018fd3ae6..2847031375 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -60,6 +60,11 @@ Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); +#ifdef DEBUG_ENABLED + Variant::Type property_type = p_target->get_indexed(p_property.get_as_property_path().get_subnames()).get_type(); + ERR_FAIL_COND_V_MSG(property_type != p_to.get_type(), Ref<PropertyTweener>(), "Type mismatch between property and final value: " + Variant::get_type_name(property_type) + " and " + Variant::get_type_name(p_to.get_type())); +#endif + Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration)); append(tweener); return tweener; @@ -83,7 +88,7 @@ Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) { return tweener; } -Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float p_to, float p_duration) { +Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration) { ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); @@ -496,6 +501,8 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f } Variant Tween::calculate_delta_value(Variant p_intial_val, Variant p_final_val) { + ERR_FAIL_COND_V_MSG(p_intial_val.get_type() != p_final_val.get_type(), p_intial_val, "Type mismatch between initial and final value: " + Variant::get_type_name(p_intial_val.get_type()) + " and " + Variant::get_type_name(p_final_val.get_type())); + switch (p_intial_val.get_type()) { case Variant::BOOL: { return (int)p_final_val - (int)p_intial_val; @@ -888,7 +895,7 @@ void MethodTweener::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ease", "ease"), &MethodTweener::set_ease); } -MethodTweener::MethodTweener(Callable p_callback, float p_from, float p_to, float p_duration) { +MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration) { callback = p_callback; initial_val = p_from; delta_val = tween->calculate_delta_value(p_from, p_to); diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 953d573539..6a48d332b8 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -128,7 +128,7 @@ public: Ref<PropertyTweener> tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration); Ref<IntervalTweener> tween_interval(float p_time); Ref<CallbackTweener> tween_callback(Callable p_callback); - Ref<MethodTweener> tween_method(Callable p_callback, float p_from, float p_to, float p_duration); + Ref<MethodTweener> tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration); void append(Ref<Tweener> p_tweener); bool custom_step(float p_delta); @@ -258,7 +258,7 @@ public: void start() override; bool step(float &r_delta) override; - MethodTweener(Callable p_callback, float p_from, float p_to, float p_duration); + MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration); MethodTweener(); protected: |