weapon ready/aiming done
This commit is contained in:
parent
ac3f0d73a6
commit
be47641bab
5 changed files with 208 additions and 26 deletions
|
@ -45,16 +45,54 @@ move_right={
|
|||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
look_up={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
look_down={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
look_left={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
look_right={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
run={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
interact={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
ready={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
fire={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
reload={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=30 format=3 uid="uid://crbrniwi6kd3p"]
|
||||
[gd_scene load_steps=36 format=3 uid="uid://crbrniwi6kd3p"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dpmbimh6m4ari" path="res://scenes/player_mesh.tscn" id="1_3vyb7"]
|
||||
[ext_resource type="Script" uid="uid://50vv0ta67tgl" path="res://src/player.gd" id="1_qhqgy"]
|
||||
|
@ -9,6 +9,9 @@
|
|||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_g2els"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_smehm"]
|
||||
animation = &"Aim"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tuyoq"]
|
||||
animation = &"PistolIdle"
|
||||
|
||||
|
@ -29,6 +32,9 @@ nodes/Blend2/node = SubResource("AnimationNodeBlend2_smehm")
|
|||
nodes/Blend2/position = Vector2(80, 120)
|
||||
node_connections = [&"Blend2", 0, &"Animation", &"Blend2", 1, &"Animation 2", &"output", 0, &"Blend2"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ur7pv"]
|
||||
animation = &"Fire"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_y4r1p"]
|
||||
animation = &"PistolIdle"
|
||||
|
||||
|
@ -43,12 +49,32 @@ advance_expression = "velocity"
|
|||
advance_mode = 2
|
||||
advance_expression = "not velocity"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_oprun"]
|
||||
advance_mode = 2
|
||||
advance_expression = "is_weapon_ready"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_a8ls1"]
|
||||
advance_mode = 2
|
||||
advance_expression = "is_firing"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_qfm1y"]
|
||||
switch_mode = 2
|
||||
advance_mode = 2
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_fulsm"]
|
||||
advance_mode = 2
|
||||
advance_expression = "not is_weapon_ready"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_d2wvv"]
|
||||
states/Aim/node = SubResource("AnimationNodeAnimation_smehm")
|
||||
states/Aim/position = Vector2(327, 194)
|
||||
states/BlendTree/node = SubResource("AnimationNodeBlendTree_ur7pv")
|
||||
states/BlendTree/position = Vector2(488, 100)
|
||||
states/Fire/node = SubResource("AnimationNodeAnimation_ur7pv")
|
||||
states/Fire/position = Vector2(462, 194)
|
||||
states/PistolIdle/node = SubResource("AnimationNodeAnimation_y4r1p")
|
||||
states/PistolIdle/position = Vector2(327, 100)
|
||||
transitions = ["Start", "PistolIdle", SubResource("AnimationNodeStateMachineTransition_ur7pv"), "PistolIdle", "BlendTree", SubResource("AnimationNodeStateMachineTransition_y4r1p"), "BlendTree", "PistolIdle", SubResource("AnimationNodeStateMachineTransition_d2wvv")]
|
||||
transitions = ["Start", "PistolIdle", SubResource("AnimationNodeStateMachineTransition_ur7pv"), "PistolIdle", "BlendTree", SubResource("AnimationNodeStateMachineTransition_y4r1p"), "BlendTree", "PistolIdle", SubResource("AnimationNodeStateMachineTransition_d2wvv"), "PistolIdle", "Aim", SubResource("AnimationNodeStateMachineTransition_oprun"), "Aim", "Fire", SubResource("AnimationNodeStateMachineTransition_a8ls1"), "Fire", "Aim", SubResource("AnimationNodeStateMachineTransition_qfm1y"), "Aim", "PistolIdle", SubResource("AnimationNodeStateMachineTransition_fulsm")]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_qhqgy"]
|
||||
animation = &"Idle"
|
||||
|
@ -72,7 +98,7 @@ advance_expression = "input.is_running"
|
|||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_qhqgy"]
|
||||
advance_mode = 2
|
||||
advance_expression = "not input.is_running"
|
||||
advance_expression = "not input.is_running or not velocity"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_dqkch"]
|
||||
advance_mode = 2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class_name Persistence extends Node
|
||||
|
||||
@export var path = "user://saves/data.sav"
|
||||
@export var path = "user://saves/"
|
||||
@export var group_name = "persist"
|
||||
|
||||
const SaveMethod = "on_save"
|
||||
|
@ -14,9 +14,12 @@ static func get_instance_data(node: Node):
|
|||
data = node.call(SaveMethod)
|
||||
}
|
||||
|
||||
func save() -> Result:
|
||||
func save(filename: String) -> Result:
|
||||
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
|
||||
var file = FileAccess.open(path, FileAccess.WRITE)
|
||||
var file_path = path.path_join(filename)
|
||||
if not file_path.is_valid_filename():
|
||||
return Result.err('invalid file path "%s"' % file_path)
|
||||
var file = FileAccess.open(file_path, FileAccess.WRITE)
|
||||
var nodes = get_tree().get_nodes_in_group(group_name)
|
||||
|
||||
for node in nodes:
|
||||
|
|
|
@ -6,23 +6,37 @@ class_name Player extends CharacterBody3D
|
|||
@onready var input = $Input
|
||||
@onready var interactor = $Interactor
|
||||
|
||||
var is_carrying_item = false
|
||||
var is_carrying_item = true
|
||||
var is_weapon_ready: bool:
|
||||
get: return is_carrying_item and input.is_weapon_ready
|
||||
|
||||
func _ready() -> void:
|
||||
input.connect("interact", _on_interact)
|
||||
input.connect('interact', _on_interact)
|
||||
input.connect('fire', _on_fire)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
move_and_rotate(delta)
|
||||
if is_weapon_ready:
|
||||
rotate_toward_look(delta)
|
||||
else:
|
||||
move_and_rotate(delta)
|
||||
|
||||
func move_and_rotate(_delta: float):
|
||||
var speed = run_speed if input.is_running else walk_speed
|
||||
velocity = input.next_velocity(speed)
|
||||
if !velocity.is_zero_approx():
|
||||
look_at(global_position + velocity, Vector3.UP, true)
|
||||
move_and_slide()
|
||||
var speed = run_speed if input.is_running else walk_speed
|
||||
velocity = input.next_velocity(speed)
|
||||
if !velocity.is_zero_approx():
|
||||
look_at(global_position + velocity, Vector3.UP, true)
|
||||
move_and_slide()
|
||||
|
||||
func rotate_toward_look(_delta: float):
|
||||
var target = input.get_look_target(global_position)
|
||||
if target.is_some():
|
||||
look_at(target.unwrap(), Vector3.UP, true)
|
||||
|
||||
func _on_interact():
|
||||
interactor.interact_nearest()
|
||||
func _on_fire():
|
||||
if is_weapon_ready:
|
||||
print('firing weapon')
|
||||
|
||||
func on_save():
|
||||
return {
|
||||
|
|
|
@ -1,10 +1,59 @@
|
|||
class_name PlayerInput extends Node
|
||||
|
||||
enum Device {
|
||||
Unknown,
|
||||
KeyboardMouse,
|
||||
Gamepad
|
||||
}
|
||||
|
||||
class Action:
|
||||
static var Run = 'run'
|
||||
static var Interact = 'interact'
|
||||
static var Ready = 'ready'
|
||||
static var Fire = 'fire'
|
||||
|
||||
signal walk
|
||||
signal run
|
||||
signal interact
|
||||
signal ready_weapon
|
||||
signal unready_weapon
|
||||
signal fire
|
||||
|
||||
var is_running: bool = false
|
||||
var is_interacting: bool = false
|
||||
var last_known_device: Device = Device.Unknown
|
||||
|
||||
var _is_running: bool = false
|
||||
var is_running: bool:
|
||||
get: return _is_running
|
||||
set(value):
|
||||
if _is_running != value:
|
||||
_is_running = value
|
||||
if value: run.emit()
|
||||
else: walk.emit()
|
||||
|
||||
var _is_interacting: bool = false
|
||||
var is_interacting: bool:
|
||||
get: return _is_interacting
|
||||
set(value):
|
||||
if _is_interacting != value:
|
||||
_is_interacting = value
|
||||
if value: interact.emit()
|
||||
|
||||
var _is_weapon_ready: bool = false
|
||||
var is_weapon_ready: bool:
|
||||
get: return _is_weapon_ready
|
||||
set(value):
|
||||
if _is_weapon_ready != value:
|
||||
_is_weapon_ready = value
|
||||
if value: ready_weapon.emit()
|
||||
else: unready_weapon.emit()
|
||||
|
||||
var _is_firing: bool = false
|
||||
var is_firing: bool:
|
||||
get: return _is_firing
|
||||
set(value):
|
||||
if _is_firing != value:
|
||||
_is_firing = value
|
||||
if value: fire.emit()
|
||||
|
||||
var movement_dir: Vector2:
|
||||
get: return Input.get_vector(
|
||||
|
@ -12,17 +61,69 @@ var movement_dir: Vector2:
|
|||
'move_up', 'move_down'
|
||||
).normalized()
|
||||
|
||||
var _mouse_position: Vector2:
|
||||
get:
|
||||
var viewport = get_viewport()
|
||||
var mouse_pos = viewport.get_mouse_position()
|
||||
var cam = viewport.get_camera_3d()
|
||||
var space_state = cam.get_world_3d().direct_space_state
|
||||
var origin = cam.project_ray_origin(mouse_pos)
|
||||
var end = origin + (cam.project_ray_normal(mouse_pos) * cam.far)
|
||||
var query = PhysicsRayQueryParameters3D.create(origin, end)
|
||||
|
||||
var result = space_state.intersect_ray(query)
|
||||
var position = result.get('position') as Vector3
|
||||
return Vector2(position.x, position.z)
|
||||
|
||||
var _analog_dir: Vector2:
|
||||
get: return Input.get_vector(
|
||||
'look_left', 'look_right',
|
||||
'look_up', 'look_down'
|
||||
).normalized()
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var running = Input.is_action_pressed("run")
|
||||
if running != is_running:
|
||||
run.emit(running)
|
||||
is_running = running
|
||||
is_running = Input.is_action_pressed(Action.Run)
|
||||
|
||||
var was_interacting = is_interacting
|
||||
is_interacting = Input.is_action_pressed("interact")
|
||||
func _get_device(event: InputEvent) -> Device:
|
||||
if event is InputEventMouse or event is InputEventKey:
|
||||
return Device.KeyboardMouse
|
||||
elif event is InputEventJoypadButton or event is InputEventJoypadMotion:
|
||||
return Device.Gamepad
|
||||
else:
|
||||
return Device.Unknown
|
||||
|
||||
if is_interacting and not was_interacting:
|
||||
interact.emit()
|
||||
func _input(event: InputEvent) -> void:
|
||||
last_known_device = _get_device(event)
|
||||
|
||||
if event.is_action_pressed(Action.Interact):
|
||||
is_interacting = true
|
||||
|
||||
if event.is_action_released(Action.Interact):
|
||||
is_interacting = false
|
||||
|
||||
if event.is_action_pressed(Action.Ready):
|
||||
is_weapon_ready = true
|
||||
|
||||
if event.is_action_released(Action.Ready):
|
||||
is_weapon_ready = false
|
||||
|
||||
if event.is_action_pressed(Action.Fire):
|
||||
is_firing = true
|
||||
|
||||
if event.is_action_released(Action.Fire):
|
||||
is_firing = false
|
||||
|
||||
func next_velocity(speed: float, dir: Vector2 = movement_dir) -> Vector3:
|
||||
return Vector3(dir.x, 0, dir.y) * speed
|
||||
|
||||
func get_look_target(position: Vector3) -> Option:
|
||||
match last_known_device:
|
||||
Device.KeyboardMouse:
|
||||
var pos = _mouse_position
|
||||
return Option.some(Vector3(pos.x, position.y, pos.y))
|
||||
Device.Gamepad:
|
||||
var pos = _analog_dir
|
||||
if pos.is_zero_approx():
|
||||
return Option.none
|
||||
return Option.some(Vector3(pos.x, 0, pos.y) + position)
|
||||
_: return Option.none
|
||||
|
|
Loading…
Add table
Reference in a new issue