Hey folks,
I'm not a programmer (which is why I love playmaker). I'm sure I'm not alone in that I've started asking chatGPT to help me solve playmaker problems. It's been great, but it can sometimes get me out over my skies, so to speak.
I'm trying to make an interactive crank that can be spun by mouse movement. I've managed, leaning very much on the assistance of chatGPT, to create a custom playmaker action that rotates the crank. It uses mouse movement to rotate the crank object in the z axis in the FSMs 'Drag' state. When I let go it returns to the 'Idle' state.
This is exactly what I want except for one thing. Every time I grab the handle the crank jumps ahead in it's rotation by 90 degrees or so. I really just want the crank to turn smoothly from the start, and it feels like I'm so close.
I realize this is more of a code question and less a playmaker one, but I was hoping someone could find our (good ol' GPT and my) error here in the code.
Thanks in advance for any help!
Here's the flawed code:
using UnityEngine;
using HutongGames.PlayMaker;
namespace MidlifeCrisis
{
[HutongGames.PlayMaker.Tooltip("Rotate the crank handle based on mouse movement.")]
public class RotateCrankHandleAction : FsmStateAction
{
// Sensitivity to control the rotation speed
public float rotationSensitivity = 1.0f;
// Store the initial mouse position
private Vector3 initialMousePosition;
private bool isDragging = false;
private bool hasMoved = false;
// Reference to the Playmaker FSM float variable
private FsmFloat crankCurrentRotation;
private float initialRotationAngle = 0f;
private float rotationOffset = 0f;
public override void OnEnter()
{
base.OnEnter();
// Retrieve the Playmaker float variable reference
crankCurrentRotation = Fsm.Variables.GetFsmFloat("crankCurrentRotation");
// Store the initial rotation angle if it's not already set
initialRotationAngle = crankCurrentRotation.Value;
// Get the initial mouse position in screen space
initialMousePosition = Input.mousePosition;
// Set the dragging flag to true
isDragging = true;
hasMoved = false;
}
public override void OnUpdate()
{
base.OnUpdate();
if (isDragging)
{
// Get the current mouse position in screen space
Vector3 currentMousePosition = Input.mousePosition;
// Calculate the delta mouse position
Vector3 deltaMousePosition = currentMousePosition - initialMousePosition;
// Normalize the delta mouse position vector
deltaMousePosition.Normalize();
// Check if the mouse has moved
if (deltaMousePosition.magnitude > 0f)
{
hasMoved = true;
// Calculate the rotation angle based on the delta mouse position
float rotationAngle = Mathf.Atan2(deltaMousePosition.y, deltaMousePosition.x) * Mathf.Rad2Deg;
// Apply the rotation sensitivity to the rotation angle
rotationAngle *= rotationSensitivity;
// Apply the rotation offset by subtracting the initial rotation angle
rotationOffset = rotationAngle - initialRotationAngle;
// Apply the rotation to the crank handle's Z-axis rotation
// Assuming you have a reference to the crank handle object
GameObject crankHandleObject = Owner.gameObject;
crankHandleObject.transform.rotation = Quaternion.Euler(0f, 0f, initialRotationAngle + rotationOffset);
}
}
// Check for mouse button release
if (!Input.GetMouseButton(0) && isDragging)
{
// Set the dragging flag to false
isDragging = false;
// Trigger the transition to the Idle state only if the mouse has moved
if (hasMoved || Input.mousePosition != initialMousePosition)
{
// Update the crankCurrentRotation variable in Playmaker
crankCurrentRotation.Value = initialRotationAngle + rotationOffset;
Fsm.Event("HandleReleased");
}
}
}
}
}