Hello smart people!
I’m making a dial puzzle, similar to this:
I’ve acheived the scripting and the dial moves to where it should when a button is pressed, but it feels very robotic. What would be the best way of adding the “sway” that is present in the video? I’ve tried understanding physics constraints, but I got stuck and confused, so if that’s the best route, I would love some more guidance to know what I’m doing.
Hi there,
I am assuming you are using a skeletal mesh, if not just let me know but I think a skeletal mesh for dials bones and switches makes sense and would be nice.
What you can do at that moment for specifically “Swaying movement”
1- You can just make a timeline lerp 0-1 but with a higher curve. and Lerp the value of whatever dial should point as angle. Lerp (CurrentAngle, ToAngle) with an alpha curve like below.
2- You can do this with an evaluate on curve again but on tick (not sure how you want to do animation so) can be animation instances and they can have individual curves Animation Curves in Unreal Engine | Unreal Engine 5.7 Documentation | Epic Developer Community
3- You don’t go with this but actually go with a regular curve (just curve different)
4- You can do this without a curve just with some math as procedural which is ok too even can be better in some cases and that can be something like this which unreal has already a spring model
5- Or you can do manually on tick which is something like this.
Basically we get the error between current needle point. and to target, scale it by force, make a speed out of it and accumulate
However this would need delta time normalization, would be better if you use the given methods first since they are more deterministic, or you can do similar in C++ then would be better since this model (last one I gave) is tick dependent in lower or higher fps and “can” behave weirdly not a big problem though since it’s not core gameplay dependent physics.
Better to decouple it from tick model. The most reliable in that sense would be curves, however using spring model is also ok aswell.
Let us know how your setup is, I took the video as reference, these diegetic interfaces can be done in many ways, skeletal meshes, static meshes, material only setups etc.
Thank you so much for your very detailed response, and sorry for the lack of information from my side.
So my setup is just a tiny cube within a scene that works as a pivot.
I rotate it like this: I use a timeline (sort of like one of your examples) and lerp between positions. So all I’m missing is the “spring-iness”.
The spring interp solution you suggested seems to be the correct solution from what I can see!
What I’m struggling with is how the physics constrains need to look for the cube itself, as I’m not used to dealing with physics at all - and where to place the spring interp within this logic?
Thanks again so much, I hope I’m making enough sense for you to be able to understand and potentially help me with the last steps.
I understand your setup and thanks for sharing.
Well we can do with this setup already and to be honest we don’t need a real physics over here if you ask me. We can do with physics simulation aswell however from my perspective using physics contraints would be over engineering it (unless you have a specific gameplay behind it)
Instead we can just simplyfy it and do something that behaves like its physics driven. So I will just do that. However if you want a physics driven (contraints, forces etc) just let me know, can do it that way too.
Simply I replicated your setup, put a texture behind, make a pivot and have a needle.
In my setup Pivot RotZ - 45 to 220 is full scale from 1 to 6
Made a float track 1 with a nice curve
An event graph like this with timeline will do the job.
Will look similar to this behaviour.

A better version with actually built in unreal spring interp let’s do, think it would give nicer resutls by default.
Should give a result like this.

Also gave a shot with actual physics sim, which is ok but can be unnecessary in terms of interaction design. However made a contraint, lock positions enable only swing 1 motion for needle cube mesh
Edited the needle Mesh with correct scale and pivot in editor
Enabled async physics tick in engine and in actor, make a map of angles to dial numbers and set random every 2 seconds as target index → get angle and set as yaw to angular drive orientation target.
Additionally nor sure why but needle was sleeping somehow in short time so used wake up to re-orient physics constratint to new angle.
I am quite satisfied with this one also, made collision overlap all, needle settings are below
In terms of overshoot and swing is naturally achieved over here, its quite sensitive in terms of values but think you can copy my settings or play with knobs to find what works for you.

Works ok, can open room for different interactions over here ofc since its physics simulated also can create some bugs / features depending on the gameplay if you have physics influencing gameplay elements ( melee combat, explosions, projectiles etc)
Thanks for the question it was nice exercise also for me too and if you want to dig more deeper into this interaction on physics side, I would be more than happy to help further.
Again, thank you so much for your help and very detailed breakdown!
I followed the spring interp, and it works really well!
I haven’t set it up to use percentages (and I’m very bad with math), and instead have the value sort of hard coded into the flow. And as I was fiddling with the interp, I’m almost getting what I want. However, I noticed if it goes beyond the top position, it overshot and spins a full 360.I’ll post my whole flow, and hopefully you can see where I need to change something? Again, I’m so grateful for this help.
I made it clearer and made 90 into 95 instead, crossing the threshold - and it spins around a full circle instead of going back.

Is there any way to ensure it only goes back and forth, instead of spinning around fully?
Hey my pleasure, I like these kind of stuff, it physical, its physics, its movement, its UI + gameplay so
I enjoy it.
I saw this overshooting issue on my side aswell and its normal if values change dramatically and speed is too high + clamping adds to it. So when you use clamping that can create problems sometimes. Also rotators by their nature above 180 degrees they always prefer the shortest way, like electricity they prefer the easiest route to target. Since I don’t know your setup I didn’t mention but I strongly recommend doing exactly like below to achive the same effect as you demonstrated in post 1.
So below you can find the exact setup how I approach it to avoid the issues you are having.
I have a needle wrapped inside a scene component which is our pivot.
My scene points at rotation 0 0 0
However I move the child of scene (needle) to match 0 at -45 degrees. That way pivot RotationX (roll) 0 is needle->0
I check betwen 0 and 1 in dial and its approximately -45 degrees for me
That means I can go -45 degree rol for each section on the dial. What I would do try to avoid default rotation system of unreal instead go with interpolation between sections of the dial. That’s a proper nice way to do it if we don’t want to normalize angles or we can go write C++ custom spring interpolation to do it for us. I can show that too if you prefer.
However in short we get a target index and interpolate between current index (float) to target index(int)
Then we multiply output of interpolation by our section degrees
which entirely bypass (walkaround) unreal interpolation of rotations. This would result always an accurate interpolation no matter how big overshoot is. I strongly suggest doing this on tick, as a side note i see that on your scripts delta time is plugged not correctly too.
In terms of performance this would be a minor tick on the game however if you want you can continue doing with timeline and use deltaworldseconds as delta time
Let me know
Edit : Side by side physics driven vs tick Spring Interpolation
Physics Sim
Spring Interp
Side by Side

I see.
I think I am hitting some problems with this solution now.
Firstly: I want this to be a puzzle that can scale, and have several buttons that add/remove X amount of degrees from the dial. So I’d prefer not to specify an index, but rather add and subtract a value - like I do here.
So the annoying thing now is that my setup works, but doesn’t have the nice spring interp. But the spring interp is listening to where to go - not what to add.
Hmm. I’m not sure how to proceed honestly. I might need to just make the animation in the timeline like your first suggestion! 
Well I think its the same and index actually.
When you add +45 or -45 in your setup its basically a step. which can be 45 or like mine 1.
The point is to not rotate the rotation directly with interpolation more likely an index. so if your current step is 1 and you click go 2 then 2x45 or 95 90 degrees basically the same result.
You can do one button DegreeScale = 15 orther one DegreeScale = 95 or whatever degree you like. When you click a button its a step, its binary. So
Click Button A+ = Step 1
Click Button A+ = Step 2
Click Button A- = Step 3
If button ADegreeScale = 10 your cumulative degree in puzzle for button A is = +10 +10 -10 = 10
Click Button B+ = Step 1
Click Button B+ = Step 2
Click Button B- = Step 3
If button BDegreeScale = 95 your cumulative degree in puzzle for button B is = +95+95-95= 95
Current Degree (if conrolling the dial ) A+B total actions = +105
Or you can normalize angles before setting if you want spring + no direction problems.
Maybe you can try LerpRotation first then Spring Interpolate after, since LerpRotator has a choice as not to use bShortestPath
I see! I will try it again tomorrow. Thank you so much!
No worries let me know if you can get it working. Just to demonstrate what I meant in the previous post as steps.
So we can count buttons states. can be multiple states Plus Minus or Binary like you do as toggle On Off.
I preferred what you did and make 2 increment decrement functions hold index seperately. EDIT: I was doing one spring state but seems thats not a good idea so seperated those too.
Bound this 2 debug inputs since I didn’t want to create buttons logic, this would be enough for demo
Interpolated them individually and multiplied(scaled) their results individually as addition.
this should fundamentally achieve that I had a similar puzzle done using same logic.