mirror of
https://github.com/Relintai/pandemonium_demo_projects.git
synced 2024-12-21 13:56:50 +01:00
Added the network synchronizer demo from https://github.com/GameNetworking/example-project-3.x .
This commit is contained in:
parent
48a313f79d
commit
d34578c442
5
networking/network_synchronizer/.gitignore
vendored
Normal file
5
networking/network_synchronizer/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Editor cache
|
||||||
|
.godot
|
||||||
|
.import
|
||||||
|
/logs/*
|
||||||
|
|
70
networking/network_synchronizer/Character.gd
Normal file
70
networking/network_synchronizer/Character.gd
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
extends KinematicBody
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------------------- Settings
|
||||||
|
const MOVE_SPEED: int = 10
|
||||||
|
const MOTION_INTERPOLATE_SPEED: int = 20
|
||||||
|
const VELOCITY_INTERPOLATE_SPEED: int = 2
|
||||||
|
const GRAVITY: int = 10
|
||||||
|
const JUMP_IMPULSE: float = 6.0
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------- Vars
|
||||||
|
onready var avatar_container: Spatial = $AvatarContainer
|
||||||
|
onready var _mesh: MeshInstance = $AvatarContainer/Mesh
|
||||||
|
var linear_velocity := Vector3()
|
||||||
|
onready var camera: Camera = $Camera
|
||||||
|
var on_floor: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------- API
|
||||||
|
func set_color(color):
|
||||||
|
var mat = _mesh.get_surface_material(0)
|
||||||
|
if mat == null:
|
||||||
|
mat = SpatialMaterial.new()
|
||||||
|
else:
|
||||||
|
mat = mat.duplicate()
|
||||||
|
mat.set_albedo(Color(color))
|
||||||
|
_mesh.set_surface_material(0, mat)
|
||||||
|
|
||||||
|
|
||||||
|
func update_safe_body_transform():
|
||||||
|
$KinematicBody.transform = transform
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------------ Notifications
|
||||||
|
func _ready():
|
||||||
|
## Avoid colliding with parent
|
||||||
|
$KinematicBody.add_collision_exception_with(self)
|
||||||
|
|
||||||
|
if "player_0" == name:
|
||||||
|
$KinematicBody.collision_layer = 0
|
||||||
|
$KinematicBody.collision_mask = 0
|
||||||
|
|
||||||
|
$AvatarContainer.physics_interpolation_mode = PHYSICS_INTERPOLATION_MODE_ON
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------ Processing internal
|
||||||
|
## Computes one motion step.
|
||||||
|
func step_body(delta: float, input_direction: Vector3, is_jumping: bool):
|
||||||
|
_set_player_orientation(input_direction)
|
||||||
|
|
||||||
|
var motion: Vector3 = input_direction * MOVE_SPEED
|
||||||
|
var new_velocity: Vector3
|
||||||
|
|
||||||
|
if on_floor and linear_velocity.length() < MOVE_SPEED:
|
||||||
|
new_velocity = linear_velocity.linear_interpolate(motion, MOTION_INTERPOLATE_SPEED * delta)
|
||||||
|
if is_jumping:
|
||||||
|
new_velocity.y = new_velocity.y + JUMP_IMPULSE
|
||||||
|
else:
|
||||||
|
new_velocity = linear_velocity.linear_interpolate(motion, VELOCITY_INTERPOLATE_SPEED * delta)
|
||||||
|
new_velocity.y = new_velocity.y - GRAVITY * delta
|
||||||
|
|
||||||
|
if new_velocity.length() > 0.01:
|
||||||
|
linear_velocity = move_and_slide(new_velocity, Vector3(0, 1, 0))
|
||||||
|
on_floor = is_on_floor()
|
||||||
|
|
||||||
|
|
||||||
|
func _set_player_orientation(input_direction):
|
||||||
|
if input_direction.length_squared() < 0.01:
|
||||||
|
return
|
||||||
|
avatar_container.transform = avatar_container.transform.looking_at(input_direction, Vector3(0, 1, 0))
|
52
networking/network_synchronizer/Character.tscn
Normal file
52
networking/network_synchronizer/Character.tscn
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
[gd_scene load_steps=8 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://NetworkedController.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://PlayerCamera.gd" type="Script" id=2]
|
||||||
|
[ext_resource path="res://Character.gd" type="Script" id=3]
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape" id=4]
|
||||||
|
radius = 0.249783
|
||||||
|
height = 1.50094
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleMesh" id=2]
|
||||||
|
radius = 0.25
|
||||||
|
mid_height = 1.5
|
||||||
|
|
||||||
|
[sub_resource type="SpatialMaterial" id=3]
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape" id=5]
|
||||||
|
radius = 0.343218
|
||||||
|
height = 1.47735
|
||||||
|
|
||||||
|
[node name="Character" type="KinematicBody"]
|
||||||
|
script = ExtResource( 3 )
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||||
|
shape = SubResource( 4 )
|
||||||
|
|
||||||
|
[node name="AvatarContainer" type="Spatial" parent="."]
|
||||||
|
|
||||||
|
[node name="Mesh" type="MeshInstance" parent="AvatarContainer"]
|
||||||
|
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||||
|
mesh = SubResource( 2 )
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
material/0 = SubResource( 3 )
|
||||||
|
|
||||||
|
[node name="Camera" type="Camera" parent="."]
|
||||||
|
transform = Transform( -0.707107, 0.454519, -0.541675, 0, 0.766044, 0.642787, 0.707107, 0.454519, -0.541675, -4.12047, 6.30383, -4.13525 )
|
||||||
|
projection = 1
|
||||||
|
size = 15.0
|
||||||
|
near = 0.01
|
||||||
|
far = 2000.0
|
||||||
|
script = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="NetworkedController" type="NetworkedController" parent="."]
|
||||||
|
doll_connection_stats_frame_span = 180
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="KinematicBody" type="KinematicBody" parent="."]
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="KinematicBody"]
|
||||||
|
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||||
|
shape = SubResource( 5 )
|
21
networking/network_synchronizer/LICENSE
Normal file
21
networking/network_synchronizer/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 GodotNetworking
|
||||||
|
|
||||||
|
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.
|
106
networking/network_synchronizer/MainScene.gd
Normal file
106
networking/network_synchronizer/MainScene.gd
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------------------- Settings
|
||||||
|
const SERVER_PORT = 2000
|
||||||
|
const MAX_PLAYERS = 5
|
||||||
|
const SERVER_IP = "127.0.0.1"
|
||||||
|
const COLORS_LIST = [
|
||||||
|
"#0ad609",
|
||||||
|
"#f0bf58",
|
||||||
|
"#1120d3",
|
||||||
|
"#704c28",
|
||||||
|
"#2af4ce"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------- Vars
|
||||||
|
onready var _menu: Control = $Menu
|
||||||
|
onready var _session_type_lbl: Label = $SessionTypeLbl
|
||||||
|
|
||||||
|
var _player_id_counter = 0
|
||||||
|
var _players = {}
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------------- UI functions
|
||||||
|
func _start_server():
|
||||||
|
_menu.hide()
|
||||||
|
_session_type_lbl.text = "Server"
|
||||||
|
|
||||||
|
var peer = NetworkedMultiplayerENet.new()
|
||||||
|
peer.create_server(SERVER_PORT, MAX_PLAYERS)
|
||||||
|
get_tree().network_peer = peer
|
||||||
|
get_tree().connect("network_peer_connected", self, "_on_client_connected")
|
||||||
|
get_tree().connect("network_peer_disconnected", self, "_on_client_disconnected")
|
||||||
|
print("Server IP: ", IP.get_local_addresses())
|
||||||
|
|
||||||
|
|
||||||
|
func _start_client():
|
||||||
|
_menu.hide()
|
||||||
|
_session_type_lbl.text = "Client"
|
||||||
|
|
||||||
|
var peer = NetworkedMultiplayerENet.new()
|
||||||
|
peer.create_client(SERVER_IP, SERVER_PORT)
|
||||||
|
get_tree().network_peer = peer
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------- Server only internal functions
|
||||||
|
func _on_client_connected(peer_id):
|
||||||
|
print("Connected: ", peer_id)
|
||||||
|
var new_player_id = _player_id_counter
|
||||||
|
_player_id_counter += 1
|
||||||
|
_players[new_player_id] = {"peer_id": peer_id, "player_id": new_player_id}
|
||||||
|
|
||||||
|
# Spawn player on server, for server any player is puppet (even if it's
|
||||||
|
# autoritative)
|
||||||
|
_spawn_new_player(new_player_id, peer_id)
|
||||||
|
|
||||||
|
# Spawn the player on the client
|
||||||
|
rpc_id(peer_id, "_spawn_new_player", new_player_id, peer_id)
|
||||||
|
|
||||||
|
# Tell anyone new player appeared
|
||||||
|
for player_id in _players.keys():
|
||||||
|
if _players[player_id]["peer_id"] != peer_id:
|
||||||
|
rpc_id(_players[player_id]["peer_id"], "_spawn_new_player", new_player_id, 1)
|
||||||
|
|
||||||
|
# Spawn the actual _players on this client
|
||||||
|
for player_id in _players.keys():
|
||||||
|
if player_id != new_player_id:
|
||||||
|
rpc_id(peer_id, "_spawn_new_player", player_id, 1)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_client_disconnected(peer_id):
|
||||||
|
print("Disconnected: ", peer_id)
|
||||||
|
|
||||||
|
var disconnected_player_id = -1
|
||||||
|
for player_id in _players.keys():
|
||||||
|
if _players[player_id]["peer_id"] == peer_id:
|
||||||
|
disconnected_player_id = player_id
|
||||||
|
break
|
||||||
|
|
||||||
|
if disconnected_player_id == -1:
|
||||||
|
return
|
||||||
|
|
||||||
|
_players.erase(disconnected_player_id)
|
||||||
|
_remove_player(disconnected_player_id)
|
||||||
|
|
||||||
|
# Tell anyone player disappeared
|
||||||
|
for player_id in _players.keys():
|
||||||
|
rpc_id(_players[player_id]["peer_id"], "_remove_player", disconnected_player_id)
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------- Remote functions
|
||||||
|
remote func _spawn_new_player(player_id, peer_id):
|
||||||
|
print("Spawn player id: ", player_id, ", Peer_id: ", peer_id)
|
||||||
|
print("While my peer id is: ", get_tree().multiplayer.network_peer.get_unique_id())
|
||||||
|
|
||||||
|
var character = load("res://Character.tscn").instance()
|
||||||
|
character.set_network_master(peer_id)
|
||||||
|
character.set_name("player_" + str(player_id))
|
||||||
|
get_tree().get_current_scene().add_child(character)
|
||||||
|
character.set_color(COLORS_LIST[player_id])
|
||||||
|
|
||||||
|
|
||||||
|
remote func _remove_player(player_id):
|
||||||
|
var player_node = get_tree().get_current_scene().get_node("player_" + str(player_id))
|
||||||
|
if player_node != null:
|
||||||
|
player_node.queue_free()
|
107
networking/network_synchronizer/MainScene.tscn
Normal file
107
networking/network_synchronizer/MainScene.tscn
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
[gd_scene load_steps=10 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://MainScene.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://aerial_rocks_02_diff_4k.jpg" type="Texture" id=2]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSky" id=1]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id=2]
|
||||||
|
background_mode = 2
|
||||||
|
background_sky = SubResource( 1 )
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape" id=3]
|
||||||
|
extents = Vector3( 50, 0.25, 50 )
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id=4]
|
||||||
|
size = Vector2( 100, 100 )
|
||||||
|
|
||||||
|
[sub_resource type="SpatialMaterial" id=5]
|
||||||
|
albedo_texture = ExtResource( 2 )
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape" id=6]
|
||||||
|
radius = 0.25
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleMesh" id=7]
|
||||||
|
radius = 0.25
|
||||||
|
|
||||||
|
[node name="Node" type="Node"]
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource( 2 )
|
||||||
|
|
||||||
|
[node name="DirectionalLight" type="DirectionalLight" parent="."]
|
||||||
|
transform = Transform( 0.942496, -0.163932, -0.291253, 0.331754, 0.35325, 0.874731, -0.0405109, -0.921054, 0.387322, 0, 29.9334, 0 )
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="Floor" type="StaticBody" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.03388, 0 )
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="Floor"]
|
||||||
|
shape = SubResource( 3 )
|
||||||
|
|
||||||
|
[node name="MeshInstance" type="MeshInstance" parent="Floor"]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.235271, 0 )
|
||||||
|
mesh = SubResource( 4 )
|
||||||
|
material/0 = SubResource( 5 )
|
||||||
|
|
||||||
|
[node name="SessionTypeLbl" type="Label" parent="."]
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
margin_left = -20.0
|
||||||
|
margin_right = 20.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
custom_colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
|
text = "None"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="Menu" type="Control" parent="."]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="Menu"]
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
margin_left = -103.0
|
||||||
|
margin_top = -7.0
|
||||||
|
margin_right = 112.0
|
||||||
|
margin_bottom = 13.0
|
||||||
|
rect_pivot_offset = Vector2( 0.5, 0.5 )
|
||||||
|
|
||||||
|
[node name="ServerButton" type="Button" parent="Menu/HBoxContainer"]
|
||||||
|
margin_right = 103.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
custom_colors/font_color = Color( 0, 1, 0.262745, 1 )
|
||||||
|
text = "Start as Server"
|
||||||
|
|
||||||
|
[node name="VSeparator" type="VSeparator" parent="Menu/HBoxContainer"]
|
||||||
|
margin_left = 107.0
|
||||||
|
margin_right = 111.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
|
||||||
|
[node name="ClientButton" type="Button" parent="Menu/HBoxContainer"]
|
||||||
|
margin_left = 115.0
|
||||||
|
margin_right = 215.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
custom_colors/font_color = Color( 0, 0.988235, 1, 1 )
|
||||||
|
text = "Start as Client"
|
||||||
|
|
||||||
|
[node name="Camera" type="Camera" parent="."]
|
||||||
|
transform = Transform( -0.707107, 0.353553, -0.612372, 0, 0.866025, 0.5, 0.707107, 0.353553, -0.612372, -71.053, 66.4778, -71.053 )
|
||||||
|
projection = 1
|
||||||
|
size = 50.0
|
||||||
|
far = 2000.0
|
||||||
|
|
||||||
|
[node name="StaticBody" type="StaticBody" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.772334, 2.46257 )
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="StaticBody"]
|
||||||
|
shape = SubResource( 6 )
|
||||||
|
|
||||||
|
[node name="MeshInstance" type="MeshInstance" parent="StaticBody"]
|
||||||
|
mesh = SubResource( 7 )
|
||||||
|
|
||||||
|
[connection signal="pressed" from="Menu/HBoxContainer/ServerButton" to="." method="_start_server"]
|
||||||
|
[connection signal="pressed" from="Menu/HBoxContainer/ClientButton" to="." method="_start_client"]
|
1
networking/network_synchronizer/NetworkSync.gd
Normal file
1
networking/network_synchronizer/NetworkSync.gd
Normal file
@ -0,0 +1 @@
|
|||||||
|
extends SceneSynchronizer
|
133
networking/network_synchronizer/NetworkedController.gd
Normal file
133
networking/network_synchronizer/NetworkedController.gd
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
extends NetworkedController
|
||||||
|
# Take cares to control the player and propagate the motion on the other peers
|
||||||
|
|
||||||
|
|
||||||
|
const MAX_PLAYER_DISTANCE: float = 20.0
|
||||||
|
|
||||||
|
var _position_id := -1
|
||||||
|
var _rotation_id := -1
|
||||||
|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Notify the NetworkSync who is controlling parent nodes.
|
||||||
|
NetworkSync.set_node_as_controlled_by(get_parent(), self)
|
||||||
|
NetworkSync.register_variable(get_parent(), "translation")
|
||||||
|
NetworkSync.register_variable(get_parent(), "linear_velocity")
|
||||||
|
NetworkSync.register_variable(get_parent(), "on_floor")
|
||||||
|
if not get_tree().multiplayer.is_network_server():
|
||||||
|
set_physics_process(false)
|
||||||
|
|
||||||
|
|
||||||
|
func _physics_process(_delta):
|
||||||
|
"""
|
||||||
|
# Changes the character relevancy to scale the net traffic depending on the character
|
||||||
|
importance.
|
||||||
|
for character in get_tree().get_nodes_in_group("characters"):
|
||||||
|
if character != get_parent():
|
||||||
|
var delta_distance = character.get_global_transform().origin - get_parent().get_global_transform().origin
|
||||||
|
|
||||||
|
var is_far_away = delta_distance.length_squared() > (MAX_PLAYER_DISTANCE * MAX_PLAYER_DISTANCE)
|
||||||
|
set_doll_peer_active(character.get_network_master(), !is_far_away);
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
func _collect_inputs(_delta: float, db: DataBuffer):
|
||||||
|
# Collects the player inputs.
|
||||||
|
|
||||||
|
var input_direction := Vector3()
|
||||||
|
var is_jumping: bool = false
|
||||||
|
|
||||||
|
if Input.is_action_pressed("forward"):
|
||||||
|
input_direction -= get_parent().camera.global_transform.basis.z
|
||||||
|
if Input.is_action_pressed("backward"):
|
||||||
|
input_direction += get_parent().camera.global_transform.basis.z
|
||||||
|
if Input.is_action_pressed("left"):
|
||||||
|
input_direction -= get_parent().camera.global_transform.basis.x
|
||||||
|
if Input.is_action_pressed("right"):
|
||||||
|
input_direction += get_parent().camera.global_transform.basis.x
|
||||||
|
if Input.is_action_pressed("jump"):
|
||||||
|
is_jumping = true
|
||||||
|
input_direction.y = 0
|
||||||
|
input_direction = input_direction.normalized()
|
||||||
|
|
||||||
|
db.add_bool(is_jumping)
|
||||||
|
|
||||||
|
var has_input: bool = input_direction.length_squared() > 0.0
|
||||||
|
db.add_bool(has_input)
|
||||||
|
if has_input:
|
||||||
|
db.add_normalized_vector2(Vector2(input_direction.x, input_direction.z), DataBuffer.COMPRESSION_LEVEL_3)
|
||||||
|
|
||||||
|
|
||||||
|
func _controller_process(delta: float, db: DataBuffer):
|
||||||
|
# Process the controller.
|
||||||
|
|
||||||
|
# Take the inputs
|
||||||
|
var is_jumping = db.read_bool()
|
||||||
|
var input_direction := Vector2()
|
||||||
|
|
||||||
|
var has_input = db.read_bool()
|
||||||
|
if has_input:
|
||||||
|
input_direction = db.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3)
|
||||||
|
|
||||||
|
var initial_transform: Vector3 = get_parent().transform.origin
|
||||||
|
|
||||||
|
# Process the character
|
||||||
|
get_parent().step_body(delta, Vector3(input_direction.x, 0.0, input_direction.y), is_jumping)
|
||||||
|
|
||||||
|
var after_transform: Vector3 = get_parent().transform.origin
|
||||||
|
|
||||||
|
var mode = "Client"
|
||||||
|
if is_server_controller():
|
||||||
|
mode = "Server"
|
||||||
|
|
||||||
|
mode = ""
|
||||||
|
|
||||||
|
#if "player_0" == get_parent().name:
|
||||||
|
# print(get_parent().name, " ", mode, ", Input: ", get_current_input_id(), " Delta: ", delta, " Dir: ", Vector3(input_direction.x, 0.0, input_direction.y), " Jump: ", is_jumping, " - Initial t ", initial_transform, " result t", after_transform)
|
||||||
|
|
||||||
|
|
||||||
|
func _count_input_size(inputs: DataBuffer) -> int:
|
||||||
|
# Count the input buffer size.
|
||||||
|
var size: int = 0
|
||||||
|
size += inputs.get_bool_size()
|
||||||
|
inputs.skip_bool()
|
||||||
|
size += inputs.get_bool_size()
|
||||||
|
if inputs.read_bool():
|
||||||
|
size += inputs.get_normalized_vector2_size(DataBuffer.COMPRESSION_LEVEL_3)
|
||||||
|
|
||||||
|
return size
|
||||||
|
|
||||||
|
|
||||||
|
func _are_inputs_different(inputs_A: DataBuffer, inputs_B: DataBuffer) -> bool:
|
||||||
|
# Compare two inputs, returns true when those are different or false when are close enough.
|
||||||
|
if inputs_A.read_bool() != inputs_B.read_bool():
|
||||||
|
return true
|
||||||
|
|
||||||
|
var inp_A_has_i = inputs_A.read_bool()
|
||||||
|
var inp_B_has_i = inputs_B.read_bool()
|
||||||
|
if inp_A_has_i != inp_B_has_i:
|
||||||
|
return true
|
||||||
|
|
||||||
|
if inp_A_has_i:
|
||||||
|
var inp_A_dir = inputs_A.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3)
|
||||||
|
var inp_B_dir = inputs_B.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3)
|
||||||
|
if (inp_A_dir - inp_B_dir).length_squared() > 0.0001:
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
func _collect_epoch_data(buffer: DataBuffer):
|
||||||
|
buffer.add_vector3(get_parent().global_transform.origin, DataBuffer.COMPRESSION_LEVEL_0)
|
||||||
|
buffer.add_vector3(get_parent().avatar_container.rotation, DataBuffer.COMPRESSION_LEVEL_2)
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_epoch(_delta: float, alpha: float, past_buffer: DataBuffer, future_buffer: DataBuffer):
|
||||||
|
var past_position := past_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_0)
|
||||||
|
var past_rotation := past_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_2)
|
||||||
|
|
||||||
|
var future_position := future_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_0)
|
||||||
|
var future_rotation := future_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_2)
|
||||||
|
|
||||||
|
get_parent().global_transform.origin = lerp(past_position, future_position, alpha)
|
||||||
|
get_parent().avatar_container.rotation = lerp(past_rotation, future_rotation, alpha)
|
8
networking/network_synchronizer/PlayerCamera.gd
Normal file
8
networking/network_synchronizer/PlayerCamera.gd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
extends Camera
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
if is_network_master():
|
||||||
|
current = true
|
||||||
|
else:
|
||||||
|
set_process_input(false)
|
BIN
networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg
Normal file
BIN
networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 MiB |
@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path.s3tc="res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.s3tc.stex"
|
||||||
|
path.etc2="res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.etc2.stex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": [ "s3tc", "etc2" ],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://aerial_rocks_02_diff_4k.jpg"
|
||||||
|
dest_files=[ "res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.s3tc.stex", "res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.etc2.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=true
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=true
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=1
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=false
|
||||||
|
svg/scale=1.0
|
7
networking/network_synchronizer/default_env.tres
Normal file
7
networking/network_synchronizer/default_env.tres
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[gd_resource type="Environment" load_steps=2 format=2]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSky" id=1]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
background_mode = 2
|
||||||
|
background_sky = SubResource( 1 )
|
BIN
networking/network_synchronizer/icon.png
Normal file
BIN
networking/network_synchronizer/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
35
networking/network_synchronizer/icon.png.import
Normal file
35
networking/network_synchronizer/icon.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://icon.png"
|
||||||
|
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
92
networking/network_synchronizer/project.pandemonium
Normal file
92
networking/network_synchronizer/project.pandemonium
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
; 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=4
|
||||||
|
|
||||||
|
_global_script_classes=[ {
|
||||||
|
"base": "SpringArm3D",
|
||||||
|
"class": @"PlayerCamera",
|
||||||
|
"language": @"GDScript",
|
||||||
|
"path": "res://player_camera.gd"
|
||||||
|
} ]
|
||||||
|
_global_script_class_icons={
|
||||||
|
@"PlayerCamera": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetworkSynchronizer]
|
||||||
|
|
||||||
|
debug_doll_speedup=true
|
||||||
|
|
||||||
|
[application]
|
||||||
|
|
||||||
|
config/name="NetSyncTest3.x"
|
||||||
|
run/main_scene="res://MainScene.tscn"
|
||||||
|
config/icon="res://icon.png"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
NetworkSync="*res://NetworkSync.gd"
|
||||||
|
|
||||||
|
[display]
|
||||||
|
|
||||||
|
window/size/width=640
|
||||||
|
window/size/height=400
|
||||||
|
window/dpi/allow_hidpi=true
|
||||||
|
window/stretch/mode="2d"
|
||||||
|
window/stretch/aspect="expand"
|
||||||
|
stretch_2d=true
|
||||||
|
|
||||||
|
[editor]
|
||||||
|
|
||||||
|
main_run_args="--server"
|
||||||
|
|
||||||
|
[gdnative]
|
||||||
|
|
||||||
|
singletons=[ ]
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
forward={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":87,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
backward={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":83,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
left={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":65,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
right={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
jump={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":32,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
[layer_names]
|
||||||
|
|
||||||
|
3d_physics/layer_1="Common"
|
||||||
|
3d_physics/layer_2="Player"
|
||||||
|
|
||||||
|
[physics]
|
||||||
|
|
||||||
|
common/physics_jitter_fix=0.0
|
||||||
|
common/enable_pause_aware_picking=true
|
||||||
|
|
||||||
|
[rendering]
|
||||||
|
|
||||||
|
environment/default_environment="res://default_env.tres"
|
Loading…
Reference in New Issue
Block a user