If your ship movement is jerky/snappy in Argon Assault

Watching Rick’s ship movement versus mine I realized my ship was snapping between pitch/yaw/roll instead of the smooth movements his ship had. I checked the discussions and saw a few people notice the same thing but no real answer as to what was happening.

After some digging I found that this is the result of the new input system. The simple answer is that the old input system applies smoothing to the change in input by default while the new system does not. The quick fix is to switch back to the old system to get the smooth movements. If you want to stick with the new input system then @Arquoono posted a great solution using Lerp here.

It is possible to have jerky movements on one set of controls (up/down) and smooth on another (left/right) if you have both active and your project set to use both control methods. It all depends on whether your code references the old system (Input.GetAxis) or the new system (movement.ReadValue) with one being smooth and the other being jerky/snappy respectively.

@Nina It might be worth having a note added somewhere as Unity moves closer to making the new system the default.

2 Likes

Hi Jonathon,

Thanks a lot for sharing your solution. :slight_smile:

If Unity drops the old input system, our instructors will either update the respective videos or it will already be time for a new version of the course. You may rest assured that they keep an eye on the new input system and Unity’s decisions. :slight_smile:

Great post, thanks @Jonathon! I hadn’t realized that the old input system had automatic smoothing, so that was new info for me :slight_smile: I’m trying to learn the new input system, but have found that it’s a bit confusing (at least for this newbie :slight_smile: ) trying to learn it when the next sections still use the old, so I’ve stuck with the old system for Realm Rush and Zombie Runner. That (nearly) same Lerp routine also came in handy for Realm Rush if you want to add smooth turning for the enemies, so the code seems pretty flexible. Anyway, thanks again for that tidbit, and tagging me so I could see it :slight_smile:

Thanks @Arquoono and @Jonathon!
That was a great solution and made the gameplay much nicer, thank you.

1 Like

Hello devs,
here is a simpler solution to avoid snappy movement -

using System.Collections;
using System.Collections.Generic;
using System.Xml.Resolvers;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerControls : MonoBehaviour
{
    [SerializeField] InputAction movement;
    [SerializeField] float controlSpeed = 20f;

    [SerializeField] float xRange = 12f;
    [SerializeField] float yRange = 10f;
    
    [SerializeField] float positionPitchFactor = -2.0f;
    [SerializeField] float controlPitchFactor = -20f;

    [SerializeField] float positionYawFactor = 2.0f;
    [SerializeField] float controlRollFactor = -20f;

    [SerializeField] float lerpSpeed = 15f;
    
    float xThrow, yThrow;
    private void OnEnable()
    {
        movement.Enable();
    }

    private void OnDisable()
    {
        movement.Disable();
    }

    void Update()
    {
        ProcessTranslation();
        ProcessRotation();

    }

    private void ProcessRotation()
    {
        float pitch = ProcessPitch();
        float yaw = transform.localPosition.x * positionYawFactor;
        float roll = xThrow * controlRollFactor;
       // The part you are looking for
       // Quaternion.Lerp(fromLocation, toLocation, speed) this should give you a rough idea how it works
        Quaternion targetRotation = Quaternion.Euler(pitch, yaw, roll);
        transform.localRotation = Quaternion.Lerp(transform.localRotation, targetRotation, Time.deltaTime * lerpSpeed);
    }

    private float ProcessPitch()
    {
        float pitchDueToPosition = transform.localPosition.y * positionPitchFactor;
        float pitchDueToRotation = yThrow * controlPitchFactor;
        float pitch = pitchDueToPosition + pitchDueToRotation;
        return pitch;
    }

    private void ProcessTranslation()
    {
        float clampedXPos = ProcessXTranslation();
        float clampedYPos = ProcessYTranslation();
        transform.localPosition = new Vector3(clampedXPos, clampedYPos, transform.localPosition.z);

    }

    private float ProcessYTranslation()
    {
        yThrow = movement.ReadValue<Vector2>().y;
        float yOffset = yThrow * controlSpeed * Time.deltaTime;
        float rawYPos = transform.localPosition.y + yOffset;
        float clampedYPos = Mathf.Clamp(rawYPos, -yRange, yRange);
        return clampedYPos;
    }

    private float ProcessXTranslation()
    {
        xThrow = movement.ReadValue<Vector2>().x;
        float xOffset = xThrow * controlSpeed * Time.deltaTime;
        float rawXPos = transform.localPosition.x + xOffset;
        float clampedXPos = Mathf.Clamp(rawXPos, -xRange, xRange);
        return clampedXPos;
    }
}

PS - This is my first ever post here, suggestions are really appreciated, thank you:)

2 Likes

Much less complicated than any other solutions I just saw and this one make sense more to me as it uses local rotation.

Privacy & Terms