Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Godot 4 FPS Support #51

Open
aladvs opened this issue Jan 4, 2024 · 5 comments
Open

Godot 4 FPS Support #51

aladvs opened this issue Jan 4, 2024 · 5 comments

Comments

@aladvs
Copy link

aladvs commented Jan 4, 2024

When using the 3d smoothing node on the head of my character, it works really well to smooth the movement instead of jittering at physics speed. The problem is :

Camera rotation is not updated in physics ticks!

When using a smoothing node before the camera, then rotations are smoothed rather than keeping their updated values between physics frames.

When disabling 'basis' on the smoothing node, rotation will not update with the parents, removing rotation altogether.

This makes setting up an FPS controller that doesn't have jitter very complicated.

@aladvs
Copy link
Author

aladvs commented Jan 4, 2024

A simple fix to this issue would be adding a new parameter called something like "keep previous transform". This allows rotation and scale of the node to be edited, while still not affecting any things that are enabled.

Under process, it would be

func _process(_delta):

	var f = Engine.get_physics_interpolation_fraction()
	var tr: Transform3D
	if SF_KEEPTRANSFORM:
		tr = transform
	else:
		tr = Transform3D()

instead of:

func _process(_delta):

	var f = Engine.get_physics_interpolation_fraction()
	var tr: Transform3D = Transform3D()

@lawnjelly
Copy link
Owner

lawnjelly commented Jan 4, 2024

I discuss this in this video for the core interpolation in 3.x:
https://www.youtube.com/watch?v=BJgDCISku_o&t=126s

For FPS camera and the addon, sometimes it can be better to keep the camera on a separate branch to the player, and manually interpolating in global space. Attaching the camera as a child of a (basis) smoothed player visual rep won't work well as you say, because the smoothed basis will likely be inherited from the parent, unless you turn off basis interpolation.

Typically in FPS you'd want to drive the rotation of the player (rather than the camera directly) using the mouse, so if you turn off basis interpolation in the player, and just alter the yaw of the player directly using the mouse (and thus inherited by a camera child) this may work for you. The pitch on the other hand might be applied directly to the camera, so the player rep is always level but the camera looks up and down. The exact setup depends on the nature of your game / camera.

@aladvs
Copy link
Author

aladvs commented Jan 4, 2024

That is correct, but it does allow for some more freedom. With this approach, my "Player" node can stay as a CharacterBody3D, which allows positional
smoothing without smoothing its rotation, allowing for exact control over the camera.

@lawnjelly
Copy link
Owner

Ah sorry, I get what you mean. This may well be an oversight on my part, will look into it when I get a moment. 👍 😃

@bryanmylee
Copy link

I've managed to solve this problem by modifying the addon. Since my player is translated on the physics tick but rotated on the process tick, I needed a way to selectively apply interpolation on a per-property basis. To do so, I made this change:

func _process(_delta):

	var f = Engine.get_physics_interpolation_fraction()
	var tr: Transform3D = Transform3D()

	# translate
	if _TestFlags(SF_TRANSLATE):
		var ptDiff = _m_trCurr.origin - _m_trPrev.origin
		tr.origin = _m_trPrev.origin + (ptDiff * f)
+	else:
+		tr.origin = _m_Target.global_transform.origin

	# rotate
	if _TestFlags(SF_BASIS):
		if _TestFlags(SF_SLERP):
			tr.basis = _m_trPrev.basis.slerp(_m_trCurr.basis, f)
		else:
			tr.basis = _LerpBasis(_m_trPrev.basis, _m_trCurr.basis, f)
+	else:
+		tr.basis = _m_Target.global_transform.basis

	transform = tr

I'm not sure if this was the intention initially, but disabling the basis or translate flag OOTB causes the transform to never be applied at all. With the change, I can configure the smoothing node to only interpolate translate but leave basis as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants