mirror of
https://codeberg.org/sunder/sunder.git
synced 2026-07-11 20:14:35 +00:00
controller cleanup
This commit is contained in:
parent
dba1bd1b6b
commit
f2a761c277
13 changed files with 1730 additions and 227 deletions
|
|
@ -19,6 +19,8 @@ dest_files=["res://.godot/imported/Particle01.png-91f92696ba4d647b684a91370e6d49
|
|||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -26,6 +28,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ dest_files=["res://.godot/imported/smoke_01.png-37c016a5a51c2cceaf682437fe75284f
|
|||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -26,6 +28,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ dest_files=["res://.godot/imported/smoke_02.png-60fd959f44b7825f3153061fdb667fe7
|
|||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -26,6 +28,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/smoke_05.png-2f5c9b30713a43c1f15c13e2ffc2abef
|
|||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/smoke_06.png-a3676bce06542e67baa5c4b1c38f48cd
|
|||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,8 @@ dest_files=["res://.godot/imported/vanguard_0.png-7e4d2faeb963c948822713a4215f97
|
|||
compress/mode=2
|
||||
compress/high_quality=true
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
|
|
@ -27,6 +29,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ dest_files=["res://.godot/imported/vanguard_1.png-bd95dbe9f4f4b9a674d90ae4deb4a8
|
|||
compress/mode=2
|
||||
compress/high_quality=true
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=1
|
||||
compress/channel_pack=0
|
||||
|
|
@ -27,6 +29,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal="res://entities/player/assets/vanguard_1.png"
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ dest_files=["res://.godot/imported/vanguard_2.png-369246b9d40329f77c1e8edd517f47
|
|||
compress/mode=2
|
||||
compress/high_quality=true
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=1
|
||||
compress/channel_pack=0
|
||||
|
|
@ -27,6 +29,10 @@ mipmaps/generate=true
|
|||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal="res://entities/player/assets/vanguard_2.png"
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
|
|
|||
BIN
scenes/entities/player/assets/vanguard_mesh.res
Normal file
BIN
scenes/entities/player/assets/vanguard_mesh.res
Normal file
Binary file not shown.
BIN
scenes/entities/player/assets/vanguard_visor.res
Normal file
BIN
scenes/entities/player/assets/vanguard_visor.res
Normal file
Binary file not shown.
|
|
@ -85,11 +85,10 @@ var control_states:Queue
|
|||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func req_loadout(idx:int = 0) -> void:
|
||||
prints("req_loadout", multiplayer.get_remote_sender_id(), multiplayer.get_unique_id(), idx)
|
||||
inventory.clear()
|
||||
if is_multiplayer_authority():
|
||||
# spawn new weapons
|
||||
prints("req_loadout", self, idx)
|
||||
pass
|
||||
|
||||
func _ready() -> void:
|
||||
input.set_multiplayer_authority(peer_id)
|
||||
|
|
@ -136,13 +135,9 @@ func _physics_process(_delta:float) -> void:
|
|||
if not is_alive():
|
||||
return
|
||||
|
||||
func apply_inputs(sample:Variant) -> void:
|
||||
func apply_inputs(sample:Variant, delta:float) -> void:
|
||||
if not sample: return
|
||||
#if OS.is_debug_build():
|
||||
#prints("%s:" % multiplayer.get_unique_id(), "apply Player(%s) input" % peer_id, sample)
|
||||
|
||||
var local_direction:Vector3 = pivot.global_transform.basis * sample.direction
|
||||
# handle jetpack
|
||||
if sample.jetting and energy.value > 0 and not jetpack.stuttering:
|
||||
apply_force(mass * (Vector3.UP * (gravity + jetpack.vertical_acceleration) + local_direction * jetpack.horizontal_acceleration))
|
||||
|
||||
|
|
@ -165,11 +160,14 @@ func apply_inputs(sample:Variant) -> void:
|
|||
if slope_angle <= max_floor_angle:
|
||||
# retrieve normalized projection of local direction on tangent plane to normal
|
||||
var tangential_direction := (local_direction - normal * local_direction.dot(normal)).normalized()
|
||||
var target_velocity := tangential_direction * ground_speed
|
||||
var target_force:Vector3 = mass * (target_velocity - linear_velocity) / get_physics_process_delta_time()
|
||||
# @TODO: smooth acceleration
|
||||
var factor := travel_acceleration_curve.sample(1.)
|
||||
apply_force(target_force * factor)
|
||||
var target_velocity := (tangential_direction * ground_speed) - linear_velocity
|
||||
# acceleration limiter
|
||||
var accel_time := .1
|
||||
var max_change := (ground_speed / accel_time) * delta
|
||||
if target_velocity.length() > max_change:
|
||||
target_velocity = target_velocity.normalized() * max_change
|
||||
apply_central_force(mass * target_velocity / delta)
|
||||
|
||||
if _jumping:
|
||||
apply_central_impulse(basis.y * mass * sqrt(2 * gravity * jump_height))
|
||||
_jumping = false
|
||||
|
|
@ -187,12 +185,10 @@ func new_state(control_state:Dictionary) -> void:
|
|||
var back:Dictionary = control_states.back()
|
||||
# drop late control states
|
||||
if control_state.id < back.id:
|
||||
prints("%s: new state (dropped)" % multiplayer.get_unique_id(), control_state, back, peer_id, self)
|
||||
return
|
||||
prints("%s: new state" % multiplayer.get_unique_id(), control_state, peer_id, self)
|
||||
control_states.enqueue(control_state)
|
||||
|
||||
func replay_inputs(from:int) -> void:
|
||||
func replay_inputs(from:int, delta:float) -> void:
|
||||
# reset local_predictions since this node needs to resync, past predictions are wrong
|
||||
local_predictions = Queue.new()
|
||||
# reapply unacknowledged inputs if any
|
||||
|
|
@ -200,17 +196,14 @@ func replay_inputs(from:int) -> void:
|
|||
for i in range(input.history.size()):
|
||||
var sample:Dictionary = input.history.dequeue()
|
||||
if sample.id > from:
|
||||
prints("replaying from", from, sample)
|
||||
input.history.enqueue(sample)
|
||||
apply_inputs(sample)
|
||||
apply_inputs(sample, delta)
|
||||
var state := PhysicsServer3D.body_get_direct_state(get_rid())
|
||||
state.integrate_forces()
|
||||
# regenerate predictions
|
||||
local_predictions.enqueue(get_state(sample.id))
|
||||
prints("local state is now", local_predictions.back())
|
||||
|
||||
func reconcile(prediction:Dictionary, control:Dictionary) -> void:
|
||||
prints("reconcile", prediction, control)
|
||||
func reconcile(prediction:Dictionary, control:Dictionary, delta:float) -> void:
|
||||
var sigma:float = .05
|
||||
var resync := [
|
||||
(prediction.state[0] - control.state[0]).length() > sigma,
|
||||
|
|
@ -226,8 +219,7 @@ func reconcile(prediction:Dictionary, control:Dictionary) -> void:
|
|||
pivot.global_rotation.y = control.state[2].y # same as spring arm
|
||||
|
||||
if resync.max():
|
||||
prints("resync", resync)
|
||||
replay_inputs(control.id)
|
||||
replay_inputs(control.id, delta)
|
||||
|
||||
func get_state(id:int) -> Dictionary:
|
||||
return {
|
||||
|
|
@ -241,15 +233,14 @@ var last_control := 0
|
|||
func _integrate_forces(state:PhysicsDirectBodyState3D) -> void:
|
||||
if not is_alive():
|
||||
return
|
||||
#prints("%s:"%multiplayer.get_unique_id(), "tick", Engine.get_physics_frames(), "Player(%s)" % peer_id)
|
||||
if is_pawn():
|
||||
# local prediction for pawns
|
||||
var sample:Dictionary = input.sample()
|
||||
if multiplayer.is_server():
|
||||
apply_inputs(sample)
|
||||
apply_inputs(sample, state.step)
|
||||
else:
|
||||
input.history.enqueue(sample)
|
||||
apply_inputs(sample)
|
||||
apply_inputs(sample, state.step)
|
||||
local_predictions.enqueue(get_state(sample.id))
|
||||
if not control_states.is_empty():
|
||||
var prediction:Dictionary = local_predictions.front()
|
||||
|
|
@ -261,7 +252,7 @@ func _integrate_forces(state:PhysicsDirectBodyState3D) -> void:
|
|||
prediction = local_predictions.dequeue()
|
||||
if prediction.id == control.id:
|
||||
prints("%s:" % multiplayer.get_unique_id(), "B", prediction.id, control.id)
|
||||
reconcile(prediction, control)
|
||||
reconcile(prediction, control, state.step)
|
||||
else:
|
||||
prints("%s:" % multiplayer.get_unique_id(), "B no prediction / control match, wait for next control state")
|
||||
else:
|
||||
|
|
@ -270,33 +261,11 @@ func _integrate_forces(state:PhysicsDirectBodyState3D) -> void:
|
|||
# make sure synchronized inputs are processed once
|
||||
if sample.id != last_sent_state:
|
||||
last_sent_state = sample.id
|
||||
apply_inputs(sample)
|
||||
apply_inputs(sample, state.step)
|
||||
spring_arm.rotation.x = input.rotation.x
|
||||
pivot.rotation.y = input.rotation.y
|
||||
new_state.rpc(get_state(sample.id))
|
||||
|
||||
#if not (local_predictions.is_empty() or control_states.is_empty()):
|
||||
#var prediction:Dictionary = local_predictions.front()
|
||||
#var control:Dictionary = control_states.front()
|
||||
#prints("A", prediction.id, control.id)
|
||||
## dequeue predictions until we match most fresh control state
|
||||
#while prediction.id != control.id:
|
||||
#if local_predictions.is_empty():
|
||||
#break
|
||||
#prediction = local_predictions.dequeue()
|
||||
#if prediction.id == control.id:
|
||||
#reconcile(prediction, control)
|
||||
#prints("B", prediction.id, control.id)
|
||||
#else:
|
||||
#prints("B no prediction / control match, wait for next control state")
|
||||
|
||||
#else:
|
||||
#if multiplayer.is_server():
|
||||
#var sample:Dictionary = input.sample()
|
||||
#apply_inputs(sample)
|
||||
#new_state.rpc(get_state(sample.id))
|
||||
|
||||
|
||||
func apply_state(control:Dictionary, do_rotate:bool = false) -> void:
|
||||
global_position = control.state[0]
|
||||
# apply central force to reach control state velocity
|
||||
|
|
@ -304,7 +273,6 @@ func apply_state(control:Dictionary, do_rotate:bool = false) -> void:
|
|||
if do_rotate:
|
||||
spring_arm.global_rotation.x = control.state[2].x
|
||||
pivot.global_rotation.y = control.state[2].y # same as spring arm
|
||||
prints("apply_state", global_position, control.state[0])
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if is_pawn() and event.is_action("pov") and event.pressed and not event.echo:
|
||||
|
|
@ -324,11 +292,11 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||
|
||||
func _animate_third_person() -> void:
|
||||
if not is_alive():
|
||||
mesh.animation_tree.set("parameters/transition/transition_request", &"dead")
|
||||
mesh.animation_tree.set("parameters/transition/transition_request", "dead")
|
||||
return
|
||||
|
||||
if is_on_floor():
|
||||
#mesh.animation_tree.set("parameters/transition/transition_request", &"grounded")
|
||||
mesh.animation_tree.set("parameters/transition/transition_request", "grounded")
|
||||
if input.skiing:
|
||||
mesh.animation_tree.set("parameters/locomotion/blend_position", Vector2.ZERO)
|
||||
mesh.animation_tree.set("parameters/mix/blend_amount", .0)
|
||||
|
|
@ -341,7 +309,7 @@ func _animate_third_person() -> void:
|
|||
var blend:float = mesh.animation_tree["parameters/mix/blend_amount"]
|
||||
mesh.animation_tree.set("parameters/mix/blend_amount", lerp(blend, input.direction.length(), .5))
|
||||
else:
|
||||
mesh.animation_tree.set("parameters/transition/transition_request", &"mid_air")
|
||||
mesh.animation_tree.set("parameters/transition/transition_request", "mid_air")
|
||||
|
||||
## This method returns wether the local system multiplayer peer has input authority over this node
|
||||
func is_pawn() -> bool:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue