diff --git a/assets/LevelBlockouts/blockout4.blend.unwrap_cache b/assets/LevelBlockouts/blockout4.blend.unwrap_cache index 8987429..44bd41d 100644 Binary files a/assets/LevelBlockouts/blockout4.blend.unwrap_cache and b/assets/LevelBlockouts/blockout4.blend.unwrap_cache differ diff --git a/assets/player.tscn b/assets/player.tscn index b1815f2..511bfd5 100644 --- a/assets/player.tscn +++ b/assets/player.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=37 format=3 uid="uid://drwae3loscbw7"] +[gd_scene load_steps=38 format=3 uid="uid://drwae3loscbw7"] [ext_resource type="Script" uid="uid://bieeh1iro4ji1" path="res://scripts/player.gd" id="1_x7wms"] +[ext_resource type="Script" uid="uid://csju024nerln6" path="res://scripts/StateMachine.gd" id="2_irwor"] [ext_resource type="Script" uid="uid://s2nes6cthron" path="res://scripts/recoil.gd" id="3_405jc"] [ext_resource type="Texture2D" uid="uid://cknftvqq8rbrm" path="res://assets/Textures/Cookie_tutorial_texture_flashlight.png" id="4_x670l"] [ext_resource type="PackedScene" uid="uid://dqgtnykkbngem" path="res://assets/weapon_select.tscn" id="5_bvbcl"] @@ -134,6 +135,9 @@ script = ExtResource("1_x7wms") SENSITIVITY = 0.008 weapon_holder = NodePath("Head/Recoil/Camera3D/WeaponHolder") +[node name="States" type="Node" parent="."] +script = ExtResource("2_irwor") + [node name="HealthIndicator" type="ColorRect" parent="."] material = SubResource("CanvasItemMaterial_l5ga0") offset_right = 40.0 diff --git a/scripts/PlayerStateMachine.gd b/scripts/PlayerStateMachine.gd new file mode 100644 index 0000000..23ddd9d --- /dev/null +++ b/scripts/PlayerStateMachine.gd @@ -0,0 +1,41 @@ +extends Node +class_name StateMachine + +@export var initial_state : State + +var current_state : State +var states : Dictionary = {} + +func _ready() -> void: + for child in get_children(): + if child is State: + states[child.name.to_lower()] = child + child.Transitioned.connect(on_child_transition) + + if initial_state: + initial_state.Enter() + current_state = initial_state + +func _process(delta: float) -> void: + if current_state: + current_state.Update(delta) + +func _physics_process(delta: float) -> void: + if current_state: + current_state.Physics_Update(delta) + +func on_child_transition(state,new_state_name): + if state != current_state: + return + + var new_state = states.get(new_state_name.to_lower()) + if !new_state: + return + + if current_state: + current_state.Exit() + + new_state.Enter() + + current_state = new_state + print("STATE CHANGED TO : ",current_state) diff --git a/scripts/PlayerStateMachine.gd.uid b/scripts/PlayerStateMachine.gd.uid new file mode 100644 index 0000000..3de2d19 --- /dev/null +++ b/scripts/PlayerStateMachine.gd.uid @@ -0,0 +1 @@ +uid://linvnr16djav diff --git a/scripts/PlayerStates.gd b/scripts/PlayerStates.gd new file mode 100644 index 0000000..6540818 --- /dev/null +++ b/scripts/PlayerStates.gd @@ -0,0 +1,91 @@ +extends State +class_name CharacterState + +@export var character : CharacterBody3D +@export var move_speed : float = 3 +@export var body_turn_speed : float = 3 +@export var head_turn_speed : float = 6.0 +@export var can_see : bool = true # indicates whether the character is able to see things in the state +@export var poi_investigate : bool = false +@export var poi_change_to_search : bool = false +@export var poi_update_waypoint_immediately : bool = false + +var move_target +var look_target + +func character_has_target(): + if character.player_last_seen != null: + return true + if character.point_of_interest != null: + return true + return false + +func update_move_target(): + if character.player_last_seen != null: + return character.player_last_seen + elif character.point_of_interest != null: + return character.point_of_interest["point"] + else: + return character.global_position + +func search_on_lost_target(): + if !character.is_player_visible(): + Transitioned.emit(self,"attack") + +func move_target_adj(position): + return Vector3(position.x,character.global_position.y,position.z) + +func rotate_to_face2D(object,target,target_offset_angle,delta,turn_speed): + #to allow both nodes and positions to be passed to this function, test the target and use Vector3 coords + var target_transformed + if target == null: + target_transformed = object.global_position + elif target is Vector3: + target_transformed = target + elif target is Node3D: + target_transformed = target.global_position + + var pos2d = Vector2(object.global_position.x,object.global_position.z) + var target_pos2d = Vector2(target_transformed.x,target_transformed.z) + var direction = (pos2d - target_pos2d) + return lerp_angle(object.global_rotation.y,atan2(direction.x,direction.y) + deg_to_rad(target_offset_angle),delta * turn_speed) + +func rotate_to_face3D(object : Node3D,target,target_offset_angle : Vector3,delta : float,turn_speed : float): + if target == null: + return + + var target_positon + + if target is Vector3: + target_positon = target + else: + target_positon = target.global_position + + var desired_rotation = object.global_transform.looking_at(target_positon,Vector3.UP).basis.get_euler() + var current_rotation = object.global_rotation + + #Interpolate each axis + current_rotation.x = lerp_angle(current_rotation.x,desired_rotation.x + target_offset_angle.x,delta * turn_speed) + current_rotation.y = lerp_angle(current_rotation.y,desired_rotation.y + target_offset_angle.y,delta * turn_speed) + current_rotation.z = lerp_angle(current_rotation.z,desired_rotation.z + target_offset_angle.z,delta * turn_speed) + + #clamp pitch + var max_downward_pitch = deg_to_rad(85) + var min_upward_pitch = deg_to_rad(-45) + current_rotation.x = clamp(current_rotation.x,min_upward_pitch, max_downward_pitch) + + object.global_rotation = current_rotation + +func move_to_nav_point(delta): + var destination = character.nav_agent.get_next_path_position() + var local_destination = destination - character.global_position + var new_velocity = local_destination.normalized() * move_speed + + character.nav_agent.set_velocity(new_velocity) + character.global_rotation.y = rotate_to_face2D(character,destination,0,delta,body_turn_speed) + +func velocity_computed(safe_velocity): + character.velocity = character.velocity.move_toward(safe_velocity,.25) + +func update_minimap(priority,duration,color): + SignalBus.emit_signal("ui_minimap_point",character,character.global_position,1,duration,color) diff --git a/scripts/PlayerStates.gd.uid b/scripts/PlayerStates.gd.uid new file mode 100644 index 0000000..c148f6a --- /dev/null +++ b/scripts/PlayerStates.gd.uid @@ -0,0 +1 @@ +uid://dk0vg5btak80a diff --git a/scripts/StateMachine.gd b/scripts/StateMachine.gd index 23ddd9d..4f335b2 100644 --- a/scripts/StateMachine.gd +++ b/scripts/StateMachine.gd @@ -1,6 +1,7 @@ extends Node -class_name StateMachine +class_name PlayerStateMachine +@export var player : Player @export var initial_state : State var current_state : State