FyroxEngine/Fyrox · warning

Implement me!

Error message

Implement me!

What it means

Fyrox UI animation value bindings support Position, Scale, Rotation, and Property. The Scale and Rotation bindings are simply not implemented yet: reaching those branches unconditionally logs this warning and the animated value is never applied to the widget. Animations targeting scale or rotation silently do nothing.

Solutions

  1. Restructure UI animations to use ValueBinding::Position or ValueBinding::Property instead of Scale/Rotation.
  2. For transforms, bind Property targets if the widget exposes transform-like properties, or animate Position only.
  3. Implement the Scale/Rotation arms by reading the track value and writing it to the widget's transform if you control the fork.

Example fix

// before: track animates scale — does nothing at runtime
let track = Track::new(widget_handle, ValueBinding::Scale, ...);
// after: animate via a bound property
let track = Track::new(widget_handle, ValueBinding::Property { name: "width".into(), value_type: NumericType::F32 }, ...);
Defensive patterns

Strategy: validation

Validate before calling

// reject unimplemented bindings before building the animation
for track in &animation.tracks_ref() {
    if matches!(track.binding(), ValueBinding::Scale | ValueBinding::Rotation) {
        panic!("UI animation: Scale/Rotation bindings are not implemented");
    }
}

Prevention

When it happens

Trigger: Playing an Animation whose tracks contain ValueBinding::Scale or ValueBinding::Rotation tracks against a UI widget node; the binding's apply() hits the stub branch every frame.

Common situations: Creating UI animations in the editor or code that animate widget scale/rotation; porting scene animations to UI widgets assuming parity with 3D node animation.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/6d75318f4f6f635a. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-ui/src/animation.rs:131

    /// Tries to set each value from the collection to the respective property (by binding) of the
    /// given widget.
    fn apply(&self, node_ref: &mut UiNode);
}

impl BoundValueCollectionExt for BoundValueCollection {
    fn apply(&self, node_ref: &mut UiNode) {
        for bound_value in self.values.iter() {
            match bound_value.binding {
                ValueBinding::Position => {
                    if let TrackValue::Vector2(v) = bound_value.value {
                        node_ref.set_desired_local_position(v);
                    } else {
                        Log::err(
                            "Unable to apply position, because underlying type is not Vector2!",
                        )
                    }
                }
                ValueBinding::Scale => Log::warn("Implement me!"),
                ValueBinding::Rotation => Log::warn("Implement me!"),
                ValueBinding::Property {
                    name: ref property_name,
                    value_type,
                } => bound_value.apply_to_object(node_ref, property_name, value_type),
            }
        }
    }
}

/// Animation player is a node that contains multiple animations. It updates and plays all the animations.
/// The node could be a source of animations for animation blending state machines. To learn more about
/// animations, see [`Animation`] docs.
#[derive(Visit, PartialEq, Reflect, Clone, Debug)]
#[reflect(
    derived_type = "UiNode",
    type_uuid = "44d1c94e-354f-4f9a-b918-9d31c28aa16a"
)]

View on GitHub (pinned to 76c91aad8e)