netfishing/player/net_attachment.gd

88 lines
2.7 KiB
GDScript

extends "res://player/tool_socket_attachment.gd"
const TextureSamplingPolicyScript := preload(
"res://main/texture_sampling_policy.gd"
)
const SPRING_ROOT_BONE: StringName = &"net_mid"
const SPRING_END_BONE: StringName = &"net_tip"
const IMPACT_BONE: StringName = &"net_rim"
@export_range(0.0, 10.0, 0.05) var spring_stiffness: float = 1.8
@export_range(0.0, 1.0, 0.01) var spring_drag: float = 0.68
@export_range(0.0, 10.0, 0.05) var spring_gravity: float = 0.3
@export_range(0.01, 0.5, 0.01) var spring_end_length: float = 0.1
@onready var _catching_net: Node3D = %CatchingNet
@onready var _net_model: Node3D = %NetModel
var _spring: SpringBoneSimulator3D
var _spring_was_visible: bool = false
var _net_skeleton: Skeleton3D
func _ready() -> void:
super._ready()
TextureSamplingPolicyScript.enforce_subtree(_net_model)
_configure_spring()
_sync_spring_activity()
func _process(_delta: float) -> void:
_sync_spring_activity()
func _configure_spring() -> void:
_net_skeleton = _net_model.find_child(
"Skeleton3D", true, false
) as Skeleton3D
if _net_skeleton == null:
push_error("Imported net model is missing its Skeleton3D.")
return
if _net_skeleton.find_bone(SPRING_ROOT_BONE) < 0:
push_error("Imported net model is missing bone %s." % SPRING_ROOT_BONE)
return
if _net_skeleton.find_bone(SPRING_END_BONE) < 0:
push_error("Imported net model is missing bone %s." % SPRING_END_BONE)
return
if _net_skeleton.find_bone(IMPACT_BONE) < 0:
push_error("Imported net model is missing bone %s." % IMPACT_BONE)
return
_spring = SpringBoneSimulator3D.new()
_spring.name = "NetSpring"
_spring.set_setting_count(1)
_spring.set_root_bone_name(0, SPRING_ROOT_BONE)
_spring.set_end_bone_name(0, SPRING_END_BONE)
_spring.set_extend_end_bone(0, true)
_spring.set_end_bone_direction(
0, SkeletonModifier3D.BONE_DIRECTION_FROM_PARENT
)
_spring.set_end_bone_length(0, spring_end_length)
_spring.set_stiffness(0, spring_stiffness)
_spring.set_drag(0, spring_drag)
_spring.set_gravity(0, spring_gravity)
_spring.set_gravity_direction(0, Vector3.DOWN)
_net_skeleton.add_child(_spring)
func get_impact_world_position() -> Vector3:
if _net_skeleton == null:
return _catching_net.global_position
var impact_bone_index := _net_skeleton.find_bone(IMPACT_BONE)
if impact_bone_index < 0:
return _catching_net.global_position
return _net_skeleton.global_transform * (
_net_skeleton.get_bone_global_pose(impact_bone_index).origin
)
func _sync_spring_activity() -> void:
if _spring == null:
return
var is_visible := _catching_net.is_visible_in_tree()
if is_visible and not _spring_was_visible:
_spring.active = true
_spring.reset()
elif not is_visible:
_spring.active = false
_spring_was_visible = is_visible