mirror of
https://gitlab.com/open-fpsz/open-fpsz.git
synced 2026-01-19 19:44:46 +00:00
Merge branch 'feat/fully-skinned-3rd-person-character' into 'develop'
Fully skinned 3rd person character, aim IK basic setup See merge request open-fpsz/open-fpsz!29
This commit is contained in:
commit
c76c149302
27
entities/player/assets/vanguard.gd
Normal file
27
entities/player/assets/vanguard.gd
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
class_name Vanguard extends Node
|
||||
|
||||
@export var spine_ik_target_attachment : Node3D
|
||||
|
||||
@onready var animation_tree : AnimationTree = $AnimationTree
|
||||
@onready var spine_ik = $Node/Skeleton3D/SpineIK
|
||||
@onready var spine_ik_target = $SpineIKTarget
|
||||
|
||||
enum GroundState { GROUND_STATE_GROUNDED, GROUND_STATE_MID_AIR, GROUND_STATE_DEAD }
|
||||
|
||||
func _ready():
|
||||
spine_ik.start()
|
||||
|
||||
func _process(_delta):
|
||||
spine_ik_target.global_transform = spine_ik_target_attachment.global_transform
|
||||
|
||||
func set_locomotion(locomotion : Vector2, ground_speed_factor : float) -> void:
|
||||
animation_tree.set("parameters/Locomotion/blend_position", locomotion)
|
||||
animation_tree.set("parameters/GroundSpeed/scale", ground_speed_factor)
|
||||
|
||||
func set_ground_state(ground_state : GroundState):
|
||||
var transition_name = "grounded"
|
||||
if ground_state == GroundState.GROUND_STATE_MID_AIR:
|
||||
transition_name = "mid_air"
|
||||
if ground_state == GroundState.GROUND_STATE_DEAD:
|
||||
transition_name = "dead"
|
||||
animation_tree.set("parameters/Transition/transition_request", transition_name)
|
||||
BIN
entities/player/assets/vanguard.glb
Normal file
BIN
entities/player/assets/vanguard.glb
Normal file
Binary file not shown.
10831
entities/player/assets/vanguard.glb.import
Normal file
10831
entities/player/assets/vanguard.glb.import
Normal file
File diff suppressed because it is too large
Load diff
3571
entities/player/assets/vanguard.tscn
Normal file
3571
entities/player/assets/vanguard.tscn
Normal file
File diff suppressed because it is too large
Load diff
BIN
entities/player/assets/vanguard_0.png
Normal file
BIN
entities/player/assets/vanguard_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
36
entities/player/assets/vanguard_0.png.import
Normal file
36
entities/player/assets/vanguard_0.png.import
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ia3bdpe4rm1m"
|
||||
path.s3tc="res://.godot/imported/vanguard_0.png-601f36bc664114e126d425d5f45085ef.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://entities/player/assets/vanguard_0.png"
|
||||
dest_files=["res://.godot/imported/vanguard_0.png-601f36bc664114e126d425d5f45085ef.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
BIN
entities/player/assets/vanguard_1.png
Normal file
BIN
entities/player/assets/vanguard_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
36
entities/player/assets/vanguard_1.png.import
Normal file
36
entities/player/assets/vanguard_1.png.import
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bvgfmpb2l1juf"
|
||||
path.s3tc="res://.godot/imported/vanguard_1.png-39b5712c4c4119a42b3540a159f8b3f2.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://entities/player/assets/vanguard_1.png"
|
||||
dest_files=["res://.godot/imported/vanguard_1.png-39b5712c4c4119a42b3540a159f8b3f2.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=1
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal="res://entities/player/assets/vanguard_1.png"
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
BIN
entities/player/assets/vanguard_2.png
Normal file
BIN
entities/player/assets/vanguard_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
36
entities/player/assets/vanguard_2.png.import
Normal file
36
entities/player/assets/vanguard_2.png.import
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://vtrbc3eja3df"
|
||||
path.s3tc="res://.godot/imported/vanguard_2.png-986e3665904b0d4758f584d5d3b7b726.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://entities/player/assets/vanguard_2.png"
|
||||
dest_files=["res://.godot/imported/vanguard_2.png-986e3665904b0d4758f584d5d3b7b726.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=1
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal="res://entities/player/assets/vanguard_2.png"
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
|
|
@ -50,16 +50,20 @@ func _ready():
|
|||
health_component.health_changed.connect(iff._on_health_changed)
|
||||
health_component.health_changed.emit(health_component.health)
|
||||
health_component.health_zeroed.connect(_die)
|
||||
if player_id == multiplayer.get_unique_id():
|
||||
if _is_first_person():
|
||||
camera.current = true
|
||||
remove_child($ThirdPerson)
|
||||
else:
|
||||
remove_child($HUD)
|
||||
weapon.hide()
|
||||
input.fired_primary.connect(_fire_primary)
|
||||
input.jumped.connect(_jump)
|
||||
|
||||
func _is_first_person():
|
||||
return player_id == multiplayer.get_unique_id()
|
||||
|
||||
func _fire_primary():
|
||||
if player_state == PlayerState.PLAYER_DEAD:
|
||||
if _is_player_dead():
|
||||
return
|
||||
if not weapon.can_fire():
|
||||
return
|
||||
|
|
@ -67,11 +71,12 @@ func _fire_primary():
|
|||
weapon.transform = _original_weapon_transform
|
||||
weapon.fire_primary()
|
||||
weapon.transform = current_weapon_transform
|
||||
animation_player.stop()
|
||||
animation_player.play("shoot")
|
||||
if _is_first_person():
|
||||
animation_player.stop()
|
||||
animation_player.play("shoot")
|
||||
|
||||
func _jump():
|
||||
if player_state == PlayerState.PLAYER_DEAD:
|
||||
if _is_player_dead():
|
||||
return
|
||||
_jumping = true
|
||||
|
||||
|
|
@ -95,26 +100,30 @@ func _handle_jetpack(delta, direction):
|
|||
energy_changed.emit(energy)
|
||||
|
||||
func _process(_delta):
|
||||
if player_state == PlayerState.PLAYER_DEAD:
|
||||
if _is_player_dead():
|
||||
iff.hide()
|
||||
return
|
||||
else:
|
||||
iff.show()
|
||||
if not _is_first_person():
|
||||
$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
|
||||
else:
|
||||
animation_player.play("idle")
|
||||
%SpringArm3D.global_transform.basis = Basis.from_euler(Vector3(input.camera_rotation.y, input.camera_rotation.x, 0.0))
|
||||
|
||||
if animation_player.current_animation == "shoot":
|
||||
pass
|
||||
else:
|
||||
animation_player.play("idle")
|
||||
|
||||
func _physics_process(delta):
|
||||
if player_state == PlayerState.PLAYER_DEAD:
|
||||
return
|
||||
|
||||
# retrieve user's direction vector
|
||||
var _input_dir = input.direction
|
||||
# compute direction in local space
|
||||
var _direction = (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)
|
||||
|
||||
|
|
@ -144,14 +153,39 @@ func _physics_process(delta):
|
|||
|
||||
_jumping = false
|
||||
|
||||
func _update_third_person_animations():
|
||||
if _is_first_person():
|
||||
return
|
||||
|
||||
var tp_player : Vanguard = $ThirdPerson/PlayerMesh
|
||||
|
||||
if _is_player_dead():
|
||||
tp_player.set_ground_state(Vanguard.GroundState.GROUND_STATE_DEAD)
|
||||
return
|
||||
|
||||
if _is_on_floor():
|
||||
tp_player.set_ground_state(Vanguard.GroundState.GROUND_STATE_GROUNDED)
|
||||
else:
|
||||
tp_player.set_ground_state(Vanguard.GroundState.GROUND_STATE_MID_AIR)
|
||||
var local_velocity = (tp_player.global_basis.inverse() * linear_velocity)
|
||||
const bias : float = 1.2 # Basically match feet speed with ground speed
|
||||
tp_player.set_locomotion(Vector2(local_velocity.x, local_velocity.z), bias)
|
||||
|
||||
func _is_player_dead():
|
||||
return player_state == PlayerState.PLAYER_DEAD
|
||||
|
||||
func _die():
|
||||
player_state = PlayerState.PLAYER_DEAD
|
||||
animation_player.stop()
|
||||
animation_player.play("death")
|
||||
if _is_first_person():
|
||||
animation_player.stop()
|
||||
animation_player.play("death")
|
||||
var tween = create_tween()
|
||||
tween.tween_interval(2)
|
||||
tween.tween_interval(4)
|
||||
tween.tween_callback(func(): died.emit(self))
|
||||
tween.tween_callback(func(): animation_player.stop())
|
||||
tween.tween_callback(func():
|
||||
if _is_first_person():
|
||||
animation_player.stop()
|
||||
)
|
||||
|
||||
func respawn(location):
|
||||
linear_velocity = Vector3()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=18 format=3 uid="uid://cbhx1xme0sb7k"]
|
||||
[gd_scene load_steps=20 format=3 uid="uid://cbhx1xme0sb7k"]
|
||||
|
||||
[ext_resource type="Script" path="res://entities/player/player.gd" id="1_mk68k"]
|
||||
[ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://entities/player/collision_shape.res" id="2_8rtw3"]
|
||||
[ext_resource type="PackedScene" uid="uid://drbefw6akui2v" path="res://entities/player/assets/vanguard.tscn" id="2_beyex"]
|
||||
[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://weapons/space_gun/space_gun.tscn" id="4_lhn5w"]
|
||||
[ext_resource type="PackedScene" uid="uid://dn1tcakam5egs" path="res://weapons/space_gun/projectile.tscn" id="5_lvaut"]
|
||||
|
|
@ -203,6 +204,7 @@ continuous_cd = true
|
|||
script = ExtResource("1_mk68k")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
visible = false
|
||||
mesh = SubResource("CapsuleMesh_vmqfq")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
|
|
@ -231,6 +233,9 @@ near = 0.1
|
|||
transform = Transform3D(-1, 0, 2.53518e-06, 0, 1, 0, -2.53518e-06, 0, -1, 0.244668, -0.229311, -0.30332)
|
||||
PROJECTILE = ExtResource("5_lvaut")
|
||||
|
||||
[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="HealthComponent" parent="." instance=ExtResource("5_t6i6e")]
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
|
|
@ -250,6 +255,10 @@ script = ExtResource("6_ymcrr")
|
|||
|
||||
[node name="ThirdPerson" type="Node3D" parent="."]
|
||||
|
||||
[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="IFFAttachment" type="Node3D" parent="ThirdPerson"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.27457, 0)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ func _test_projectile_class():
|
|||
var projectile = Projectile.new()
|
||||
assert(projectile != null, "Projectile class should be instantiated")
|
||||
assert(projectile.speed == 78.4, "Projectile damage should be initialized to 78.4")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue