TransWikia.com

Unity - Smooth player input direction when changing camera

Game Development Asked by herewego on January 24, 2021

Preface- I’m very new to Unity.

I’m working on an exercise using fixed cameras like how they work in the PSX final fantasy games. I have the camera scripts working fine but it’s an aspect of the character control that I’m struggling with.

My character moves relative to the cameras facing position, but when the camera suddenly changes to another angle, my running direction instantly and abruptly changes too. In the final fantasy games it sort of keeps going roughly in the same direction you were briefly.

input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
input = Vector2.ClampMagnitude(input, 1);

// get camera direction
// need to add something here for in between camera switches! 
camF = Camera.main.transform.forward;
camR = Camera.main.transform.right;
camF.y = 0;
camR.y = 0;
camF = camF.normalized;
camR = camR.normalized;

transform.position += (camF * input.y + camR * input.x) * Time.deltaTime * 8;

I saw someone with a similar game comment on an article with his solution, but I don’t quite know how to put it into code. The quote;

"Player just gets a rotation based on where the camera is looking and multiplies the character’s motor force by that .forward and .right. I only update that rotation after a big delta in input so you can smoothly move between shots."

This is his small (online) game which he’s talking about, I’m trying to mimic the movement basically;
https://ocias.com/games/foggy-shore/

Can anyone give me some pointers?


Updated:

It doesn’t quite play how it does in the demo game, but it’s getting there.

    input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    input = Vector2.ClampMagnitude(input, 1);

    if (!cameraChanged) {
        _lastCameraInput = input;
        camF = Camera.main.transform.forward;
        camR = Camera.main.transform.right;
        camF.y = 0;
        camR.y = 0;
        camF = camF.normalized;
        camR = camR.normalized;
        
    } else if (Vector3.Dot(input, _lastCameraInput) <= -0f) {
        cameraChanged = false;
        }
    
    transform.position += (camF * input.y + camR * input.x) * Time.deltaTime * 8;

One Answer

Here's one potential implementation of this behaviour:

Quaternion _lastCameraFacing;
Vector2 _lastCameraInput;

void Start() {
    _lastCameraFacing = Camera.main.transform.rotation;
}

void Update() {
    var input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    input = Vector2.ClampMagnitude(input, 1);

    var cameraFacing = Camera.main.transform.rotation;
    // If our camera angle has changed abruptly, 
    // store our current input to compare against in future frames.
    if (Quaternion.Angle(cameraFacing, _lastCameraFacing) > 30f) {
        _lastCameraInput = input;
    } else if (Vector3.Dot(input, _lastCameraInput) <= 0f) {
        // If we let go of the stick, or turn 90+ degrees,
        // switch to using the latest camera angle.
        _lastCameraFacing = cameraFacing;
    }

    // Keep using the saved camera angle for movement.
    var camF = _lastCameraFacing * Vector3.forward;
    var camR = _lastCameraFacing * Vector3.right;
    camF.y = 0;
    camR.y = 0;

    camF = camF.normalized;
    camR = camR.normalized;

    transform.position += (camF * input.y + camR * input.x) * Time.deltaTime * 8;
}

Answered by DMGregory on January 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP