something is wrong with ripple motion

cc @littensy something is wrong with motion when i set the velocity ripple 10 a3. if i setVelocity it works exactly once and doesnt work anymore. it works again only if i do motion.getVelocity()
const OnMouseButton1Clicked = () => {
if (!Active) return;
//jelly_motion.getVelocity(); //if that line is commented, velocity works only once
jelly_motion.setVelocity(50);
SoundSystem.PlayLocalSoundFromName(SoundResources.ESoundName.UIClickButton);
OnClick?.();
};
const OnMouseButton1Clicked = () => {
if (!Active) return;
//jelly_motion.getVelocity(); //if that line is commented, velocity works only once
jelly_motion.setVelocity(50);
SoundSystem.PlayLocalSoundFromName(SoundResources.ESoundName.UIClickButton);
OnClick?.();
};
9 Replies
Tester
TesterOP2mo ago
main code:
import { composeBindings, getBindingValue, useEventListener } from "@rbxts/pretty-react-hooks";
import { Binding, useBinding, useMemo, useRef } from "@rbxts/react";
import { Animatable, Motion, MotionOptions, SpringOptions, createMotion } from "@rbxts/ripple";
import { GuiService, RunService } from "@rbxts/services";

export function useMotion(
initial_value: number,
options?: MotionOptions<number>,
): LuaTuple<[Binding<number>, Motion]>;
export function useMotion<T extends Animatable>(
initial_value: T,
options?: MotionOptions<T>,
): LuaTuple<[Binding<T>, Motion<T>]>;
export function useMotion<T extends Animatable>(initial_value: T, options?: MotionOptions<T>) {
const motion = useMemo(() => {
return createMotion(initial_value, options);
}, []);

const [binding, SetValue] = useBinding(initial_value);

useEventListener(RunService.Heartbeat, (delta) => {
const value = motion.step(delta);
if (value === binding.getValue()) return;
SetValue(value);
});

return $tuple(binding, motion);
}

export function useJellySpring(
config?: SpringOptions,
force_animation?: boolean,
): LuaTuple<[Binding<Vector2>, Motion<number>]> {
const [binding_y, motion] = useMotion(1, {
spring: config,
});
const binding_x = binding_y.map((y) => 1 / math.sqrt(math.clamp(y, 0.2, 5)));

return $tuple(
composeBindings(binding_x, binding_y, (x, y) => {
const reduced_motion = GuiService.ReducedMotionEnabled && !force_animation;
return reduced_motion ? Vector2.one : new Vector2(x, y);
}),
motion,
);
}
import { composeBindings, getBindingValue, useEventListener } from "@rbxts/pretty-react-hooks";
import { Binding, useBinding, useMemo, useRef } from "@rbxts/react";
import { Animatable, Motion, MotionOptions, SpringOptions, createMotion } from "@rbxts/ripple";
import { GuiService, RunService } from "@rbxts/services";

export function useMotion(
initial_value: number,
options?: MotionOptions<number>,
): LuaTuple<[Binding<number>, Motion]>;
export function useMotion<T extends Animatable>(
initial_value: T,
options?: MotionOptions<T>,
): LuaTuple<[Binding<T>, Motion<T>]>;
export function useMotion<T extends Animatable>(initial_value: T, options?: MotionOptions<T>) {
const motion = useMemo(() => {
return createMotion(initial_value, options);
}, []);

const [binding, SetValue] = useBinding(initial_value);

useEventListener(RunService.Heartbeat, (delta) => {
const value = motion.step(delta);
if (value === binding.getValue()) return;
SetValue(value);
});

return $tuple(binding, motion);
}

export function useJellySpring(
config?: SpringOptions,
force_animation?: boolean,
): LuaTuple<[Binding<Vector2>, Motion<number>]> {
const [binding_y, motion] = useMotion(1, {
spring: config,
});
const binding_x = binding_y.map((y) => 1 / math.sqrt(math.clamp(y, 0.2, 5)));

return $tuple(
composeBindings(binding_x, binding_y, (x, y) => {
const reduced_motion = GuiService.ReducedMotionEnabled && !force_animation;
return reduced_motion ? Vector2.one : new Vector2(x, y);
}),
motion,
);
}
Tester
TesterOP2mo ago
value didnt update?
No description
Tester
TesterOP2mo ago
so what happens, intermediate.value doesnt update when the velocity is set, but updates if you get it
No description
Tester
TesterOP2mo ago
No description
Tester
TesterOP2mo ago
ok, seems like this is the fix
local function setValue<T>(intermediate: Intermediate<T>, value: T): boolean
if type(value) == "table" then
value = merge(getValue(intermediate), value)
end

local currentValue = getValue(intermediate) --getValue instead of directly .value

if currentValue ~= value then
intermediate.value = value
intermediate.encode(intermediate.components, value)
intermediate.dirty = nil -- clean dirty here
return true
else
return false --false instead of true
end
end
local function setValue<T>(intermediate: Intermediate<T>, value: T): boolean
if type(value) == "table" then
value = merge(getValue(intermediate), value)
end

local currentValue = getValue(intermediate) --getValue instead of directly .value

if currentValue ~= value then
intermediate.value = value
intermediate.encode(intermediate.components, value)
intermediate.dirty = nil -- clean dirty here
return true
else
return false --false instead of true
end
end
Dont know how correct it is @littensy , and idk whether .dirty = nil should be in the first part of if statement @littensy have you seen it/fixed it?
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Tester
TesterOP6d ago
Hii, was it fixed? would be nice if i could install the version from the npm instead of local one
Unknown User
Unknown User6d ago
Message Not Public
Sign In & Join Server To View
Tester
TesterOP6d ago
oki, in a bit

Did you find this page helpful?