Add casting animation phases and stabilize held rod
This commit is contained in:
parent
9e6536adcd
commit
ff536e62a6
5 changed files with 97 additions and 13 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -363,15 +363,15 @@ func handle_escape_action() -> bool:
|
||||||
|
|
||||||
|
|
||||||
func set_local_menu_input_suppressed(
|
func set_local_menu_input_suppressed(
|
||||||
owner: StringName,
|
input_owner: StringName,
|
||||||
suppressed: bool,
|
suppressed: bool,
|
||||||
) -> void:
|
) -> void:
|
||||||
if owner.is_empty():
|
if input_owner.is_empty():
|
||||||
return
|
return
|
||||||
if suppressed:
|
if suppressed:
|
||||||
_local_menu_input_owners[owner] = true
|
_local_menu_input_owners[input_owner] = true
|
||||||
else:
|
else:
|
||||||
_local_menu_input_owners.erase(owner)
|
_local_menu_input_owners.erase(input_owner)
|
||||||
if suppressed and state == FishingState.WAITING_FOR_BITE:
|
if suppressed and state == FishingState.WAITING_FOR_BITE:
|
||||||
_withdrawal_input_held = false
|
_withdrawal_input_held = false
|
||||||
_stop_reeling_audio()
|
_stop_reeling_audio()
|
||||||
|
|
@ -627,6 +627,7 @@ func _begin_aiming(player: PlayerType) -> void:
|
||||||
_cast_charge = 0.0
|
_cast_charge = 0.0
|
||||||
_cast_target = _calculate_cast_target(minimum_cast_distance)
|
_cast_target = _calculate_cast_target(minimum_cast_distance)
|
||||||
state = FishingState.AIMING_CAST
|
state = FishingState.AIMING_CAST
|
||||||
|
_active_player.set_casting_visual()
|
||||||
status_changed.emit("")
|
status_changed.emit("")
|
||||||
_cast_path_is_clear = is_cast_path_clear(
|
_cast_path_is_clear = is_cast_path_clear(
|
||||||
_get_cast_launch_position(),
|
_get_cast_launch_position(),
|
||||||
|
|
@ -813,6 +814,8 @@ func _confirm_cast() -> void:
|
||||||
# released so the active bobber/fishing event remains anchored.
|
# released so the active bobber/fishing event remains anchored.
|
||||||
_active_player.set_movement_enabled(false)
|
_active_player.set_movement_enabled(false)
|
||||||
state = FishingState.CASTING
|
state = FishingState.CASTING
|
||||||
|
if _active_player != null:
|
||||||
|
_active_player.set_release_visual()
|
||||||
status_changed.emit("")
|
status_changed.emit("")
|
||||||
_presentation.begin_cast(
|
_presentation.begin_cast(
|
||||||
_cast_target,
|
_cast_target,
|
||||||
|
|
@ -1102,7 +1105,7 @@ func _on_catch_encounter_updated(
|
||||||
barrier_health: PackedInt32Array,
|
barrier_health: PackedInt32Array,
|
||||||
barrier_max_health: PackedInt32Array,
|
barrier_max_health: PackedInt32Array,
|
||||||
active_barrier_index: int,
|
active_barrier_index: int,
|
||||||
visible: bool,
|
encounter_visible: bool,
|
||||||
) -> void:
|
) -> void:
|
||||||
catch_display_changed.emit(
|
catch_display_changed.emit(
|
||||||
progress,
|
progress,
|
||||||
|
|
@ -1111,9 +1114,9 @@ func _on_catch_encounter_updated(
|
||||||
barrier_health,
|
barrier_health,
|
||||||
barrier_max_health,
|
barrier_max_health,
|
||||||
active_barrier_index,
|
active_barrier_index,
|
||||||
visible
|
encounter_visible
|
||||||
)
|
)
|
||||||
if state != FishingState.FIGHTING or not visible:
|
if state != FishingState.FIGHTING or not encounter_visible:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ func show_cast(origin: Vector3, target: Vector3) -> void:
|
||||||
_bobber.visible = true
|
_bobber.visible = true
|
||||||
_line.visible = true
|
_line.visible = true
|
||||||
_owner.set_active_item_is_rod(true)
|
_owner.set_active_item_is_rod(true)
|
||||||
|
_owner.set_release_visual()
|
||||||
_redraw_line()
|
_redraw_line()
|
||||||
_cast_tween = create_tween()
|
_cast_tween = create_tween()
|
||||||
_cast_tween.set_trans(Tween.TRANS_SINE)
|
_cast_tween.set_trans(Tween.TRANS_SINE)
|
||||||
|
|
@ -99,6 +100,7 @@ func show_bite() -> void:
|
||||||
func play_return(showcase_catch: FishCatch = null) -> void:
|
func play_return(showcase_catch: FishCatch = null) -> void:
|
||||||
if _owner != null and is_instance_valid(_owner):
|
if _owner != null and is_instance_valid(_owner):
|
||||||
_owner.set_fighting_visual(false)
|
_owner.set_fighting_visual(false)
|
||||||
|
_owner.set_fishing_visual(false)
|
||||||
if not _active or _bobber == null:
|
if not _active or _bobber == null:
|
||||||
cleanup()
|
cleanup()
|
||||||
return_completed.emit()
|
return_completed.emit()
|
||||||
|
|
@ -135,6 +137,7 @@ func cleanup() -> void:
|
||||||
_bobber_idle_elapsed = 0.0
|
_bobber_idle_elapsed = 0.0
|
||||||
if _owner != null and is_instance_valid(_owner):
|
if _owner != null and is_instance_valid(_owner):
|
||||||
_owner.set_fighting_visual(false)
|
_owner.set_fighting_visual(false)
|
||||||
|
_owner.set_fishing_visual(false)
|
||||||
_owner.end_catch_showcase(Callable(), true)
|
_owner.end_catch_showcase(Callable(), true)
|
||||||
if _bobber != null:
|
if _bobber != null:
|
||||||
_bobber.visible = false
|
_bobber.visible = false
|
||||||
|
|
@ -162,6 +165,8 @@ func _set_cast_sample(
|
||||||
func _on_cast_finished() -> void:
|
func _on_cast_finished() -> void:
|
||||||
_cast_tween = null
|
_cast_tween = null
|
||||||
_bobber_idle_elapsed = 0.0
|
_bobber_idle_elapsed = 0.0
|
||||||
|
if _owner != null and is_instance_valid(_owner):
|
||||||
|
_owner.set_fishing_visual(true)
|
||||||
_apply_bobber_idle_motion()
|
_apply_bobber_idle_motion()
|
||||||
_redraw_line()
|
_redraw_line()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,19 @@ const CHARACTER_IDLE_SIT_ANIMATION: StringName = &"idle_sit"
|
||||||
const CHARACTER_IDLE_SIT_SHOW_ANIMATION: StringName = &"idle_sit_show"
|
const CHARACTER_IDLE_SIT_SHOW_ANIMATION: StringName = &"idle_sit_show"
|
||||||
const CHARACTER_WALKING_ANIMATION: StringName = &"walking"
|
const CHARACTER_WALKING_ANIMATION: StringName = &"walking"
|
||||||
const CHARACTER_WALKING_SHOW_ANIMATION: StringName = &"walking_show"
|
const CHARACTER_WALKING_SHOW_ANIMATION: StringName = &"walking_show"
|
||||||
|
const CHARACTER_CASTING_ANIMATION: StringName = &"casting"
|
||||||
|
const CHARACTER_RELEASE_ANIMATION: StringName = &"release"
|
||||||
const CHARACTER_FISHING_ANIMATION: StringName = &"fishing"
|
const CHARACTER_FISHING_ANIMATION: StringName = &"fishing"
|
||||||
const CHARACTER_FISHING_SIT_ANIMATION: StringName = &"fishing_sit"
|
const CHARACTER_FISHING_SIT_ANIMATION: StringName = &"fishing_sit"
|
||||||
const CHARACTER_FIGHTING_ANIMATION: StringName = &"fighting"
|
const CHARACTER_FIGHTING_ANIMATION: StringName = &"fighting"
|
||||||
const CHARACTER_FIGHTING_SIT_ANIMATION: StringName = &"fighting_sit"
|
const CHARACTER_FIGHTING_SIT_ANIMATION: StringName = &"fighting_sit"
|
||||||
|
|
||||||
|
enum FishingVisualPhase {
|
||||||
|
NONE,
|
||||||
|
CASTING,
|
||||||
|
RELEASE,
|
||||||
|
FISHING,
|
||||||
|
}
|
||||||
const FIGHTING_EYES_ID: String = "alligator_eyes"
|
const FIGHTING_EYES_ID: String = "alligator_eyes"
|
||||||
const BASE_REEL_SPEED: float = 0.16
|
const BASE_REEL_SPEED: float = 0.16
|
||||||
# The target Android handheld exposes its physical right trigger through
|
# The target Android handheld exposes its physical right trigger through
|
||||||
|
|
@ -121,9 +130,24 @@ func set_fighting_visual(active: bool) -> void:
|
||||||
|
|
||||||
|
|
||||||
func set_fishing_visual(active: bool) -> void:
|
func set_fishing_visual(active: bool) -> void:
|
||||||
if _fishing_visual_active == active:
|
_set_fishing_visual_phase(
|
||||||
|
FishingVisualPhase.FISHING if active else FishingVisualPhase.NONE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func set_casting_visual() -> void:
|
||||||
|
_set_fishing_visual_phase(FishingVisualPhase.CASTING)
|
||||||
|
|
||||||
|
|
||||||
|
func set_release_visual() -> void:
|
||||||
|
_set_fishing_visual_phase(FishingVisualPhase.RELEASE)
|
||||||
|
|
||||||
|
|
||||||
|
func _set_fishing_visual_phase(phase: FishingVisualPhase) -> void:
|
||||||
|
if _fishing_visual_phase == phase:
|
||||||
return
|
return
|
||||||
_fishing_visual_active = active
|
_fishing_visual_phase = phase
|
||||||
|
_fishing_visual_active = phase != FishingVisualPhase.NONE
|
||||||
_character_animation_name = &""
|
_character_animation_name = &""
|
||||||
_update_character_animation()
|
_update_character_animation()
|
||||||
|
|
||||||
|
|
@ -283,8 +307,12 @@ var _held_fish_visible: bool = false
|
||||||
var _showcase_animation_active: bool = false
|
var _showcase_animation_active: bool = false
|
||||||
var _fighting_visual_active: bool = false
|
var _fighting_visual_active: bool = false
|
||||||
var _fishing_visual_active: bool = false
|
var _fishing_visual_active: bool = false
|
||||||
|
var _fishing_visual_phase: FishingVisualPhase = FishingVisualPhase.NONE
|
||||||
var _fishing_rod: Node3D
|
var _fishing_rod: Node3D
|
||||||
var _fishing_rod_tip: Marker3D
|
var _fishing_rod_tip: Marker3D
|
||||||
|
var _fishing_rod_skeleton: Skeleton3D
|
||||||
|
var _fishing_rod_hand_bone: int = -1
|
||||||
|
var _fishing_rod_relative_basis: Basis = Basis.IDENTITY
|
||||||
var _controller_mapping_manager: ControllerMappingManagerType
|
var _controller_mapping_manager: ControllerMappingManagerType
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -334,6 +362,38 @@ func _initialize_fishing_rod() -> void:
|
||||||
_fishing_rod_tip = attachment.get_node(
|
_fishing_rod_tip = attachment.get_node(
|
||||||
"FishingRod/FishingRodTip"
|
"FishingRod/FishingRodTip"
|
||||||
) as Marker3D
|
) as Marker3D
|
||||||
|
_fishing_rod_skeleton = skeleton
|
||||||
|
_fishing_rod_hand_bone = skeleton.find_bone(&"hand.R")
|
||||||
|
if _fishing_rod_hand_bone < 0:
|
||||||
|
push_error("Player character right-hand bone is unavailable.")
|
||||||
|
return
|
||||||
|
_fishing_rod_relative_basis = (
|
||||||
|
skeleton.global_basis.orthonormalized().inverse()
|
||||||
|
* _fishing_rod.global_basis.orthonormalized()
|
||||||
|
)
|
||||||
|
_fishing_rod.top_level = true
|
||||||
|
_sync_fishing_rod_transform()
|
||||||
|
|
||||||
|
|
||||||
|
func _sync_fishing_rod_transform() -> void:
|
||||||
|
if (
|
||||||
|
_fishing_rod == null
|
||||||
|
or _fishing_rod_skeleton == null
|
||||||
|
or _fishing_rod_hand_bone < 0
|
||||||
|
):
|
||||||
|
return
|
||||||
|
var skeleton_transform := _fishing_rod_skeleton.global_transform
|
||||||
|
var hand_pose := _fishing_rod_skeleton.get_bone_global_pose(
|
||||||
|
_fishing_rod_hand_bone
|
||||||
|
)
|
||||||
|
var fixed_basis := (
|
||||||
|
skeleton_transform.basis.orthonormalized()
|
||||||
|
* _fishing_rod_relative_basis
|
||||||
|
)
|
||||||
|
_fishing_rod.global_transform = Transform3D(
|
||||||
|
fixed_basis.scaled(skeleton_transform.basis.get_scale().abs()),
|
||||||
|
(skeleton_transform * hand_pose).origin,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _initialize_held_item_attachment() -> void:
|
func _initialize_held_item_attachment() -> void:
|
||||||
|
|
@ -363,6 +423,7 @@ func _initialize_held_item_attachment() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
|
_sync_fishing_rod_transform()
|
||||||
if _network_interpolation_enabled:
|
if _network_interpolation_enabled:
|
||||||
_update_network_interpolation(delta)
|
_update_network_interpolation(delta)
|
||||||
return
|
return
|
||||||
|
|
@ -455,6 +516,7 @@ func _physics_process(delta: float) -> void:
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
_sync_fishing_rod_transform()
|
||||||
_update_character_animation()
|
_update_character_animation()
|
||||||
# The hand bone supplies the attachment position, but its animated wrist
|
# The hand bone supplies the attachment position, but its animated wrist
|
||||||
# rotation should not turn the flat fish/catch artwork edge-on. Keep each
|
# rotation should not turn the flat fish/catch artwork edge-on. Keep each
|
||||||
|
|
@ -588,10 +650,24 @@ func _update_character_animation() -> void:
|
||||||
&"idle_sit_loop",
|
&"idle_sit_loop",
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
requested_animation = [
|
match _fishing_visual_phase:
|
||||||
CHARACTER_FISHING_ANIMATION,
|
FishingVisualPhase.CASTING:
|
||||||
CHARACTER_IDLE_ANIMATION,
|
requested_animation = [
|
||||||
]
|
CHARACTER_CASTING_ANIMATION,
|
||||||
|
CHARACTER_FISHING_ANIMATION,
|
||||||
|
CHARACTER_IDLE_ANIMATION,
|
||||||
|
]
|
||||||
|
FishingVisualPhase.RELEASE:
|
||||||
|
requested_animation = [
|
||||||
|
CHARACTER_RELEASE_ANIMATION,
|
||||||
|
CHARACTER_FISHING_ANIMATION,
|
||||||
|
CHARACTER_IDLE_ANIMATION,
|
||||||
|
]
|
||||||
|
_:
|
||||||
|
requested_animation = [
|
||||||
|
CHARACTER_FISHING_ANIMATION,
|
||||||
|
CHARACTER_IDLE_ANIMATION,
|
||||||
|
]
|
||||||
elif _sitting:
|
elif _sitting:
|
||||||
if _held_fish_visible:
|
if _held_fish_visible:
|
||||||
requested_animation = [
|
requested_animation = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue