mirror of
https://gitlab.com/open-fpsz/open-fpsz.git
synced 2026-03-09 15:30:36 +00:00
Merge branch 'feat/nicknames' into 'develop'
✨ Working profile names in-game, basic settings save/load system, flag drops on player death See merge request open-fpsz/open-fpsz!39
This commit is contained in:
commit
63e39bbe15
12 changed files with 122 additions and 67 deletions
|
|
@ -1,6 +1,24 @@
|
|||
# This file is part of open-fpsz.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class_name FlagCarryComponent extends Node
|
||||
## This component allows its entity to grab, carry and throw flags
|
||||
##
|
||||
## To work correctly the owner MUST set an attachment point for carried flags
|
||||
## and a sensor to detect when flags are within grab range
|
||||
|
||||
@export var throw_velocity : float = 10.0
|
||||
@export var max_throw_speed : float = 10.0
|
||||
@export var attachment : Node3D
|
||||
@export var sensor : Area3D
|
||||
|
||||
|
|
@ -20,11 +38,12 @@ func _grab(flag : Flag):
|
|||
flag.grab()
|
||||
_carried_flag = flag
|
||||
|
||||
func throw():
|
||||
@rpc("call_local")
|
||||
func _drop(throw_speed : float):
|
||||
if _is_carrying():
|
||||
_carried_flag.drop()
|
||||
_carried_flag.linear_velocity = attachment.global_basis.z * throw_velocity
|
||||
_carried_flag.rotation_degrees.x = 0.0
|
||||
_carried_flag.linear_velocity = attachment.global_basis.z * throw_speed
|
||||
_carried_flag = null
|
||||
|
||||
func _is_carrying() -> bool:
|
||||
|
|
@ -33,3 +52,9 @@ func _is_carrying() -> bool:
|
|||
func _sensor_on_body_entered(collider):
|
||||
if collider is Flag:
|
||||
_grab.rpc(collider)
|
||||
|
||||
func drop():
|
||||
_drop.rpc(0.0)
|
||||
|
||||
func throw():
|
||||
_drop.rpc(max_throw_speed)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# This file is part of open-fpsz.
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class_name HealthComponent extends Area3D
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bof3mg7wgxrmn"]
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bof3mg7wgxrmn"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/health_component.gd" id="1_00xis"]
|
||||
[ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://entities/player/collision_shape.res" id="2_sgbmt"]
|
||||
|
||||
[node name="HealthComponent" type="Area3D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
script = ExtResource("1_00xis")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = ExtResource("2_sgbmt")
|
||||
|
|
|
|||
Binary file not shown.
4
entities/player/collision_shape.tres
Normal file
4
entities/player/collision_shape.tres
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[gd_resource type="CapsuleShape3D" format=3 uid="uid://cb8esdlnottdn"]
|
||||
|
||||
[resource]
|
||||
radius = 0.25
|
||||
|
|
@ -36,6 +36,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD }
|
|||
set(id):
|
||||
player_id = id
|
||||
$PlayerInput.set_multiplayer_authority(id)
|
||||
@export var nickname : String
|
||||
|
||||
@onready var input : PlayerInput = $PlayerInput
|
||||
@onready var camera = $SpringArm3D/Camera3D
|
||||
|
|
@ -45,7 +46,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD }
|
|||
@onready var weapon = $SpringArm3D/Inventory/SpaceGun
|
||||
@onready var animation_player : AnimationPlayer = $AnimationPlayer
|
||||
@onready var health_component = $HealthComponent
|
||||
@onready var flag_carry_component = $FlagCarryComponent
|
||||
@onready var flag_carry_component : FlagCarryComponent = $FlagCarryComponent
|
||||
@onready var spring_arm_height = $SpringArm3D.position.y
|
||||
@onready var _original_weapon_transform : Transform3D = weapon.transform
|
||||
@onready var flag_carry_attachment = $SpringArm3D/FlagCarryAttachment
|
||||
|
|
@ -65,7 +66,6 @@ func _ready():
|
|||
health_component.health_zeroed.connect(_die)
|
||||
if _is_first_person():
|
||||
camera.current = true
|
||||
flag_carry_attachment.hide()
|
||||
remove_child($ThirdPerson)
|
||||
else:
|
||||
remove_child($HUD)
|
||||
|
|
@ -214,6 +214,11 @@ func _die():
|
|||
if _is_first_person():
|
||||
animation_player.stop()
|
||||
)
|
||||
flag_carry_component.drop()
|
||||
|
||||
@rpc("call_local")
|
||||
func set_nickname(value):
|
||||
nickname = value
|
||||
|
||||
func respawn(location):
|
||||
linear_velocity = Vector3()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
[gd_scene load_steps=21 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="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://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"]
|
||||
|
|
@ -180,6 +180,9 @@ properties/3/replication_mode = 2
|
|||
properties/4/path = NodePath(".:player_state")
|
||||
properties/4/spawn = true
|
||||
properties/4/replication_mode = 2
|
||||
properties/5/path = NodePath(".:nickname")
|
||||
properties/5/spawn = true
|
||||
properties/5/replication_mode = 2
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_5j4ew"]
|
||||
properties/0/path = NodePath(".:direction")
|
||||
|
|
@ -210,11 +213,11 @@ visible = false
|
|||
mesh = SubResource("CapsuleMesh_vmqfq")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = ExtResource("2_8rtw3")
|
||||
shape = ExtResource("2_vjqny")
|
||||
|
||||
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
|
||||
transform = Transform3D(1.05, 0, 0, 0, 1.05, 0, 0, 0, 1.05, 0, 0, 0)
|
||||
shape = ExtResource("2_8rtw3")
|
||||
shape = ExtResource("2_vjqny")
|
||||
target_position = Vector3(0, 0, 0)
|
||||
collision_mask = 2147483656
|
||||
collide_with_areas = true
|
||||
|
|
@ -225,7 +228,7 @@ collision_mask = 8
|
|||
monitorable = false
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Sensor"]
|
||||
shape = ExtResource("2_8rtw3")
|
||||
shape = ExtResource("2_vjqny")
|
||||
|
||||
[node name="HUD" parent="." instance=ExtResource("3_ccety")]
|
||||
|
||||
|
|
@ -252,8 +255,10 @@ transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, -0.
|
|||
|
||||
[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")]
|
||||
throw_velocity = 20.0
|
||||
attachment = NodePath("../SpringArm3D/FlagCarryAttachment")
|
||||
sensor = NodePath("../Sensor")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# This file is part of open-fpsz.
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
extends Node2D
|
||||
|
|
@ -28,7 +28,7 @@ func _process(_delta):
|
|||
else:
|
||||
_v_box_container.show()
|
||||
|
||||
_player_name_label.text = player.name
|
||||
_player_name_label.text = player.nickname
|
||||
position = camera.unproject_position(attach_point.global_position)
|
||||
var viewport_size : Vector2 = get_viewport_rect().size
|
||||
position.x = clampf(position.x, 0, viewport_size.x - _v_box_container.size.x)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://bjctlqvs33nqy"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://bjctlqvs33nqy"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c1tjamjm8qjog" path="res://interfaces/menus/boot/background.webp" id="1_ph586"]
|
||||
|
||||
|
|
@ -10,6 +10,13 @@ signal start_demo
|
|||
|
||||
func _on_demo_pressed():
|
||||
start_demo.emit()
|
||||
|
||||
func _on_multiplayer_pressed():
|
||||
$Main.hide()
|
||||
$Multiplayer.show()
|
||||
|
||||
func _on_quit_pressed():
|
||||
get_tree().quit()
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_krqeq"]
|
||||
|
|
@ -20,9 +27,11 @@ script/source = "class_name MultiplayerPanel extends PanelContainer
|
|||
|
||||
const DEFAULT_HOST : String = \"localhost\"
|
||||
const DEFAULT_PORT : int = 9000
|
||||
const CONFIG_FILE_PATH : String = \"user://settings.cfg\"
|
||||
|
||||
var _join_address = RegEx.new()
|
||||
var _registered_ports = RegEx.new()
|
||||
var _join_address : RegEx = RegEx.new()
|
||||
var _registered_ports : RegEx = RegEx.new()
|
||||
var _config_file : ConfigFile = ConfigFile.new()
|
||||
|
||||
signal start_server(port)
|
||||
signal join_server(host, port)
|
||||
|
|
@ -34,8 +43,21 @@ func _ready():
|
|||
# see https://datatracker.ietf.org/doc/html/rfc1700
|
||||
_registered_ports.compile(r'^(?:102[4-9]|10[3-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$')
|
||||
_join_address.compile(r'^(?<host>[a-zA-Z0-9.-]+)(:(?<port>:102[4-9]|10[3-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5]))?$')
|
||||
_load_config()
|
||||
hide() # start hidden
|
||||
|
||||
func _load_config():
|
||||
var error : Error = _config_file.load(CONFIG_FILE_PATH)
|
||||
if error != OK:
|
||||
return
|
||||
|
||||
var profile_name : String = _config_file.get_value(\"profile\", \"name\", \"Newblood\")
|
||||
%ProfileName.text = profile_name
|
||||
|
||||
func _on_save_pressed():
|
||||
_config_file.set_value(\"profile\", \"name\", %ProfileName.text)
|
||||
_config_file.save(CONFIG_FILE_PATH)
|
||||
|
||||
func _on_menu_pressed():
|
||||
hide()
|
||||
owner.get_node(\"Main\").show()
|
||||
|
|
@ -53,8 +75,8 @@ func _on_host_pressed():
|
|||
else: # port is not valid
|
||||
push_warning(\"A valid port number in the range 1024-65535 is required.\")
|
||||
return
|
||||
|
||||
start_server.emit(port)
|
||||
|
||||
start_server.emit(port, %ProfileName.text)
|
||||
|
||||
func _on_join_pressed():
|
||||
var addr = [DEFAULT_HOST, DEFAULT_PORT]
|
||||
|
|
@ -66,7 +88,7 @@ func _on_join_pressed():
|
|||
if rport: addr[1] = int(rport)
|
||||
|
||||
$Modal.show()
|
||||
join_server.emit(addr[0], addr[1])
|
||||
join_server.emit(addr[0], addr[1], %ProfileName.text)
|
||||
|
||||
func _on_connected_to_server():
|
||||
$Modal.hide()
|
||||
|
|
@ -79,17 +101,6 @@ func _on_connection_failed():
|
|||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_snh7i"]
|
||||
bg_color = Color(0, 0.5, 0.5, 0.25)
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_yqbr7"]
|
||||
script/source = "extends PanelContainer
|
||||
|
||||
func _on_multiplayer_pressed():
|
||||
hide()
|
||||
owner.get_node(\"Multiplayer\").show()
|
||||
|
||||
func _on_quit_pressed():
|
||||
get_tree().quit()
|
||||
"
|
||||
|
||||
[node name="BootMenu" type="CanvasLayer"]
|
||||
script = SubResource("GDScript_jd8xf")
|
||||
|
||||
|
|
@ -156,6 +167,10 @@ layout_mode = 2
|
|||
disabled = true
|
||||
text = "Delete"
|
||||
|
||||
[node name="Save" type="Button" parent="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox"]
|
||||
layout_mode = 2
|
||||
text = "Save"
|
||||
|
||||
[node name="Spacer" type="MarginContainer" parent="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
|
@ -313,7 +328,6 @@ offset_right = 313.0
|
|||
grow_vertical = 2
|
||||
size_flags_horizontal = 0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_snh7i")
|
||||
script = SubResource("GDScript_yqbr7")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Main"]
|
||||
layout_mode = 2
|
||||
|
|
@ -342,6 +356,7 @@ text = "Quit"
|
|||
|
||||
[connection signal="join_server" from="Multiplayer" to="." method="_on_multiplayer_join_server"]
|
||||
[connection signal="start_server" from="Multiplayer" to="." method="_on_multiplayer_start_server"]
|
||||
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Save" to="Multiplayer" method="_on_save_pressed"]
|
||||
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Menu" to="Multiplayer" method="_on_menu_pressed"]
|
||||
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Quit" to="Multiplayer" method="_on_quit_pressed"]
|
||||
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Join/MarginContainer/HBoxContainer/LeftBox/Join" to="Multiplayer" method="_on_join_pressed"]
|
||||
|
|
@ -352,5 +367,5 @@ text = "Quit"
|
|||
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/LeftBox/Quit" to="Multiplayer" method="_on_quit_pressed"]
|
||||
[connection signal="text_changed" from="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/RightBox/ServerPort" to="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/RightBox/ServerPort" method="_on_text_changed"]
|
||||
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Demo" to="." method="_on_demo_pressed"]
|
||||
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Multiplayer" to="Main" method="_on_multiplayer_pressed"]
|
||||
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Quit" to="Main" method="_on_quit_pressed"]
|
||||
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Multiplayer" to="." method="_on_multiplayer_pressed"]
|
||||
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Quit" to="." method="_on_quit_pressed"]
|
||||
|
|
|
|||
|
|
@ -24,20 +24,20 @@ func _start_demo():
|
|||
add_child(mode)
|
||||
$BootMenu.hide()
|
||||
|
||||
func _start_server(port):
|
||||
func _start_server(port, nickname):
|
||||
if mode: mode.queue_free()
|
||||
mode = MULTIPLAYER.instantiate()
|
||||
add_child(mode)
|
||||
mode.start_server(port)
|
||||
mode.start_server(port, nickname)
|
||||
$BootMenu.hide()
|
||||
|
||||
func _join_server(host, port):
|
||||
func _join_server(host, port, nickname):
|
||||
if mode: mode.queue_free()
|
||||
mode = MULTIPLAYER.instantiate()
|
||||
add_child(mode)
|
||||
mode.connected_to_server.connect($BootMenu/Multiplayer._on_connected_to_server)
|
||||
mode.connection_failed.connect($BootMenu/Multiplayer._on_connection_failed)
|
||||
mode.join_server(host, port)
|
||||
mode.join_server(host, port, nickname)
|
||||
|
||||
func _unhandled_input(event):
|
||||
# exit the program
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ signal connection_failed
|
|||
func load_map(scene : PackedScene):
|
||||
map.add_child(scene.instantiate())
|
||||
|
||||
func start_server(port):
|
||||
func start_server(port, nickname):
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
peer.create_server(port, MAX_CLIENTS)
|
||||
|
||||
|
|
@ -34,23 +34,21 @@ func start_server(port):
|
|||
multiplayer.peer_connected.connect(add_player)
|
||||
multiplayer.peer_disconnected.connect(remove_player)
|
||||
|
||||
for id in multiplayer.get_peers():
|
||||
add_player(id)
|
||||
|
||||
if DisplayServer.get_name() != \"headless\":
|
||||
add_player(1)
|
||||
add_player(1, nickname)
|
||||
|
||||
add_flag()
|
||||
|
||||
func join_server(host, port):
|
||||
func join_server(host, port, nickname):
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
peer.create_client(host, port)
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server)
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server.bind(nickname))
|
||||
multiplayer.connection_failed.connect(_on_connection_failed)
|
||||
multiplayer.multiplayer_peer = peer
|
||||
|
||||
func _on_connected_to_server():
|
||||
func _on_connected_to_server(nickname):
|
||||
connected_to_server.emit()
|
||||
_join_match.rpc(nickname)
|
||||
|
||||
func _on_connection_failed():
|
||||
connection_failed.emit()
|
||||
|
|
@ -58,10 +56,11 @@ func _on_connection_failed():
|
|||
func respawn_player(player):
|
||||
player.respawn(Vector3(0.0, 150.0, 0.0))
|
||||
|
||||
func add_player(peer_id : int):
|
||||
func add_player(peer_id : int, nickname : String):
|
||||
var player : Player = PLAYER.instantiate()
|
||||
player.name = str(peer_id)
|
||||
player.player_id = peer_id
|
||||
player.nickname = nickname
|
||||
player.position = Vector3(0.0, 150.0, 0.0)
|
||||
players.add_child(player)
|
||||
player.died.connect(respawn_player)
|
||||
|
|
@ -73,6 +72,12 @@ func remove_player(peer_id : int):
|
|||
players.get_node(node_name).queue_free()
|
||||
print(\"Peer `%s` disconnected\" % node_name)
|
||||
|
||||
@rpc(\"any_peer\")
|
||||
func _join_match(nickname):
|
||||
if multiplayer.is_server():
|
||||
add_player(multiplayer.get_remote_sender_id(), nickname)
|
||||
|
||||
|
||||
func add_flag():
|
||||
var flag : Flag = FLAG.instantiate()
|
||||
flag.position = Vector3(5.0, 100.0, 0.0)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# This file is part of open-fpsz.
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class_name Trail3D extends MeshInstance3D
|
||||
|
|
@ -54,7 +54,7 @@ func _process(delta):
|
|||
if(_old_pos - get_global_transform().origin).length() > _motion_delta and _trail_enabled:
|
||||
_append_point() # Create new point
|
||||
_old_pos = get_global_transform().origin # Update previous position to current position coordinates
|
||||
|
||||
|
||||
# Update the lifespan
|
||||
var p = 0
|
||||
var max_points = _points.size()
|
||||
|
|
@ -64,29 +64,29 @@ func _process(delta):
|
|||
_remove_point(p)
|
||||
p -= 1
|
||||
if (p < 0): p = 0
|
||||
|
||||
|
||||
max_points = _points.size()
|
||||
p += 1
|
||||
|
||||
|
||||
mesh.clear_surfaces()
|
||||
|
||||
|
||||
# If less than 2 points, stop rendering trail
|
||||
if _points.size() < 2:
|
||||
return
|
||||
|
||||
|
||||
# Render new mesh for each point
|
||||
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
||||
|
||||
|
||||
for i in range(_points.size()):
|
||||
var t = float(i) / (_points.size() - 1.0)
|
||||
var curr_color = _start_color.lerp(_end_color, 1 - t)
|
||||
mesh.surface_set_color(curr_color)
|
||||
|
||||
|
||||
var curr_width = _widths[i][0] - pow(1 - t, _scale_acceleration) * _widths[i][1]
|
||||
|
||||
|
||||
var t0 = i / _points.size()
|
||||
var t1 = t
|
||||
|
||||
|
||||
mesh.surface_set_uv(Vector2(t0, 0))
|
||||
mesh.surface_add_vertex(to_local(_points[i] + curr_width))
|
||||
mesh.surface_set_uv(Vector2(t1, 1))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue