Sadly, adding a physics component isn’t an option, as the handle itself is a custom component and is to be used for various types of devices (not just rotatable switches/levers, but also rotatable dials & translatable levers).
And something else to note is that some of these devices can even have multiple states, or bi-directional movement.
Take the following lever for example:
This lever, by default, is centered within it’s base. It can be pulled all the way down, or all the way up before “activating” something.
For the “translatable” version of this lever, picture it’s base being flat and the handle moving along it’s track (as opposed to rotating from it’s pivot).
So what I really need is to determine which direction the device needs to be rotated (or translated, in the case of translatable levers), and allow the delta mouse movements to tie into how much the device moves within that direction. Something like this really calls for a mathematical approach, but I’m having trouble figuring out the exact algorithm that I should be using to figure out which direction these devices should move.
For the actual rotations, I’m using USceneComponent::AddRelativeRotation and then clamping the angles to user-defined values within the blueprint’s class defaults.
As for the dot product, I’m not sure what to do with it. Here’s basically what I have:
auto MouseDirection = MouseEnd - MouseStart; // Direction (2D) the mouse has moved since the last frame
MouseDirection.Normalize();
auto GrabSocketLocation = HandleMesh->GetSocketLocation(TEXT("Handle")); // Location (3D, World-Space) of handle
auto PivotSocketLocation = HandleMesh->GetSocketLocation(TEXT("Pivot")); // Location (3D, World-Space) of pivot/base
auto PC = CastChecked<AMyPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
auto MouseWorldLocation = FVector::ZeroVector;
auto MouseWorldDirection = FVector::ZeroVector;
PC->DeprojectMousePositionToWorld(MouseWorldLocation, MouseWorldDirection);
auto V1 = PivotSocketLocation - GrabSocketLocation;
auto V2 = PivotSocketLocation - MouseWorldLocation;
V1.Normalize();
V2.Normalize();
auto DotProduct = FVector::DotProduct(V1, V2); // Not sure what to do with this value
auto ArcCos = FMath::Acos(DotProduct); // Not sure what to do with this value
//...
HandleMesh->AddRelativeLocation(/* Magic Numbers Based On Direction and Scaled By MouseDelta */);