[1] feat: add interactions system #1

Merged
Filip merged 4 commits from feature/1-add-interactions into master 2026-08-26 17:46:49 +00:00
13 changed files with 524 additions and 1 deletions
Showing only changes of commit bed12ad335 - Show all commits
+20
View File
@@ -66,6 +66,26 @@ move_down={
"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":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) "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":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
] ]
} }
interact={
"deadzone": 0.2,
"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":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
]
}
use_left_hand={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
use_right_hand={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
drop_modifier={
"deadzone": 0.2,
"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":71,"key_label":0,"unicode":103,"location":0,"echo":false,"script":null)
]
}
[physics] [physics]
@@ -0,0 +1,223 @@
using System.Collections.Generic;
using Game.Features.Interactions.Contracts;
using Game.Features.Items.Contracts;
using Game.Features.Players.Contracts;
using Game.Godot;
using Game.Godot.Extensions;
using Game.Godot.Mappings;
using Godot;
namespace Game.Features.Interactions.Godot;
public partial class PlayerInteractionController : Node, IItemSpawnPoint
{
[Export] public Camera3D Camera;
[Export] public CharacterBody3D Body;
[Export] public InteractionRaycaster InteractionRaycaster;
[Export] public RayCast3D DropRaycaster;
[Export] public InteractionPromptController PromptController;
[Export] public Node3D LeftHandAnchor;
[Export] public Node3D RightHandAnchor;
private IItemInteractionService _items;
private IInteractionService _interactions;
private PlayerId _playerId;
private readonly HashSet<Hand> _dropActions = [];
private readonly Dictionary<Hand, InteractionTargetId?> _activeUseTargets = [];
public override void _Ready()
{
this.AssertRequiredExports();
}
public void Initialize(
PlayerId playerId,
IItemInteractionService items,
IInteractionService interactions
)
{
_playerId = playerId;
_items = items;
_interactions = interactions;
}
public override void _Process(double delta)
{
if (_items is null || _interactions is null || GamePause.IsPaused || !MouseCapture.IsCaptured)
{
PromptController.Clear();
return;
}
UpdatePrompt();
}
public override void _UnhandledInput(InputEvent @event)
{
if (_items is null || _interactions is null || GamePause.IsPaused || !MouseCapture.IsCaptured)
{
return;
}
if (@event.IsActionPressed(InputAction.UseLeftHand.ActionName()))
{
ProcessHandActionStarted(Hand.Left);
GetViewport().SetInputAsHandled();
return;
}
if (@event.IsActionReleased(InputAction.UseLeftHand.ActionName()))
{
ProcessHandActionCompleted(Hand.Left);
GetViewport().SetInputAsHandled();
return;
}
if (@event.IsActionPressed(InputAction.UseRightHand.ActionName()))
{
ProcessHandActionStarted(Hand.Right);
GetViewport().SetInputAsHandled();
return;
}
if (@event.IsActionReleased(InputAction.UseRightHand.ActionName()))
{
ProcessHandActionCompleted(Hand.Right);
GetViewport().SetInputAsHandled();
return;
}
if (@event.IsActionPressed(InputAction.Interact.ActionName()))
{
IInteractionTarget target = InteractionRaycaster.GetTarget<IInteractionTarget>();
if (target?.CanInteract == true)
{
_interactions.TryInteract(new InteractionRequest(_playerId, target.Id));
}
GetViewport().SetInputAsHandled();
}
}
public Vector3 GetItemSpawnPosition() => CalculateDropPosition();
private void ProcessHandActionStarted(Hand hand)
{
if (Input.IsActionPressed(InputAction.DropModifier.ActionName()))
{
if (_activeUseTargets.Remove(hand, out InteractionTargetId? activeTargetId))
{
_items.TryUse(new ItemUseRequest(
_playerId,
hand,
ItemActionPhase.Cancelled,
activeTargetId
));
}
_items.TryDrop(hand, CalculateDropPosition());
_dropActions.Add(hand);
return;
}
if (!_items.IsHandFree(hand))
{
ItemUseRequest request = CreateUseRequest(hand, ItemActionPhase.Started);
ItemActionResult result = _items.TryUse(request);
if (result.Success)
{
_activeUseTargets[hand] = request.TargetId;
}
return;
}
IPickupTarget target = InteractionRaycaster.GetTarget<IPickupTarget>();
if (target is not null)
{
_items.TryPickup(target.ItemInfo.Id, hand);
}
}
private void ProcessHandActionCompleted(Hand hand)
{
if (_dropActions.Remove(hand))
{
return;
}
if (_activeUseTargets.Remove(hand, out InteractionTargetId? targetId))
{
_items.TryUse(new ItemUseRequest(_playerId, hand, ItemActionPhase.Completed, targetId));
}
}
private ItemUseRequest CreateUseRequest(Hand hand, ItemActionPhase phase)
{
InteractionTargetId? targetId = InteractionRaycaster.GetTarget<IInteractionTarget>()?.Id;
return new ItemUseRequest(_playerId, hand, phase, targetId);
}
private Vector3 CalculateDropPosition()
{
DropRaycaster.ForceRaycastUpdate();
Vector3 origin = Camera.GlobalPosition;
Vector3 direction = -Camera.GlobalBasis.Z.Normalized();
float distance = DropRaycaster.TargetPosition.Length();
if (DropRaycaster.IsColliding())
{
distance = Mathf.Max(0.25f, origin.DistanceTo(DropRaycaster.GetCollisionPoint()) - 0.2f);
}
return origin + direction * distance;
}
private void UpdatePrompt()
{
IPickupTarget pickupTarget = InteractionRaycaster.GetTarget<IPickupTarget>();
if (pickupTarget is not null)
{
ShowPickupPrompt(pickupTarget.ItemInfo);
return;
}
IInteractionTarget interactionTarget = InteractionRaycaster.GetTarget<IInteractionTarget>();
if (interactionTarget?.CanInteract == true)
{
PromptController.ShowPrompt($"[E] {interactionTarget.Prompt.Text}");
return;
}
PromptController.Clear();
}
private void ShowPickupPrompt(ItemInfo itemInfo)
{
if (itemInfo.HandRequirement == HandRequirement.Both)
{
bool bothHandsFree = _items.IsHandFree(Hand.Left) && _items.IsHandFree(Hand.Right);
PromptController.ShowPrompt(bothHandsFree
? $"[LPM lub PPM] Podnieś {itemInfo.DisplayName} — obie ręce"
: "Potrzebujesz obu wolnych rąk");
return;
}
List<string> actions = [];
if (_items.IsHandFree(Hand.Left))
{
actions.Add($"[LPM] Podnieś {itemInfo.DisplayName} — lewa ręka");
}
if (_items.IsHandFree(Hand.Right))
{
actions.Add($"[PPM] Podnieś {itemInfo.DisplayName} — prawa ręka");
}
PromptController.ShowPrompt(actions.Count > 0
? string.Join("\n", actions)
: "Brak wolnej ręki");
}
}
@@ -0,0 +1 @@
uid://c2v8m5r1y7q4d
@@ -0,0 +1,19 @@
using Game.Features.Items.Contracts;
namespace Game.Features.Items.Domain.Flashlight;
public sealed class FlashlightItemInstance(ItemInfo info) : IItemInstance
{
public ItemInfo Info { get; } = info;
public bool IsOn { get; private set; }
public ItemActionResult Use(ItemUseRequest request)
{
if (request.Phase == ItemActionPhase.Started)
{
IsOn = !IsOn;
}
return ItemActionResult.Ok();
}
}
@@ -0,0 +1 @@
uid://b8r2n5q9w4m1y
@@ -0,0 +1,26 @@
[gd_scene load_steps=3 format=3 uid="uid://dy6p2w9m4c8kr"]
[sub_resource type="StandardMaterial3D" id="Material_flashlight"]
albedo_color = Color(0.08, 0.09, 0.1, 1)
metallic = 0.65
roughness = 0.3
[sub_resource type="CylinderMesh" id="Mesh_flashlight"]
material = SubResource("Material_flashlight")
top_radius = 0.055
bottom_radius = 0.07
height = 0.32
radial_segments = 12
[node name="FlashlightHeldView" type="Node3D"]
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, -0.08)
mesh = SubResource("Mesh_flashlight")
[node name="SpotLight3D" type="SpotLight3D" parent="."]
visible = false
light_energy = 3.0
shadow_enabled = true
spot_range = 14.0
spot_angle = 24.0
@@ -0,0 +1,47 @@
[gd_scene load_steps=6 format=3 uid="uid://cv8m3q1y6r4nf"]
[ext_resource type="Script" uid="uid://a5q9y2d7m4v8p" path="res://src/Features/Items/Godot/Flashlight/FlashlightItemController.cs" id="1_script"]
[ext_resource type="PackedScene" uid="uid://dy6p2w9m4c8kr" path="res://src/Features/Items/Godot/Flashlight/FlashlightHeldView.tscn" id="2_held"]
[sub_resource type="StandardMaterial3D" id="Material_flashlight"]
albedo_color = Color(0.08, 0.09, 0.1, 1)
metallic = 0.65
roughness = 0.3
[sub_resource type="CylinderMesh" id="Mesh_flashlight"]
material = SubResource("Material_flashlight")
top_radius = 0.055
bottom_radius = 0.07
height = 0.32
radial_segments = 12
[sub_resource type="CapsuleShape3D" id="Shape_flashlight"]
radius = 0.07
height = 0.32
[node name="FlashlightItem" type="RigidBody3D" node_paths=PackedStringArray("Collision", "WorldVisual", "WorldLight")]
mass = 0.4
script = ExtResource("1_script")
DefinitionId = "flashlight"
DisplayName = "latarkę"
Collision = NodePath("CollisionShape3D")
WorldVisual = NodePath("WorldVisual")
HeldViewScene = ExtResource("2_held")
WorldLight = NodePath("WorldVisual/SpotLight3D")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0)
shape = SubResource("Shape_flashlight")
[node name="WorldVisual" type="Node3D" parent="."]
[node name="MeshInstance3D" type="MeshInstance3D" parent="WorldVisual"]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0)
mesh = SubResource("Mesh_flashlight")
[node name="SpotLight3D" type="SpotLight3D" parent="WorldVisual"]
visible = false
light_energy = 3.0
shadow_enabled = true
spot_range = 14.0
spot_angle = 24.0
@@ -0,0 +1,39 @@
using Game.Features.Items.Contracts;
using Game.Features.Items.Domain.Flashlight;
using Game.Features.Items.Godot;
using Godot;
namespace Game.Features.Items.Godot.Flashlight;
public partial class FlashlightItemController : WorldItemController
{
[Export] public SpotLight3D WorldLight;
private SpotLight3D _heldLight;
protected override IItemInstance CreateItemInstance(ItemInfo itemInfo) => new FlashlightItemInstance(itemInfo);
protected override void OnHeldViewCreated(Node3D heldView)
{
_heldLight = heldView.GetNodeOrNull<SpotLight3D>("SpotLight3D");
}
protected override void OnHeldViewRemoving(Node3D heldView)
{
_heldLight = null;
}
protected override void OnPresentationChanged(IItemInstance item)
{
bool isOn = item is FlashlightItemInstance flashlight && flashlight.IsOn;
if (WorldLight is not null)
{
WorldLight.Visible = isOn && !IsHeld;
}
if (_heldLight is not null)
{
_heldLight.Visible = isOn;
}
}
}
@@ -0,0 +1 @@
uid://a5q9y2d7m4v8p
@@ -2,6 +2,9 @@
[ext_resource type="Script" uid="uid://mjm7ghkibnxa" path="res://src/Features/Players/Godot/PlayerController.cs" id="1_gkqfc"] [ext_resource type="Script" uid="uid://mjm7ghkibnxa" path="res://src/Features/Players/Godot/PlayerController.cs" id="1_gkqfc"]
[ext_resource type="Texture2D" uid="uid://bymgknsy145ap" path="res://assets/models/simple-character-psx_character_256.png" id="2_tduai"] [ext_resource type="Texture2D" uid="uid://bymgknsy145ap" path="res://assets/models/simple-character-psx_character_256.png" id="2_tduai"]
[ext_resource type="Script" uid="uid://c2v8m5r1y7q4d" path="res://src/Features/Interactions/Godot/PlayerInteractionController.cs" id="3_interaction"]
[ext_resource type="Script" uid="uid://e4m7k1x8c3q6h" path="res://src/Features/Interactions/Godot/InteractionRaycaster.cs" id="4_raycaster"]
[ext_resource type="Script" uid="uid://b9r2w6n4f8k1v" path="res://src/Features/Interactions/Godot/InteractionPromptController.cs" id="5_prompt"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_130ks"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_130ks"]
radius = 0.25 radius = 0.25
@@ -775,3 +778,82 @@ skeleton = NodePath("..")
[node name="Camera3D" type="Camera3D" parent="CharacterBody3D" unique_id=718409984] [node name="Camera3D" type="Camera3D" parent="CharacterBody3D" unique_id=718409984]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.817, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.817, 0)
cull_mask = 1048573 cull_mask = 1048573
[node name="LeftHandAnchor" type="Node3D" parent="CharacterBody3D/Camera3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.22, -0.2, -0.48)
[node name="RightHandAnchor" type="Node3D" parent="CharacterBody3D/Camera3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.22, -0.2, -0.48)
[node name="InteractionRaycaster" type="RayCast3D" parent="CharacterBody3D/Camera3D"]
enabled = true
target_position = Vector3(0, 0, -2.5)
collide_with_areas = true
script = ExtResource("4_raycaster")
[node name="DropRaycaster" type="RayCast3D" parent="CharacterBody3D/Camera3D"]
enabled = true
target_position = Vector3(0, 0, -1)
collide_with_areas = true
[node name="PlayerInteraction" type="Node" parent="." node_paths=PackedStringArray("Camera", "Body", "InteractionRaycaster", "DropRaycaster", "PromptController", "LeftHandAnchor", "RightHandAnchor")]
script = ExtResource("3_interaction")
Camera = NodePath("../CharacterBody3D/Camera3D")
Body = NodePath("../CharacterBody3D")
InteractionRaycaster = NodePath("../CharacterBody3D/Camera3D/InteractionRaycaster")
DropRaycaster = NodePath("../CharacterBody3D/Camera3D/DropRaycaster")
PromptController = NodePath("InteractionUi")
LeftHandAnchor = NodePath("../CharacterBody3D/Camera3D/LeftHandAnchor")
RightHandAnchor = NodePath("../CharacterBody3D/Camera3D/RightHandAnchor")
[node name="InteractionUi" type="CanvasLayer" parent="PlayerInteraction" node_paths=PackedStringArray("PromptLabel")]
layer = 50
script = ExtResource("5_prompt")
PromptLabel = NodePath("Root/Prompt")
[node name="Root" type="Control" parent="PlayerInteraction/InteractionUi"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Crosshair" type="Label" parent="PlayerInteraction/InteractionUi/Root"]
layout_mode = 0
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -10.0
offset_top = -15.0
offset_right = 10.0
offset_bottom = 15.0
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 18
text = "+"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Prompt" type="Label" parent="PlayerInteraction/InteractionUi/Root"]
layout_mode = 0
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -320.0
offset_top = 34.0
offset_right = 320.0
offset_bottom = 94.0
grow_horizontal = 2
grow_vertical = 2
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
theme_override_constants/shadow_offset_x = 2
theme_override_constants/shadow_offset_y = 2
theme_override_font_sizes/font_size = 16
horizontal_alignment = 1
vertical_alignment = 1
+28
View File
@@ -1,9 +1,16 @@
using System;
using Game.Features.Console.Application.Commands; using Game.Features.Console.Application.Commands;
using Game.Features.Console.Godot; using Game.Features.Console.Godot;
using Game.Features.Console.Infrastructure; using Game.Features.Console.Infrastructure;
using Game.Features.Logging.Godot; using Game.Features.Logging.Godot;
using Game.Features.Logging.Infrastructure; using Game.Features.Logging.Infrastructure;
using Game.Features.Interactions.Application;
using Game.Features.Interactions.Godot;
using Game.Features.Items.Application;
using Game.Features.Items.Domain;
using Game.Features.Items.Godot;
using Game.Features.Multiplayer.Godot; using Game.Features.Multiplayer.Godot;
using Game.Features.Players.Contracts;
using Game.Features.Players.Godot; using Game.Features.Players.Godot;
using Game.Godot.Extensions; using Game.Godot.Extensions;
using Game.Godot.Mappings; using Game.Godot.Mappings;
@@ -15,6 +22,10 @@ public partial class GameBootstrap : Node
{ {
[Export] public ConsoleController Console; [Export] public ConsoleController Console;
[Export] public PlayerController Player; [Export] public PlayerController Player;
[Export] public PlayerInteractionController PlayerInteraction;
[Export] public ItemWorldController ItemWorld;
[Export] public ItemSpawnerController ItemSpawner;
[Export] public InteractionWorldController InteractionWorld;
[Export] public MultiplayerController MultiplayerController; [Export] public MultiplayerController MultiplayerController;
private FileLogger _fileLogger; private FileLogger _fileLogger;
@@ -53,6 +64,22 @@ public partial class GameBootstrap : Node
MultiplayerController.PeerLeft += id => _logger.Info("Multiplayer", $"Peer {id} left."); MultiplayerController.PeerLeft += id => _logger.Info("Multiplayer", $"Peer {id} left.");
} }
private void InitializeItems()
{
ItemWorld.RegisterSceneItems();
ItemSpawner.Initialize();
InteractionWorld.RegisterSceneTargets();
PlayerHeldItemPresenter presenter = new(
ItemWorld,
PlayerInteraction.LeftHandAnchor,
PlayerInteraction.RightHandAnchor
);
ItemInteractionService itemInteractions = new(new HandsInventory(), ItemWorld, presenter);
InteractionService interactions = new(InteractionWorld);
PlayerInteraction.Initialize(new PlayerId(Guid.NewGuid()), itemInteractions, interactions);
}
public override void _Ready() public override void _Ready()
{ {
this.AssertRequiredExports(); this.AssertRequiredExports();
@@ -60,6 +87,7 @@ public partial class GameBootstrap : Node
MouseCapture.Capture(); MouseCapture.Capture();
InitializeLogging(); InitializeLogging();
InitializeItems();
InitializeMultiplayer(); InitializeMultiplayer();
RegisterConsoleCommands(); RegisterConsoleCommands();
} }
+8
View File
@@ -10,6 +10,10 @@ public enum InputAction
MoveBack, MoveBack,
MoveDown, MoveDown,
Jump, Jump,
Interact,
UseLeftHand,
UseRightHand,
DropModifier,
Cancel, Cancel,
ToggleConsole ToggleConsole
} }
@@ -27,6 +31,10 @@ public static class InputActionExtensions
InputAction.MoveBack => "move_back", InputAction.MoveBack => "move_back",
InputAction.MoveDown => "move_down", InputAction.MoveDown => "move_down",
InputAction.Jump => "jump", InputAction.Jump => "jump",
InputAction.Interact => "interact",
InputAction.UseLeftHand => "use_left_hand",
InputAction.UseRightHand => "use_right_hand",
InputAction.DropModifier => "drop_modifier",
InputAction.Cancel => "ui_cancel", InputAction.Cancel => "ui_cancel",
InputAction.ToggleConsole => "toggle_console", InputAction.ToggleConsole => "toggle_console",
_ => throw new ArgumentOutOfRangeException(nameof(action), action, null) _ => throw new ArgumentOutOfRangeException(nameof(action), action, null)
+29 -1
View File
@@ -6,6 +6,10 @@
[ext_resource type="Script" uid="uid://drctu5y21ey2y" path="res://src/Godot/GameBootstrap.cs" id="3_bootstrap"] [ext_resource type="Script" uid="uid://drctu5y21ey2y" path="res://src/Godot/GameBootstrap.cs" id="3_bootstrap"]
[ext_resource type="PackedScene" uid="uid://bk0771dvonxh8" path="res://src/Features/Console/Godot/ConsoleController.tscn" id="4_console"] [ext_resource type="PackedScene" uid="uid://bk0771dvonxh8" path="res://src/Features/Console/Godot/ConsoleController.tscn" id="4_console"]
[ext_resource type="Script" uid="uid://drqx0wiw0sbj1" path="res://src/Features/Multiplayer/Godot/MultiplayerController.cs" id="5_multiplayer"] [ext_resource type="Script" uid="uid://drqx0wiw0sbj1" path="res://src/Features/Multiplayer/Godot/MultiplayerController.cs" id="5_multiplayer"]
[ext_resource type="Script" uid="uid://f8n3b6w1k5r9m" path="res://src/Features/Items/Godot/ItemWorldController.cs" id="6_items"]
[ext_resource type="PackedScene" uid="uid://cv8m3q1y6r4nf" path="res://src/Features/Items/Godot/Flashlight/FlashlightItem.tscn" id="7_flashlight"]
[ext_resource type="Script" uid="uid://c3x9m6w2q8r1b" path="res://src/Features/Items/Godot/ItemSpawnerController.cs" id="8_spawner"]
[ext_resource type="Script" uid="uid://f6q1c9m4w7v2n" path="res://src/Features/Interactions/Godot/InteractionWorldController.cs" id="9_interactions"]
[sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_epykj"] [sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_epykj"]
panorama = ExtResource("1_g4n7o") panorama = ExtResource("1_g4n7o")
@@ -18,10 +22,14 @@ background_mode = 2
sky = SubResource("Sky_1kpcd") sky = SubResource("Sky_1kpcd")
glow_enabled = true glow_enabled = true
[node name="GameWorld" type="Node" unique_id=222644234 node_paths=PackedStringArray("Console", "Player", "MultiplayerController")] [node name="GameWorld" type="Node" unique_id=222644234 node_paths=PackedStringArray("Console", "Player", "PlayerInteraction", "ItemWorld", "ItemSpawner", "InteractionWorld", "MultiplayerController")]
script = ExtResource("3_bootstrap") script = ExtResource("3_bootstrap")
Console = NodePath("Console") Console = NodePath("Console")
Player = NodePath("Player") Player = NodePath("Player")
PlayerInteraction = NodePath("Player/PlayerInteraction")
ItemWorld = NodePath("ItemWorld")
ItemSpawner = NodePath("ItemSpawner")
InteractionWorld = NodePath("InteractionWorld")
MultiplayerController = NodePath("Multiplayer") MultiplayerController = NodePath("Multiplayer")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1669211403] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1669211403]
@@ -39,6 +47,18 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
[node name="Multiplayer" type="Node" parent="." unique_id=1209131013] [node name="Multiplayer" type="Node" parent="." unique_id=1209131013]
script = ExtResource("5_multiplayer") script = ExtResource("5_multiplayer")
[node name="ItemWorld" type="Node" parent="."]
script = ExtResource("6_items")
[node name="ItemSpawner" type="Node" parent="." node_paths=PackedStringArray("ItemsRoot", "ItemWorld")]
script = ExtResource("8_spawner")
ItemsRoot = NodePath("../Entities")
ItemWorld = NodePath("../ItemWorld")
ItemScenes = Array[PackedScene]([ExtResource("7_flashlight")])
[node name="InteractionWorld" type="Node" parent="."]
script = ExtResource("9_interactions")
[node name="Entities" type="Node3D" parent="." unique_id=851492709] [node name="Entities" type="Node3D" parent="." unique_id=851492709]
[node name="floor_ceiling_hr_46" parent="Entities" unique_id=33949496 instance=ExtResource("2_1kpcd")] [node name="floor_ceiling_hr_46" parent="Entities" unique_id=33949496 instance=ExtResource("2_1kpcd")]
@@ -66,3 +86,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0, -4)
[node name="floor_ceiling_hr_50" parent="Entities" unique_id=1804933431 instance=ExtResource("2_1kpcd")] [node name="floor_ceiling_hr_50" parent="Entities" unique_id=1804933431 instance=ExtResource("2_1kpcd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0, 0)
[node name="FlashlightLeft" parent="Entities" instance=ExtResource("7_flashlight")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.65, -0.7)
InstanceId = "c08790de-b2de-44e6-a73c-a7502ca27e34"
[node name="FlashlightRight" parent="Entities" instance=ExtResource("7_flashlight")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.65, -0.7)
InstanceId = "f71e67cb-786b-49eb-bd56-cb42ad19a754"