1-6 player splitscreen multiplayer addon
base functionality
| -rw-r--r-- | .github/image.png | bin | 0 -> 353002 bytes | |||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Main.tscn | 29 | ||||
| -rw-r--r-- | README.md | 16 | ||||
| -rw-r--r-- | addons/splitter/screen.gd | 37 | ||||
| -rw-r--r-- | addons/splitter/viewport.gd | 22 | ||||
| -rw-r--r-- | project.godot | 1 | ||||
| -rw-r--r-- | test.gd | 9 |
8 files changed, 112 insertions, 3 deletions
diff --git a/.github/image.png b/.github/image.png Binary files differnew file mode 100644 index 0000000..2e26865 --- /dev/null +++ b/.github/image.png @@ -6,4 +6,3 @@ logs/ .vscode/ exports/ *.x86_64 -addons/ @@ -1,3 +1,28 @@ -[gd_scene format=2] +[gd_scene load_steps=2 format=3 uid="uid://862orftxq81e"] -[node name="Main" type="Node2D"] +[ext_resource type="Script" path="res://test.gd" id="1_ncs1l"] + +[node name="Main" type="Node3D"] + +[node name="CSGBox3D" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.86143, 0, -5.02182) + +[node name="CSGBox3D2" type="CSGBox3D" parent="."] +transform = Transform3D(0.755853, 0.654741, 0, -0.654741, 0.755853, 0, 0, 0, 1, 0, 1.42561, -6.12958) + +[node name="CSGBox3D5" type="CSGBox3D" parent="."] +transform = Transform3D(0.334084, 0.768755, -0.545348, 0.0288089, -0.58665, -0.809328, -0.942103, 0.254672, -0.218137, -0.595417, 0.115944, -3.48055) + +[node name="CSGBox3D3" type="CSGBox3D" parent="."] +transform = Transform3D(0.755853, 0.654741, 0, -0.362328, 0.418283, -0.832921, -0.545348, 0.629566, 0.553392, 1.30623, 0.992493, -8.65402) + +[node name="CSGBox3D4" type="CSGBox3D" parent="."] +transform = Transform3D(0.337242, 0.185292, -0.923003, -0.678851, -0.631421, -0.374793, -0.652249, 0.752977, -0.0871558, -2.09498, 0.478853, -6.66823) + +[node name="Node" type="Node" parent="."] +script = ExtResource("1_ncs1l") + +[node name="OmniLight3D" type="OmniLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5.78558, 0) +light_energy = 16.0 +omni_range = 13.704 @@ -4,3 +4,19 @@ <a href='https://ko-fi.com/bendn' title='Buy me a coffee' target='_blank'><img height='28' src='https://storage.ko-fi.com/cdn/brandasset/kofi_button_red.png' alt='Buy me a coffee'> </a> Small addon for multiplayer splitscreen + +[](_blank "Picture!") + +## Usage + +```GDScript +extends Splitscreen + +func _ready() -> void: + super() + var cam := Camera3D.new() + join().add_child(cam) + await get_tree().create_timer(1).timeout + cam = Camera3D.new() + join().add_child(cam) +``` diff --git a/addons/splitter/screen.gd b/addons/splitter/screen.gd new file mode 100644 index 0000000..343b6a0 --- /dev/null +++ b/addons/splitter/screen.gd @@ -0,0 +1,37 @@ +extends Node +class_name Splitscreen + +var players: Array[PlayerViewport] = [] + +func _ready() -> void: + get_window().size_changed.connect(resize_players) + +func resize_players(): + # plan: + #┌----┐ + #├────┤ + #└────┘ + var size := Vector2(get_window().size) if len(players) == 1 else Vector2(get_window().size.x, get_window().size.y / 2.0) + for p in players: + p.player_count = len(players) + p.size_port(size) + +func join() -> Viewport: + if len(players) > 1: + push_error("no slots") + return + + var player := PlayerViewport.new(len(players) + 1) + player.name = "player %d" % (len(players) + 1) + players.append(player) + add_child(player) + resize_players() + return player.viewport # so you can add a camera + +func leave(id: int) -> void: + var p := players.pop_at(id) + if p == null: + push_error("no player") + return + p.kill() + resize_players() diff --git a/addons/splitter/viewport.gd b/addons/splitter/viewport.gd new file mode 100644 index 0000000..6e73d4c --- /dev/null +++ b/addons/splitter/viewport.gd @@ -0,0 +1,22 @@ +extends TextureRect +class_name PlayerViewport + +var player_count: int +var viewport: Viewport +var id: int + +func _init(_id: int) -> void: + viewport = SubViewport.new() + add_child(viewport) + texture = viewport.get_texture() + id = _id + player_count = _id # id should be count + 1 + +func size_port(to: Vector2) -> void: + viewport.size = to + size = to + global_position = Vector2.ZERO if id == 1 else Vector2(0, size.y) + +func kill() -> void: + viewport.queue_free() + queue_free()
\ No newline at end of file diff --git a/project.godot b/project.godot index 325907f..f3809b5 100644 --- a/project.godot +++ b/project.godot @@ -12,6 +12,7 @@ config_version=5 config/name="splitter" config/description="smol addon to simplify creation of multiplayer splitscreen" +run/main_scene="res://Main.tscn" config/features=PackedStringArray("4.0") [rendering] @@ -0,0 +1,9 @@ +extends Splitscreen + +func _ready() -> void: + super() + var cam := Camera3D.new() + join().add_child(cam) + await get_tree().create_timer(1).timeout + cam = Camera3D.new() + join().add_child(cam)
\ No newline at end of file |