Hey Zeer The same thing happened to me, so I took a few days out of the course to figure out a workaround. As far as I can see, you’ve already identified the problem. If your xThrow and yThrow are either 0 or 1, then multiplying them with your controllRollFactor and controllPitchFactor (respectively) will act as a toggle. For instance, if your controllRollFactor is 30, then your ship will either be rotated -30, 0, or 30, with no smoothing. I’m guessing that Rick was demonstrating with a thumbstick and getting smoother input values in between 0 and 1, but since I’m working off a keyboard, I had that “toggle” effect. Now… if you’re using a controller and only getting 0/1 as our input with the Input System, then… I can’t help grin I’m about 3 weeks into this course, and that’s also how long I’ve been using Unity (and almost as long as I’ve been familiar with C#), so my workaround isn’t at all the intent of the assignment, and wouldn’t address any deeper issues, but it has smoothed the roll and pitch of my ship, so I’ll paste it here.
public class PlayerControls : MonoBehaviour
{
[SerializeField] InputAction movement;
[SerializeField] float moveFactor = 20f;
[SerializeField] float xRange = 18f;
[SerializeField] float yRange = 10.5f;
[SerializeField] float yRangeOffset = 5.5f;
[SerializeField] float positionPitchFactor = -1f;
[SerializeField] float controlPitchFactor = -5f;
[SerializeField] float positionYawFactor = 1.5f;
[SerializeField] float controlRollFactor = -10f;
[SerializeField] float rotationLerpIncrement = 3f; // Lerp variable
[SerializeField] float rollRotation = 5f; // Lerp variable
[SerializeField] float pitchRotation = 3f; // Lerp variable
float xThrow, yThrow, xLerpThrow, yLerpThrow; // The last two variables are used in the smooth-rotation code
float tForRollLerp = 0.5f; // Lerp variable
float tForPitchLerp = 0.5f; // Lerp variable
void Update() // ---UPDATE---
{
ProcessTranslation();
ProcessRotation();
}
void ProcessTranslation() // Controls X and Y movement
{
xThrow = movement.ReadValue<Vector2>().x; // float xThrow = Input.GetAxis("Horizontal"); // Used for the old input Manager vs...
yThrow = movement.ReadValue<Vector2>().y; // float yThrow = Input.GetAxis("Vertical"); // ...what this project uses (Input System)
float xOffset = xThrow * Time.deltaTime * moveFactor;
float yOffset = yThrow * Time.deltaTime * moveFactor;
float rawXPos = transform.localPosition.x + xOffset;
float rawYPos = transform.localPosition.y + yOffset;
float clampedXPos = Mathf.Clamp(rawXPos, -xRange, xRange);
float clampedYPos = Mathf.Clamp(rawYPos, -yRange + yRangeOffset, yRange + yRangeOffset);
transform.localPosition = new Vector3(clampedXPos, clampedYPos, transform.localPosition.z);
}
void ProcessRotation() // Processes Pitch/Yaw/Roll of the ship
{
xLerpThrow = Mathf.Lerp(-rollRotation, rollRotation, tForRollLerp);
yLerpThrow = Mathf.Lerp(-pitchRotation, pitchRotation, tForPitchLerp);
float pitchDueToPosition = transform.localPosition.y * positionPitchFactor;
float pitchDueToControlThrow = yLerpThrow * controlPitchFactor;
float pitch = pitchDueToPosition + pitchDueToControlThrow;
float yaw = transform.localPosition.x * positionYawFactor;
float roll = xLerpThrow * controlRollFactor;
transform.localRotation = Quaternion.Euler(pitch, yaw, roll);
// Lerp smooth movement code begins here
if (xThrow > 0)
tForRollLerp = Mathf.Max(0, tForRollLerp - rotationLerpIncrement * Time.deltaTime);
else if (xThrow < 0)
tForRollLerp = Mathf.Min(1, tForRollLerp + rotationLerpIncrement * Time.deltaTime);
else
if (tForRollLerp > 0.5)
tForRollLerp = Mathf.Max(0.5f, tForRollLerp - rotationLerpIncrement * Time.deltaTime);
else if (tForRollLerp < 0.5)
tForRollLerp = Mathf.Min(0.5f, tForRollLerp + rotationLerpIncrement * Time.deltaTime);
if (yThrow > 0)
tForPitchLerp = Mathf.Max(0, tForPitchLerp - rotationLerpIncrement * Time.deltaTime);
else if (yThrow < 0)
tForPitchLerp = Mathf.Min(1, tForPitchLerp + rotationLerpIncrement * Time.deltaTime);
else
if (tForPitchLerp > 0.5)
tForPitchLerp = Mathf.Max(0.5f, tForPitchLerp - rotationLerpIncrement * Time.deltaTime);
else if (tForPitchLerp < 0.5)
tForPitchLerp = Mathf.Min(0.5f, tForPitchLerp + rotationLerpIncrement * Time.deltaTime);
}
}
This is my first attempt at posting code (and my first forum post at that ) so I hope it’s not too long. I basically used xThrow and yThrow only as toggles in the ProcessRotation function, then used Mathf.Lerp to increment from (psudo-code) -pitch/roll to +pitch/roll with the t increment of Mathf.Lerp being at “rest” at 0.5. I created a small sandbox scene in my ship world to test this out, rotating a cube in one direction to a maximum and then having it rotate back to rest when the key was no longer pressed, and then plugged the code into the main script for my ship.
Now, the obvious problem with all this will be that if someone were to plug a controller in to fly my ship, there’s no code to differentiate between keyboard and thumbstick input. So moving the thumbstick only a little would have the correct effect on movement (since xThrow/yThrow will be a number between 0 and 1) but the ship, no matter how slow it’s moving, will rotate to maximum in either direction. …but this is a shortcoming for another day when I’m working on something serious. At the present, it was a good exercise in learning and using Mathf.Lerp (though it still baffles me a bit) and is outside the scope of the assignment.
Anyway, hope that helps (rather than just confusing things). If it doesn’t help… then… erm… back to you, Nina