Player script after implementing Half Sword mechanics:
extends CharacterBody3D
Настройки движения
const WALK_SPEED = 4.0
const SPRINT_SPEED = 6.5
const JUMP_FORCE = 8.0
const MOUSE_SENSITIVITY = 0.1
Настройки рук
const HAND_FOLLOW_SPEED = 8.0
const PUNCH_FORCE_MULTIPLIER = 80.0
Ноды
@onready var skeleton = $Skin/Skeleton3D
@onready var camera = $CameraPoint/Camera3D
@onready var left_hand_area = $Skin/Skeleton3D/LeftHandBone/LeftHandArea
@onready var right_hand_area = $Skin/Skeleton3D/RightHandBone/RightHandArea
Переменные
var current_hand_pos = Vector3.ZERO
var is_punching = false
var punch_start_pos = Vector2.ZERO
var mouse_velocity = Vector2.ZERO
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
setup_physical_bones()
func setup_physical_bones():
Создаем физические кости если их нет
if skeleton.get_child_count() == 0:
skeleton.create_physical_skeleton()
# Настраиваем только для рук
for bone in skeleton.get_children():
if bone is PhysicalBone3D and "Hand" in bone.name:
bone.gravity_scale = 0.2
bone.linear_damp = 4.0
bone.angular_damp = 4.0
bone.mass = 1.2
func _input(event):
if event is InputEventMouseMotion:
handle_camera_rotation(event)
mouse_velocity = event.relative
if event.is_action_pressed("left_click"):
start_punch(true)
elif event.is_action_pressed("right_click"):
start_punch(false)
elif event.is_action_released("left_click") or event.is_action_released("right_click"):
end_punch()
func handle_camera_rotation(event):
rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
camera.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-70), deg_to_rad(70))
func _physics_process(delta):
handle_movement(delta)
update_hands(delta)
move_and_slide()
func handle_movement(delta):
var input_dir = Input.get_vector("left", "right", "forward", "backward")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
var speed = SPRINT_SPEED if Input.is_action_pressed("sprint") else WALK_SPEED
velocity.x = direction.x * speed
velocity.z = direction.z * speed
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = JUMP_FORCE
if not is_on_floor():
velocity.y -= get_gravity() * delta
func update_hands(delta):
if is_punching:
update_punch()
else:
update_hands_idle(delta)
func update_hands_idle(delta):
var target_pos = Vector3(
mouse_velocity.x * 0.001,
-mouse_velocity.y * 0.001,
-0.3
)
current_hand_pos = current_hand_pos.lerp(target_pos, delta * HAND_FOLLOW_SPEED)
apply_hand_positions()
func start_punch(is_left):
is_punching = true
punch_start_pos = get_viewport().get_mouse_position()
if is_left:
left_hand_area.monitoring = true
else:
right_hand_area.monitoring = true
func update_punch():
var current_mouse_pos = get_viewport().get_mouse_position()
var punch_direction = (current_mouse_pos - punch_start_pos).normalized()
var punch_power = clamp(punch_direction.length() * 0.3, 0.2, 1.0)
current_hand_pos = Vector3(
punch_direction.x * punch_power,
-punch_direction.y * punch_power,
-0.2
)
apply_hand_positions()
func end_punch():
is_punching = false
left_hand_area.monitoring = false
right_hand_area.monitoring = false
mouse_velocity = Vector2.ZERO
func apply_hand_positions():
for hand in ["LeftHand", "RightHand"]:
var bone_id = skeleton.find_bone("mixamorig_" + hand)
if bone_id != -1:
skeleton.set_bone_pose_position(bone_id, current_hand_pos)
func _on_hand_area_body_entered(body):
if body.has_method("take_damage"):
var force_direction = -global_transform.basis.z
var force_strength = clamp(mouse_velocity.length() * 0.05, 5.0, 20.0)
body.take_damage(force_strength, force_direction)
