diff --git a/addons/smoothing/LICENSE b/addons/smoothing/LICENSE new file mode 100644 index 0000000..1742475 --- /dev/null +++ b/addons/smoothing/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Lawnjelly + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/smoothing/plugin.cfg b/addons/smoothing/plugin.cfg new file mode 100644 index 0000000..f263dae --- /dev/null +++ b/addons/smoothing/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Smoothing" +description="Smoothing nodes for fixed timestep interpolation." +author="Lawnjelly" +version="1.2.1" +script="smoothing_plugin.gd" diff --git a/addons/smoothing/smoothing.gd b/addons/smoothing/smoothing.gd new file mode 100644 index 0000000..7cda59e --- /dev/null +++ b/addons/smoothing/smoothing.gd @@ -0,0 +1,235 @@ +# Copyright (c) 2019 Lawnjelly +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +extends Node3D + +@export +var target: NodePath: + get: + return target + set(v): + target = v + set_target() + + +var _m_Target: Node3D + +var _m_trCurr: Transform3D +var _m_trPrev: Transform3D + +const SF_ENABLED = 1 << 0 +const SF_TRANSLATE = 1 << 1 +const SF_BASIS = 1 << 2 +const SF_SLERP = 1 << 3 +const SF_INVISIBLE = 1 << 4 + +@export_flags("enabled", "translate", "basis", "slerp") var flags: int = SF_ENABLED | SF_TRANSLATE | SF_BASIS: + set(v): + flags = v + # we may have enabled or disabled + _SetProcessing() + get: + return flags + + +########################################################################################## +# USER FUNCS + + +# call this checked e.g. starting a level, AFTER moving the target +# so we can update both the previous and current values +func teleport(): + var temp_flags = flags + _SetFlags(SF_TRANSLATE | SF_BASIS) + + _RefreshTransform() + _m_trPrev = _m_trCurr + + # do one frame update to make sure all components are updated + _process(0) + + # resume old flags + flags = temp_flags + + +func set_enabled(bEnable: bool): + _ChangeFlags(SF_ENABLED, bEnable) + _SetProcessing() + + +func is_enabled(): + return _TestFlags(SF_ENABLED) + + +########################################################################################## + + +func _ready(): + _m_trCurr = Transform3D() + _m_trPrev = Transform3D() + set_process_priority(100) + set_as_top_level(true) + Engine.set_physics_jitter_fix(0.0) + + +func set_target(): + if is_inside_tree(): + _FindTarget() + + +func _set_flags(new_value): + flags = new_value + # we may have enabled or disabled + _SetProcessing() + + +func _get_flags(): + return flags + + +func _SetProcessing(): + var bEnable = _TestFlags(SF_ENABLED) + if _TestFlags(SF_INVISIBLE): + bEnable = false + + set_process(bEnable) + set_physics_process(bEnable) + pass + + +func _enter_tree(): + # might have been moved + _FindTarget() + pass + + +func _notification(what): + match what: + # invisible turns unchecked processing + NOTIFICATION_VISIBILITY_CHANGED: + _ChangeFlags(SF_INVISIBLE, is_visible_in_tree() == false) + _SetProcessing() + + +func _RefreshTransform(): + if _HasTarget() == false: + return + + _m_trPrev = _m_trCurr + _m_trCurr = _m_Target.global_transform + +func _FindTarget(): + _m_Target = null + + # If no target has been assigned in the property, + # default to using the parent as the target. + if target.is_empty(): + var parent = get_parent_node_3d() + if parent: + _m_Target = parent + return + + var targ = get_node(target) + + if ! targ: + printerr("ERROR SmoothingNode : Target " + str(target) + " not found") + return + + if not targ is Node3D: + printerr("ERROR SmoothingNode : Target " + str(target) + " is not node 3D") + target = "" + return + + # if we got to here targ is a spatial + _m_Target = targ + + # certain targets are disallowed + if _m_Target == self: + var msg = str(_m_Target.get_name()) + " assigned to " + str(self.get_name()) + "]" + printerr("ERROR SmoothingNode : Target should not be self [", msg) + + # error message + #OS.alert("Target cannot be a parent or grandparent in the scene tree.", "SmoothingNode") + _m_Target = null + target = "" + return + + +func _HasTarget() -> bool: + if _m_Target == null: + return false + + # has not been deleted? + if is_instance_valid(_m_Target): + return true + + _m_Target = null + return false + + +func _process(_delta): + + var f = Engine.get_physics_interpolation_fraction() + var tr: Transform3D = Transform3D() + + # translate + if _TestFlags(SF_TRANSLATE): + var ptDiff = _m_trCurr.origin - _m_trPrev.origin + tr.origin = _m_trPrev.origin + (ptDiff * f) + + # rotate + if _TestFlags(SF_BASIS): + if _TestFlags(SF_SLERP): + tr.basis = _m_trPrev.basis.slerp(_m_trCurr.basis, f) + else: + tr.basis = _LerpBasis(_m_trPrev.basis, _m_trCurr.basis, f) + + transform = tr + + +func _physics_process(_delta): + _RefreshTransform() + + +func _LerpBasis(from: Basis, to: Basis, f: float) -> Basis: + var res: Basis = Basis() + res.x = from.x.lerp(to.x, f) + res.y = from.y.lerp(to.y, f) + res.z = from.z.lerp(to.z, f) + return res + + +func _SetFlags(f): + flags |= f + + +func _ClearFlags(f): + flags &= ~f + + +func _TestFlags(f): + return (flags & f) == f + + +func _ChangeFlags(f, bSet): + if bSet: + _SetFlags(f) + else: + _ClearFlags(f) diff --git a/addons/smoothing/smoothing.png b/addons/smoothing/smoothing.png new file mode 100644 index 0000000..4d46817 Binary files /dev/null and b/addons/smoothing/smoothing.png differ diff --git a/addons/smoothing/smoothing_2d.gd b/addons/smoothing/smoothing_2d.gd new file mode 100644 index 0000000..3e09c4a --- /dev/null +++ b/addons/smoothing/smoothing_2d.gd @@ -0,0 +1,212 @@ +# Copyright (c) 2019 Lawnjelly +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +extends Node2D + + +@export +var target: NodePath: + get: + return target + set(v): + target = v + if is_inside_tree(): + _FindTarget() + +var _m_Target: Node2D +var _m_Flip:bool = false + +var _m_Trans_curr: Transform2D = Transform2D() +var _m_Trans_prev: Transform2D = Transform2D() + +const SF_ENABLED = 1 << 0 +const SF_GLOBAL_IN = 1 << 1 +const SF_GLOBAL_OUT = 1 << 2 +const SF_TOP_LEVEL = 1 << 3 +const SF_INVISIBLE = 1 << 4 + +@export_flags("enabled", "global in", "global out", "top level") var flags: int = SF_ENABLED | SF_GLOBAL_IN | SF_GLOBAL_OUT: + set(v): + flags = v + # we may have enabled or disabled + _SetProcessing() + get: + return flags + +########################################################################################## +# USER FUNCS + + +# call this checked e.g. starting a level, AFTER moving the target +# so we can update both the previous and current values +func teleport(): + _RefreshTransform() + _m_Trans_prev = _m_Trans_curr + + # call frame upate to make sure all components of the node are set + _process(0) + + +func set_enabled(bEnable: bool): + _ChangeFlags(SF_ENABLED, bEnable) + _SetProcessing() + + +func is_enabled(): + return _TestFlags(SF_ENABLED) + + +########################################################################################## + + +func _ready(): + set_process_priority(100) + Engine.set_physics_jitter_fix(0.0) + set_as_top_level(_TestFlags(SF_TOP_LEVEL)) + + +func _SetProcessing(): + var bEnable = _TestFlags(SF_ENABLED) + if _TestFlags(SF_INVISIBLE): + bEnable = false + + set_process(bEnable) + set_physics_process(bEnable) + set_as_top_level(_TestFlags(SF_TOP_LEVEL)) + + +func _enter_tree(): + # might have been moved + _FindTarget() + + +func _notification(what): + match what: + # invisible turns unchecked processing + NOTIFICATION_VISIBILITY_CHANGED: + _ChangeFlags(SF_INVISIBLE, is_visible_in_tree() == false) + _SetProcessing() + + +func _RefreshTransform(): + + if _HasTarget() == false: + return + + _m_Trans_prev = _m_Trans_curr + + if _TestFlags(SF_GLOBAL_IN): + _m_Trans_curr = _m_Target.get_global_transform() + else: + _m_Trans_curr = _m_Target.get_transform() + + _m_Flip = false + # Ideally we would use determinant core function, as in commented line below, but we + # need to workaround for backward compat. + # if (_m_Trans_prev.determinant() < 0) != (_m_Trans_curr.determinant() < 0): + + if (_Determinant_Sign(_m_Trans_prev) != _Determinant_Sign(_m_Trans_curr)): + _m_Flip = true + +func _Determinant_Sign(t:Transform2D)->bool: + # Workaround Transform2D determinant function not being available + # until 3.6 / 4.1. + # We calculate determinant manually, slower but compatible to lower + # godot versions. + var d = (t.x.x * t.y.y) - (t.x.y * t.y.x) + return d >= 0.0 + + +func _FindTarget(): + _m_Target = null + + # If no target has been assigned in the property, + # default to using the parent as the target. + if target.is_empty(): + var parent = get_parent() + if parent and (parent is Node2D): + _m_Target = parent + return + + var targ = get_node(target) + + if ! targ: + printerr("ERROR SmoothingNode2D : Target " + str(target) + " not found") + return + + if not targ is Node2D: + printerr("ERROR SmoothingNode2D : Target " + str(target) + " is not Node2D") + target = "" + return + + # if we got to here targ is correct type + _m_Target = targ + +func _HasTarget() -> bool: + if _m_Target == null: + return false + + # has not been deleted? + if is_instance_valid(_m_Target): + return true + + _m_Target = null + return false + + +func _process(_delta): + var f = Engine.get_physics_interpolation_fraction() + + var tr = Transform2D() + tr.origin = lerp(_m_Trans_prev.origin, _m_Trans_curr.origin, f) + tr.x = lerp(_m_Trans_prev.x, _m_Trans_curr.x, f) + tr.y = lerp(_m_Trans_prev.y, _m_Trans_curr.y, f) + + # When a sprite flip is detected, turn off interpolation for that tick. + if _m_Flip: + tr = _m_Trans_curr + + if _TestFlags(SF_GLOBAL_OUT) and not _TestFlags(SF_TOP_LEVEL): + set_global_transform(tr) + else: + set_transform(tr) + + +func _physics_process(_delta): + _RefreshTransform() + + +func _SetFlags(f): + flags |= f + + +func _ClearFlags(f): + flags &= ~f + + +func _TestFlags(f): + return (flags & f) == f + + +func _ChangeFlags(f, bSet): + if bSet: + _SetFlags(f) + else: + _ClearFlags(f) diff --git a/addons/smoothing/smoothing_2d.png b/addons/smoothing/smoothing_2d.png new file mode 100644 index 0000000..558117a Binary files /dev/null and b/addons/smoothing/smoothing_2d.png differ diff --git a/addons/smoothing/smoothing_plugin.gd b/addons/smoothing/smoothing_plugin.gd new file mode 100644 index 0000000..3bf6fb1 --- /dev/null +++ b/addons/smoothing/smoothing_plugin.gd @@ -0,0 +1,17 @@ +@tool +extends EditorPlugin + + +func _enter_tree(): + # Initialization of the plugin goes here + # Add the new type with a name, a parent type, a script and an icon + add_custom_type("Smoothing", "Node3D", preload("smoothing.gd"), preload("smoothing.png")) + add_custom_type("Smoothing2D", "Node2D", preload("smoothing_2d.gd"), preload("smoothing_2d.png")) + pass + + +func _exit_tree(): + # Clean-up of the plugin goes here + # Always remember to remove_at it from the engine when deactivated + remove_custom_type("Smoothing") + remove_custom_type("Smoothing2D") diff --git a/entities/player/player.gd b/entities/player/player.gd index 5682b47..4ba3dc2 100644 --- a/entities/player/player.gd +++ b/entities/player/player.gd @@ -42,17 +42,17 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD } @export var nickname : String @onready var input : PlayerInput = $PlayerInput -@onready var camera : Camera3D = $SpringArm3D/Camera3D +@onready var camera : Camera3D = $Smoothing/SpringArm3D/Camera3D @onready var hud : CanvasLayer = $HUD @onready var shape_cast : ShapeCast3D = $ShapeCast3D -@onready var weapon : Node3D = $SpringArm3D/Inventory/SpaceGun +@onready var weapon : Node3D = $Smoothing/SpringArm3D/Inventory/SpaceGun @onready var animation_player : AnimationPlayer = $AnimationPlayer @onready var health_component : Area3D = $HealthComponent @onready var collision_shape : CollisionShape3D = $CollisionShape3D @onready var flag_carry_component : FlagCarryComponent = $FlagCarryComponent -@onready var spring_arm_height : float = $SpringArm3D.position.y +@onready var spring_arm_height : float = $Smoothing/SpringArm3D.position.y @onready var _original_weapon_transform : Transform3D = weapon.transform -@onready var flag_carry_attachment : Node3D = $SpringArm3D/FlagCarryAttachment +@onready var flag_carry_attachment : Node3D = $Smoothing/SpringArm3D/FlagCarryAttachment @onready var _game_settings : Settings = get_node("/root/GlobalSettings") signal died(player : Player) @@ -68,24 +68,25 @@ func _ready() -> void: health_component.health_changed.connect(iff._on_health_changed) health_component.health_changed.emit(health_component.health) health_component.health_zeroed.connect(die) - + input.fired_primary.connect(_fire_primary) input.jumped.connect(_jump) input.throwed_flag.connect(_throw_flag) - + input.MOUSE_SENSITIVITY = _game_settings.mouse_sensitivity input.inverted_y_axis = _game_settings.inverted_y_axis - + if _is_pawn(): camera.current = true camera.fov = _game_settings.fov # set the spring arm translation to be about head height level - $SpringArm3D.transform = Transform3D().translated(Vector3(0, collision_shape.shape.height / 2, 0) * 0.9) + $Smoothing/SpringArm3D.transform = Transform3D().translated(Vector3(0, collision_shape.shape.height / 2, 0) * 0.9) flag_carry_attachment.hide() - remove_child($ThirdPerson) + + $Smoothing.remove_child($Smoothing/ThirdPerson) else: # set the iff attachment translation to be about head height level - $ThirdPerson/IFFAttachment.transform = Transform3D().translated(Vector3(0, collision_shape.shape.height / 2, 0) * 0.9) + $Smoothing/ThirdPerson/IFFAttachment.transform = Transform3D().translated(Vector3(0, collision_shape.shape.height / 2, 0) * 0.9) remove_child(hud) weapon.hide() @@ -128,13 +129,17 @@ func _handle_aerial_control(direction : Vector3) -> void: if not input.jetting and not is_on_floor(): apply_force(direction * aerial_control_force) -func _handle_jetpack(delta : float, direction : Vector3) -> void: +func _handle_jetpack(direction : Vector3) -> void: if input.jetting: if energy > 0: var up_vector : Vector3 = Vector3.UP * jetpack_vertical_force * jetpack_force_factor var side_vector : Vector3 = direction * jetpack_horizontal_force * jetpack_force_factor apply_force(up_vector + side_vector) - energy -= energy_drain_rate * delta + +func _update_jetpack_energy(delta : float) -> void: + if input.jetting: + if energy > 0: + energy -= energy_drain_rate * delta else: energy += energy_charge_rate * delta @@ -148,7 +153,7 @@ func _process(_delta : float) -> void: else: iff.show() if not _is_pawn(): - $ThirdPerson/PlayerMesh.global_transform.basis = Basis.from_euler(Vector3(0.0, input.camera_rotation.x + PI, 0.0)) + $Smoothing/ThirdPerson/PlayerMesh.global_transform.basis = Basis.from_euler(Vector3(0.0, input.camera_rotation.x + PI, 0.0)) else: if animation_player.current_animation == "shoot": pass @@ -157,20 +162,24 @@ func _process(_delta : float) -> void: %SpringArm3D.global_transform.basis = Basis.from_euler(Vector3(input.camera_rotation.y, input.camera_rotation.x, 0.0)) func _physics_process(delta : float) -> void: + _update_jetpack_energy(delta) + +func _handle_movement() -> void: # retrieve user's direction vector var _input_dir : Vector2 = input.direction # compute direction in local space var _direction : Vector3 = (transform.basis * Vector3(_input_dir.x, 0, _input_dir.y)).normalized() + _update_third_person_animations() if _is_player_dead(): return # adjust direction based on spring arm rotation - _direction = _direction.rotated(Vector3.UP, $SpringArm3D.rotation.y) + _direction = _direction.rotated(Vector3.UP, $Smoothing/SpringArm3D.rotation.y) _handle_aerial_control(_direction) - _handle_jetpack(delta, _direction) + _handle_jetpack(_direction) # handle ski if _is_skiing(): @@ -191,18 +200,20 @@ func _physics_process(delta : float) -> void: linear_velocity = lerp(linear_velocity, _direction * ground_speed, .1) -func _integrate_forces(_state : PhysicsDirectBodyState3D) -> void: - if is_on_floor() and _jumping: - var v : float = sqrt(2 * g * jump_height) - apply_central_impulse(Vector3(0, mass * v, 0)) + if _jumping: + var v : float = sqrt(2 * g * jump_height) + apply_central_impulse(Vector3(0, mass * v, 0)) _jumping = false +func _integrate_forces(_state : PhysicsDirectBodyState3D) -> void: + _handle_movement() + func _update_third_person_animations() -> void: if _is_pawn(): return - var tp_player : Vanguard = $ThirdPerson/PlayerMesh + var tp_player : Vanguard = $Smoothing/ThirdPerson/PlayerMesh if _is_player_dead(): tp_player.set_ground_state(Vanguard.GroundState.GROUND_STATE_DEAD) diff --git a/entities/player/player.tscn b/entities/player/player.tscn index 184dac0..35d0a4a 100644 --- a/entities/player/player.tscn +++ b/entities/player/player.tscn @@ -1,15 +1,16 @@ -[gd_scene load_steps=21 format=3 uid="uid://cbhx1xme0sb7k"] +[gd_scene load_steps=22 format=3 uid="uid://cbhx1xme0sb7k"] [ext_resource type="Script" path="res://entities/player/player.gd" id="1_mk68k"] [ext_resource type="PackedScene" uid="uid://drbefw6akui2v" path="res://entities/player/assets/vanguard.tscn" id="2_beyex"] [ext_resource type="Shape3D" uid="uid://cb8esdlnottdn" path="res://entities/player/collision_shape.tres" id="2_vjqny"] [ext_resource type="PackedScene" uid="uid://bcv81ku26xo" path="res://interfaces/hud/hud.tscn" id="3_ccety"] -[ext_resource type="PackedScene" uid="uid://c8co0qa2omjmh" path="res://entities/weapons/space_gun/space_gun.tscn" id="4_ehwwq"] +[ext_resource type="PackedScene" uid="uid://c8co0qa2omjmh" path="res://entities/weapons/space_gun/space_gun.tscn" id="4_6jh57"] +[ext_resource type="PackedScene" uid="uid://dn1tcakam5egs" path="res://entities/weapons/space_gun/projectile.tscn" id="5_2xh36"] [ext_resource type="PackedScene" uid="uid://bof3mg7wgxrmn" path="res://components/health_component.tscn" id="5_t6i6e"] -[ext_resource type="PackedScene" uid="uid://dn1tcakam5egs" path="res://entities/weapons/space_gun/projectile.tscn" id="5_w56pa"] [ext_resource type="Script" path="res://entities/player/player_input.gd" id="6_ymcrr"] [ext_resource type="PackedScene" uid="uid://dsysi2rd3bu76" path="res://interfaces/hud/iff.tscn" id="7_8hc80"] [ext_resource type="PackedScene" uid="uid://2t8ql8pkxv6c" path="res://components/flag_carry_component.tscn" id="7_e7s1a"] +[ext_resource type="Script" path="res://addons/smoothing/smoothing.gd" id="11_k330l"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_clur0"] resource_local_to_scene = true @@ -27,7 +28,7 @@ length = 0.001 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("SpringArm3D/Inventory/SpaceGun:position") +tracks/0/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -39,7 +40,7 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("SpringArm3D/Inventory/SpaceGun:rotation") +tracks/1/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { @@ -51,7 +52,7 @@ tracks/1/keys = { tracks/2/type = "value" tracks/2/imported = false tracks/2/enabled = true -tracks/2/path = NodePath("SpringArm3D:position") +tracks/2/path = NodePath("Smoothing/SpringArm3D:position") tracks/2/interp = 1 tracks/2/loop_wrap = true tracks/2/keys = { @@ -63,7 +64,7 @@ tracks/2/keys = { tracks/3/type = "value" tracks/3/imported = false tracks/3/enabled = true -tracks/3/path = NodePath("SpringArm3D:rotation") +tracks/3/path = NodePath("Smoothing/SpringArm3D:rotation") tracks/3/interp = 1 tracks/3/loop_wrap = true tracks/3/keys = { @@ -78,7 +79,7 @@ resource_name = "death" tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("SpringArm3D:position") +tracks/0/path = NodePath("Smoothing/SpringArm3D:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -90,7 +91,7 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("SpringArm3D:rotation") +tracks/1/path = NodePath("Smoothing/SpringArm3D:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { @@ -107,7 +108,7 @@ loop_mode = 1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("SpringArm3D/Inventory/SpaceGun:position") +tracks/0/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -119,7 +120,7 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("SpringArm3D/Inventory/SpaceGun:rotation") +tracks/1/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { @@ -134,7 +135,7 @@ resource_name = "shoot" tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("SpringArm3D/Inventory/SpaceGun:position") +tracks/0/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -146,7 +147,7 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("SpringArm3D/Inventory/SpaceGun:rotation") +tracks/1/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { @@ -205,9 +206,10 @@ axis_lock_angular_y = true axis_lock_angular_z = true mass = 75.0 physics_material_override = SubResource("PhysicsMaterial_clur0") +can_sleep = false continuous_cd = true script = ExtResource("1_mk68k") -iff = NodePath("ThirdPerson/IFFAttachment/IFF") +iff = NodePath("Smoothing/ThirdPerson/IFF") jump_height = 1.5 [node name="MeshInstance3D" type="MeshInstance3D" parent="."] @@ -234,49 +236,15 @@ shape = ExtResource("2_vjqny") [node name="HUD" parent="." instance=ExtResource("3_ccety")] -[node name="SpringArm3D" type="SpringArm3D" parent="."] -unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) -spring_length = 0.0 - -[node name="Camera3D" type="Camera3D" parent="SpringArm3D"] -fov = 100.0 -near = 0.1 - -[node name="Inventory" type="Node3D" parent="SpringArm3D"] - -[node name="SpaceGun" parent="SpringArm3D/Inventory" instance=ExtResource("4_ehwwq")] -transform = Transform3D(-1, 0, 2.53518e-06, 0, 1, 0, -2.53518e-06, 0, -1, 0.244668, -0.229311, -0.30332) -PROJECTILE = ExtResource("5_w56pa") - -[node name="SpineIKTarget" type="Node3D" parent="SpringArm3D"] -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) - -[node name="FlagCarryAttachment" type="Node3D" parent="SpringArm3D"] -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, -0.620994, -0.287925) - [node name="HealthComponent" parent="." instance=ExtResource("5_t6i6e")] [node name="CollisionShape3D" type="CollisionShape3D" parent="HealthComponent"] shape = ExtResource("2_vjqny") [node name="FlagCarryComponent" parent="." node_paths=PackedStringArray("attachment", "sensor") instance=ExtResource("7_e7s1a")] -attachment = NodePath("../SpringArm3D/FlagCarryAttachment") +attachment = NodePath("../Smoothing/SpringArm3D/FlagCarryAttachment") sensor = NodePath("../Sensor") -[node name="ThirdPerson" type="Node3D" parent="."] - -[node name="IFFAttachment" type="Marker3D" parent="ThirdPerson"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0) - -[node name="IFF" parent="ThirdPerson/IFFAttachment" node_paths=PackedStringArray("player", "attach_point") instance=ExtResource("7_8hc80")] -player = NodePath("../../..") -attach_point = NodePath("..") - -[node name="PlayerMesh" parent="ThirdPerson" node_paths=PackedStringArray("spine_ik_target_attachment") instance=ExtResource("2_beyex")] -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) -spine_ik_target_attachment = NodePath("../../SpringArm3D/SpineIKTarget") - [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { "": SubResource("AnimationLibrary_hg307") @@ -291,3 +259,42 @@ replication_config = SubResource("SceneReplicationConfig_rqdp6") root_path = NodePath(".") replication_config = SubResource("SceneReplicationConfig_5j4ew") script = ExtResource("6_ymcrr") + +[node name="Smoothing" type="Node3D" parent="."] +script = ExtResource("11_k330l") +target = NodePath("..") +flags = 3 + +[node name="SpringArm3D" type="SpringArm3D" parent="Smoothing"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +spring_length = 0.0 + +[node name="Camera3D" type="Camera3D" parent="Smoothing/SpringArm3D"] +fov = 100.0 +near = 0.1 + +[node name="Inventory" type="Node3D" parent="Smoothing/SpringArm3D"] + +[node name="SpaceGun" parent="Smoothing/SpringArm3D/Inventory" instance=ExtResource("4_6jh57")] +transform = Transform3D(-1, 0, 2.53518e-06, 0, 1, 0, -2.53518e-06, 0, -1, 0.244668, -0.229311, -0.30332) +PROJECTILE = ExtResource("5_2xh36") + +[node name="SpineIKTarget" type="Node3D" parent="Smoothing/SpringArm3D"] +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) + +[node name="FlagCarryAttachment" type="Node3D" parent="Smoothing/SpringArm3D"] +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, -0.620994, -0.287925) + +[node name="ThirdPerson" type="Node3D" parent="Smoothing"] + +[node name="PlayerMesh" parent="Smoothing/ThirdPerson" node_paths=PackedStringArray("spine_ik_target_attachment") instance=ExtResource("2_beyex")] +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) +spine_ik_target_attachment = NodePath("../../SpringArm3D/SpineIKTarget") + +[node name="IFFAttachment" type="Marker3D" parent="Smoothing/ThirdPerson"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.27457, 0) + +[node name="IFF" parent="Smoothing/ThirdPerson" node_paths=PackedStringArray("player", "attach_point") instance=ExtResource("7_8hc80")] +player = NodePath("../../..") +attach_point = NodePath("../IFFAttachment") diff --git a/interfaces/hud/iff.gd b/interfaces/hud/iff.gd index 7a065fc..1e7aab7 100644 --- a/interfaces/hud/iff.gd +++ b/interfaces/hud/iff.gd @@ -30,11 +30,11 @@ extends Control func _ready() -> void: _player_name_label.text = player.name - + func _process(_delta : float) -> void: # retrieve camera for current viewport var camera : Camera3D = get_viewport().get_camera_3d() - + # if the player is NOT infront of the camera or camera does NOT have LOS to player if camera.is_position_behind(attach_point.global_position) or !is_within_los: _iff_container.hide() # hide the IFF and exit function @@ -60,21 +60,21 @@ func _physics_process(_delta : float) -> void: var new_iff_position : Vector2 = camera.unproject_position(attach_point.global_position) # get the screen location of the players head var viewport_size : Vector2 = get_viewport_rect().size - + # check if the unprojected point lies inside the viewport if !Rect2(Vector2(0, 0), viewport_size).has_point(new_iff_position): _iff_container.hide() # hide the IFF and exit function return - + # if player is NOT in range to have its healthbar and name drawn if (new_iff_position - viewport_size / 2).length() > iff_in_range_radius_ratio * viewport_size.length(): _iff_in_range_container.hide() # hide the in range IFF else: _iff_in_range_container.show() - + new_iff_position.y -= _iff_container.size.y # move the IFF up so the bottom of it is at the players head new_iff_position.x -= _iff_container.size.x / 2 # move the IFF left so it's centered horizontally above players head - + position = new_iff_position # set the position of the IFF func _update_health_bar(health : float) -> void: @@ -86,6 +86,6 @@ func _update_health_bar(health : float) -> void: healthbar_fill_stylebox.bg_color = healthbar_low_health_color else: healthbar_fill_stylebox.bg_color = healthbar_high_health_color - + func _on_health_changed(new_health : float) -> void: _update_health_bar(new_health) diff --git a/project.godot b/project.godot index 6fcb923..5f007c7 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ movie_writer/disable_vsync=true [editor_plugins] -enabled=PackedStringArray("res://addons/gut/plugin.cfg", "res://addons/terrain_3d/plugin.cfg") +enabled=PackedStringArray("res://addons/gut/plugin.cfg", "res://addons/smoothing/plugin.cfg", "res://addons/terrain_3d/plugin.cfg") [input]