Simple networking

main
Fat mimir 3 years ago committed by Carlos Martínez
commit 74694080b4

2
.gitattributes vendored

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

2
.gitignore vendored

@ -0,0 +1,2 @@
# Godot 4+ specific ignores
.godot/

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(32 32)"><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99z" fill="#363d52"/><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99zm0 4h96c6.64 0 12 5.35 12 11.99v95.98c0 6.64-5.35 11.99-12 11.99h-96c-6.64 0-12-5.35-12-11.99v-95.98c0-6.64 5.36-11.99 12-11.99z" fill-opacity=".4"/></g><g stroke-width="9.92746" transform="matrix(.10073078 0 0 .10073078 12.425923 2.256365)"><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 919.24059 771.67186)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 104.69892 525.90697)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 784.07144 817.24284)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 389.21484 625.67104)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 367.36686 631.05679)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 511.99336 724.73954)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 634.78706 625.67104)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 656.64056 631.05679)"/></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d0grjf1jatuoi"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
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=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

@ -0,0 +1,53 @@
extends Node3D
const Player := preload("res://player.tscn")
@onready
var ui_main_menu := $UIMainMenu
@onready
var players := $Players
func _ready():
pass
func _process(_delta):
pass
func _on_button_start_as_server_pressed():
var peer := ENetMultiplayerPeer.new()
peer.create_server(9080, 10)
peer.peer_connected.connect(self._on_peer_connect)
peer.peer_disconnected.connect(self._on_peer_disconnected)
multiplayer.multiplayer_peer = peer
ui_main_menu.visible = false
# Server connected
_on_peer_connect(get_multiplayer_authority())
func _on_button_start_as_client_pressed():
var peer := ENetMultiplayerPeer.new()
peer.create_client("localhost", 9080)
multiplayer.multiplayer_peer = peer
ui_main_menu.visible = false
func _on_peer_connect(id):
print("(server) peer connected: ", id)
var player: Node3D = Player.instantiate()
player.name = str(id)
player.set_multiplayer_authority(id)
player.global_transform = players.global_transform.translated(Vector3.UP * 3)
players.add_child(player, true)
func _on_peer_disconnected(id):
print("(server) peer disconnected: ", id)
var player := players.get_node_or_null(str(id))
if player:
player.queue_free()

@ -0,0 +1,62 @@
[gd_scene load_steps=3 format=3 uid="uid://cncputkhqxo0m"]
[ext_resource type="Script" path="res://main.gd" id="1_mw2j2"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_p8g5e"]
albedo_color = Color(0.211765, 0.211765, 0.211765, 1)
[node name="Main" type="Node3D"]
script = ExtResource("1_mw2j2")
[node name="Map" type="CSGCombiner3D" parent="."]
use_collision = true
[node name="Floor" type="CSGBox3D" parent="Map"]
size = Vector3(20, 0.1, 20)
material = SubResource("StandardMaterial3D_p8g5e")
[node name="Sun" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.707107, -0.5, 0.5, 0, 0.707107, 0.707107, -0.707107, -0.5, 0.5, -4.68001, 6.95, 4.07778)
shadow_enabled = true
[node name="MainCamera" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 10, 13)
[node name="Players" type="Node3D" parent="."]
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://player.tscn")
spawn_path = NodePath("../Players")
[node name="UIMainMenu" type="ColorRect" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 1)
[node name="ContainerOptions" type="VBoxContainer" parent="UIMainMenu"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
[node name="ButtonStartAsServer" type="Button" parent="UIMainMenu/ContainerOptions"]
layout_mode = 2
text = "Start as server"
[node name="ButtonStartAsClient" type="Button" parent="UIMainMenu/ContainerOptions"]
layout_mode = 2
text = "Start as client"
[connection signal="pressed" from="UIMainMenu/ContainerOptions/ButtonStartAsServer" to="." method="_on_button_start_as_server_pressed"]
[connection signal="pressed" from="UIMainMenu/ContainerOptions/ButtonStartAsClient" to="." method="_on_button_start_as_client_pressed"]

@ -0,0 +1,86 @@
extends CharacterBody3D
# We don't actually want to fully interpolate between states
# since it may result in "jumpy" transitions
const STATE_INTERP_MIN = 0.2
const STATE_INTERP_MAX = 0.8
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var sync_state := PackedByteArray(): get = _get_sync_state, set = _set_sync_state
@export var speed := 5.0
@export var jump_speed := 5.0
@onready var gametag := $Gametag
@onready var target_origin := global_transform.origin
var last_snapshot_tag := 0
var snapshot_interp_start := 0.0
var snapshot_interp_end := 0.0
func _process(_delta):
gametag.text = "[%s %d]" % [name, get_multiplayer_authority()]
func _physics_process(delta):
if is_multiplayer_authority():
velocity.y += -gravity * delta
var input := Input.get_vector("left", "right", "forward", "backward")
var direction := transform.basis * Vector3(input.x, 0, input.y)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
move_and_slide()
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = jump_speed
else:
var interp_value = remap_range(
Time.get_ticks_msec(),
snapshot_interp_start,
snapshot_interp_end,
STATE_INTERP_MIN,
STATE_INTERP_MAX
)
if interp_value >= 0.0 and interp_value <= 1.0:
global_transform.origin = global_transform.origin.slerp(
target_origin, interp_value
)
else:
global_transform.origin = target_origin
func _enter_tree():
if name == str(multiplayer.get_unique_id()):
set_multiplayer_authority(multiplayer.get_unique_id())
func _get_sync_state():
var encoder := PackedByteArray()
encoder.resize(20)
encoder.encode_u64(0, Time.get_ticks_msec())
encoder.encode_float(8, transform.origin.x)
encoder.encode_float(12, transform.origin.y)
encoder.encode_float(16, transform.origin.z)
return encoder
func _set_sync_state(value):
assert(
typeof(value) == TYPE_PACKED_BYTE_ARRAY and value.size() == 20,
"Invalid `sync_state` array type or size (must be TYPE_RAW_ARRAY of size 20)."
)
var time_tag: int = value.decode_u64(0)
if time_tag > last_snapshot_tag:
var snapshot_time_diff = time_tag - last_snapshot_tag
if global_transform:
global_transform.origin = target_origin # Override last origin
snapshot_interp_start = Time.get_ticks_msec()
snapshot_interp_end = Time.get_ticks_msec() + snapshot_time_diff
last_snapshot_tag = time_tag
target_origin = Vector3(
value.decode_float(8),
value.decode_float(12),
value.decode_float(16),
)
func remap_range(value, in_a, in_b, out_a, out_b):
return (value - in_a) / (in_b - in_a) * (out_b - out_a) + out_a

@ -0,0 +1,32 @@
[gd_scene load_steps=5 format=3 uid="uid://cq06n5dnq6xc2"]
[ext_resource type="Script" path="res://player.gd" id="1_dokki"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_k38on"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_wtqcn"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_my5gd"]
properties/0/path = NodePath(".:sync_state")
properties/0/spawn = true
properties/0/sync = true
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_dokki")
[node name="Gametag" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.148, 0)
pixel_size = 0.03
text = "AAAAAAAAAAAAAA"
[node name="CollisionShape" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_k38on")
[node name="MeshInstance" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
mesh = SubResource("CapsuleMesh_wtqcn")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_interval = 0.1
replication_config = SubResource("SceneReplicationConfig_my5gd")

@ -0,0 +1,44 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Godot4 Standard Networking"
run/main_scene="res://main.tscn"
config/features=PackedStringArray("4.0", "Forward Plus")
config/icon="res://icon.svg"
[input]
forward={
"deadzone": 0.5,
"events": [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":87,"key_label":0,"unicode":119,"echo":false,"script":null)
]
}
backward={
"deadzone": 0.5,
"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":83,"key_label":0,"unicode":115,"echo":false,"script":null)
]
}
left={
"deadzone": 0.5,
"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":65,"key_label":0,"unicode":97,"echo":false,"script":null)
]
}
right={
"deadzone": 0.5,
"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":68,"key_label":0,"unicode":100,"echo":false,"script":null)
]
}
jump={
"deadzone": 0.5,
"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":32,"key_label":0,"unicode":32,"echo":false,"script":null)
]
}
Loading…
Cancel
Save