0% found this document useful (0 votes)
16 views2 pages

Unity Steering Wheel Rotation Script

This C# script controls the rotation of a steering wheel attached to a hinge joint in Unity. It tracks the cumulative rotation, clamps it within limits, and applies motor resistance as the limits are approached. On grab/release it toggles interaction state and allows the wheel to return to zero position when ungrabbed. It logs the rotation values for debugging.

Uploaded by

Benny Trần
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views2 pages

Unity Steering Wheel Rotation Script

This C# script controls the rotation of a steering wheel attached to a hinge joint in Unity. It tracks the cumulative rotation, clamps it within limits, and applies motor resistance as the limits are approached. On grab/release it toggles interaction state and allows the wheel to return to zero position when ungrabbed. It logs the rotation values for debugging.

Uploaded by

Benny Trần
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

using System.

Collections;
using [Link];
using UnityEngine;
using [Link];

public class SteeringWheelRotation : MonoBehaviour


{
private HingeJoint hinge;
private float cumulativeRotation = 0f;
private float lastRotation = 0f;
private const float MAX_ROTATION = 720f;
private bool isInteracted = false;
private float previousRotation;

private void Start()


{
XRGrabInteractable grabInteractable = GetComponent<XRGrabInteractable>();

hinge = GetComponent<HingeJoint>();
previousRotation = [Link].y;
}

private void Update()


{
float currentRotation = [Link];
float rotationChange = currentRotation - lastRotation;

// Check for wrapping around the limits


if ([Link](rotationChange) > 150f) // This number can be adjusted based
on your specific setup
{
rotationChange = -[Link](rotationChange) * (180f -
[Link](rotationChange));
}

cumulativeRotation += rotationChange;

// Clamp cumulativeRotation
cumulativeRotation = [Link](cumulativeRotation, -MAX_ROTATION,
MAX_ROTATION);
lastRotation = currentRotation;

// Reset motor
[Link] = false;

// Check for resistance or stopping rotation


if ([Link](cumulativeRotation) >= 0.8 * MAX_ROTATION) // If rotation is
within 20% of max rotation
{
[Link] = true;
JointMotor motor = [Link];
[Link] = 100; // Play with this value for desired resistance
[Link] = -[Link](rotationChange) * 50; // This pushes
back against the rotation
[Link] = motor;
}
else if ((cumulativeRotation <= -MAX_ROTATION && rotationChange < 0) ||
(cumulativeRotation >= MAX_ROTATION && rotationChange > 0))
{
[Link] = true;
JointMotor motor = [Link];
[Link] = 0; // prevents any further rotation
[Link] = motor;
}

if (!isInteracted && cumulativeRotation != 0)


{
float returnSpeed = 5f; // Adjust this value as needed
cumulativeRotation = [Link](cumulativeRotation, 0,
returnSpeed * [Link]);
}
// Logging code:
float currentLocalRotation = [Link].y;
if ([Link](currentLocalRotation - previousRotation) > 0.1f) // Only log
if rotation changed by more than 0.1 degrees
{
[Link]("Wheel Rotation Changed: " + currentLocalRotation);
previousRotation = currentLocalRotation;
}
[Link] = new Vector3([Link].x, -
90f, -90f);

// Logging the local Euler angles:


Vector3 currentEulerAngles = [Link];
[Link]("Steering Wheel Rotation - X: {0}, Y: {1}, Z: {2}",
currentEulerAngles.x, currentEulerAngles.y, currentEulerAngles.z);
}

// You'd need to hook these up to the actual grab/release events


public void OnGrabbed() // This method name will vary based on your VR
interaction system
{
isInteracted = true;
}

public void OnReleased() // This method name will vary based on your VR
interaction system
{
isInteracted = false;
}

private float ConvertEulerAngle(float angle)


{
if (angle > 180)
return angle - 360;
return angle;
}

Common questions

Powered by AI

The script ensures the wheel does not exceed its rotational limits by clamping the cumulative rotation within a predefined range of -720 to 720 degrees. It uses Mathf.Clamp for this purpose, effectively preventing any further changes once these limits are reached. Additionally, it activates the hinge motor when nearing the limits, applying opposing torque to resist further rotation. If the limits are surpassed, the motor's force is reduced to zero, thus completely preventing any further rotation. This combination of clamp control and dynamic motor adjustments robustly manages and limits wheel rotation .

The script checks for a rotation change greater than 150 degrees to handle angle wrapping issues that occur due to the way Euler angles work in Unity. When angles wrap around from 360 to 0 (or vice versa), it can lead to large incorrect rotation values. To mitigate this, the script corrects these large changes by flipping their direction and adjusting the value to be the difference between the erroneously high change and 180 degrees. This adjustment maintains consistent rotation control and prevents erratic steering behavior .

The SteeringWheelRotation script employs logging to monitor significant changes in the steering wheel's rotation. It logs the current local Euler angles whenever the rotation changes by more than 0.1 degrees. This logging occurs by comparing the current local rotation angle with the previously recorded one, and if the difference exceeds the threshold, a log is generated with details of the wheel's new orientation. Additionally, the local Euler angles of the steering wheel's transform are logged each update cycle for debugging purposes .

The XRGrabInteractable component in this script allows the steering wheel to be interactable within a VR environment. It facilitates the detection of user inputs such as grabbing and releasing, associating these actions with the steering wheel's motion. Although the script doesn't detail the set-up of XRGrabInteractable, it is critical for linking user interactions with the steering mechanics defined in the script, ensuring the wheel responds dynamically to user input within the VR setting .

The script ensures the steering wheel returns to its neutral position by gradually reducing the cumulative rotation back to zero when not interacted with. This is achieved using Mathf.MoveTowards, which progressively reduces the cumulative rotation towards zero at a speed defined by 'returnSpeed' in the absence of user interaction ('isInteracted' is false). This approach simulates the physical return to a neutral position, creating a soft reset effect as opposed to an abrupt change, maintaining a smooth and realistic steering experience .

The motor in the SteeringWheelRotation script provides resistance or stops the rotation to simulate realistic steering wheel behavior. When the wheel's cumulative rotation is within 20% of the maximum allowed rotation, the motor is activated with a specified force, applying counter rotation to resist further movement. If the rotation matches or exceeds the limits, the motor force is set to zero to fully stop additional rotation. This dynamic control over the motor simulates physical constraints a real steering wheel might encounter, enhancing the interaction's realism .

User interaction is incorporated through the 'isInteracted' boolean variable that represents whether the steering wheel is currently being manipulated by a user. The methods 'OnGrabbed' and 'OnReleased' manage this state, altering 'isInteracted' to true or false depending on whether a user is grabbing or releasing the wheel. This interactive state influences whether the wheel's rotation should naturally return to zero or not since the return mechanism is only active when the wheel is not currently being interacted with .

The script implements a logging mechanism to track unexpected local rotation changes, logging details when the change in local rotation exceeds 0.1 degrees. This functionality serves as an alert system to identify and debug disproportionate or unanticipated adjustments in the wheel's orientation. Concurrently, the script maintains control over the wheel's rotation using angle clamping and motor activation, thereby minimizing the effect of sudden changes by reverting the rotation towards defined limits or resisting excess movement through the motor .

The script calculates cumulative rotation by updating the rotation change from the hinge's current angle to the last recorded angle. It specifically checks for angle wrapping by adjusting the rotation change if the absolute difference exceeds 150 degrees, ensuring smooth transitions across angular limits. The cumulative rotation is clamped between -720 and 720 degrees to prevent excessive rotation. Moreover, when the cumulative rotation approaches 80% of the maximum, or reaches the maximum limits, the script enables a motor to apply resistance or stop further rotation, thus managing the cumulative rotation effectively .

Converting Euler angles is significant for ensuring continuity and accuracy in rotational calculations. The script handles negative angles by converting angles greater than 180 degrees into their equivalent negative forms using the 'ConvertEulerAngle' method. This conversion standardizes angles to a range usable for computing rotations and avoids issues related to angle arithmetic that might arise with standard 0-360 degree representations .

You might also like