Player direction and motion input #432
Replies: 1 comment 1 reply
-
Read the topic. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have been using phantom camera for a while now, and i've been struggling with some issues when dealing with analog controls with a game with various cameras on a 3D environment, much like the classic Resident Evil games and Devil May Cry 3, or even Metal Gear Solid 2.
As it stands right now, the direction that my player character goes depends on the direction of the current camera. The player gets the direction through the Main Camera 3D node through an @export variable, and applies that direction in the player movement :
It works well most of the time, except in two instances :
1- When a camera is facing the ground, the player dramatically loses speed whenever it reaches the center of the direction of the game, rendering him nearly immobile ;
2- And most aggravating of all to players, whenever there are two cameras with opposing directions that connect WITHOUT any smoothing, as in, with a tween of 0, if players keep pressing the move_forward button, characters get stuck in a "loop" where they go back and forth, and i'll explain what is happening.
When a player enters a new camera, the new direction is fed to the player. This causes the direction to immediately update. If players were pressing forward with a camera facing north, and then suddenly pass through a camera that is facing south, the direction of "forward" immediately changes as well, causing the players to go south, getting stuck in an endless loop, lest they stop pressing forward and walk carefully in order to not get mixed up.
Now, this problem isn't new, and games dealt with this in at least two ways that i know :
1- Use tank controls : Where the direction of the player depends on the model's direction. So, if the player model is facing south, pressing "forward" causes the player to move south, even if the camera is pointing "north."
2- Introduce a grace period : Seen in Devil May Cry 3, if you keep pressing the movement button and don't let go, the direction of the old camera will still apply, until you let go, then it updates the direction with the current camera. I think i'm looking to implement this solution, as i would like to keep analog controls nice and snappy instead of having to control the player like a car. This solution also enables the player to keep moving throughout an environment with many cameras without getting too confused.
So i'm looking for possible solutions and implementations.
It's also important to say that the direction is fed through the process function.
Extra problem : How can i make the "follow" camera collide with walls? I tried using using the third person camera but for some reason the raycast was janky and it would automatically look away from the look-at target when i set it to that.
EDIT : I've found a solution a while ago where i only update the cam_direction when the player isn't moving :
if (Input.is_action_pressed("forward") || Input.is_action_pressed("backward") || Input.is_action_pressed("left") || Input.is_action_pressed("right")) and !Game.typing:
[...]
direction = direction = (cam_dir * direction.z + cam_right * direction.x)
else:
is_moving = false
cam_dir: Vector3 = -_camera.global_transform.basis.z
cam_right: Vector3 = -_camera.global_transform.basis.x
However, movement feels a little janky now. And i think i figured out why:
Before, movement felt smoother because the direction of the camera was updated in real time. Now, it's updating whenever the player stops moving, which can be a problem for "look-at" cameras because they're always looking at the player, and therefore, changing direction. Wow.
I guess the best solution would be to keep an option to also update the direction if the player doesn't move in a continuous manner, as in, if the player rotates at all, which i'm gonna be working through as the next step.
Or maybe another way would be to check if the current camera is looking at target(s) and if it is, then it could rapidly update
EDIT 2 : Fixed it. Here's my solution :
var last_input_angle : float
var current_input_angle : float
var angle_tolerance : float = 30.0
physics process :
Beta Was this translation helpful? Give feedback.
All reactions