From 24a781f36a9aa6673bdb8eb65df79f43cb3c9843 Mon Sep 17 00:00:00 2001 From: minimata Date: Thu, 15 Jan 2026 10:31:13 +0100 Subject: [PATCH] base level for enemies testing --- addons/sk_fly_camera/LICENSE | 21 ++ addons/sk_fly_camera/README.md | 11 + addons/sk_fly_camera/icons/fly_camera.png | Bin 0 -> 3661 bytes .../sk_fly_camera/icons/fly_camera.png.import | 40 +++ addons/sk_fly_camera/icons/fly_camera.svg | 64 ++++ .../sk_fly_camera/icons/fly_camera.svg.import | 43 +++ addons/sk_fly_camera/plugin.cfg | 7 + addons/sk_fly_camera/plugin.gd | 5 + addons/sk_fly_camera/plugin.gd.uid | 1 + addons/sk_fly_camera/src/fly_camera.gd | 314 ++++++++++++++++++ addons/sk_fly_camera/src/fly_camera.gd.uid | 1 + maps/camera.gd | 28 ++ maps/camera.gd.uid | 1 + maps/enemies.tscn | 95 ++++++ 14 files changed, 631 insertions(+) create mode 100644 addons/sk_fly_camera/LICENSE create mode 100644 addons/sk_fly_camera/README.md create mode 100644 addons/sk_fly_camera/icons/fly_camera.png create mode 100644 addons/sk_fly_camera/icons/fly_camera.png.import create mode 100644 addons/sk_fly_camera/icons/fly_camera.svg create mode 100644 addons/sk_fly_camera/icons/fly_camera.svg.import create mode 100644 addons/sk_fly_camera/plugin.cfg create mode 100644 addons/sk_fly_camera/plugin.gd create mode 100644 addons/sk_fly_camera/plugin.gd.uid create mode 100644 addons/sk_fly_camera/src/fly_camera.gd create mode 100644 addons/sk_fly_camera/src/fly_camera.gd.uid create mode 100644 maps/camera.gd create mode 100644 maps/camera.gd.uid create mode 100644 maps/enemies.tscn diff --git a/addons/sk_fly_camera/LICENSE b/addons/sk_fly_camera/LICENSE new file mode 100644 index 0000000..f626ecf --- /dev/null +++ b/addons/sk_fly_camera/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Skaruts + +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. diff --git a/addons/sk_fly_camera/README.md b/addons/sk_fly_camera/README.md new file mode 100644 index 0000000..363c1de --- /dev/null +++ b/addons/sk_fly_camera/README.md @@ -0,0 +1,11 @@ +# Fly Camera Addon for Godot 4 + +A camera addon for flying around scenes at runtime, which can be handy during the prototyping phase of a project, for example. + +The camera is easy to use. You can just drop it in a scene, and run the game. +Optionally you can also tweek the camera node settings in the inspector (speed, mouse sensitivity, etc). + +By default the camera uses `WASD` keys for movement, `Shift` to move faster, `Ctrl` to move slower, +and `Right Mouse Button` to activate/deactivate the camera's mouse controls. + +Please refer to the documentation for more information. diff --git a/addons/sk_fly_camera/icons/fly_camera.png b/addons/sk_fly_camera/icons/fly_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..bcc6ab8cb6ce51e0f763221b75ea9078023b2a31 GIT binary patch literal 3661 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 literal 0 HcmV?d00001 diff --git a/addons/sk_fly_camera/icons/fly_camera.png.import b/addons/sk_fly_camera/icons/fly_camera.png.import new file mode 100644 index 0000000..713935a --- /dev/null +++ b/addons/sk_fly_camera/icons/fly_camera.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b42t3486jwfud" +path="res://.godot/imported/fly_camera.png-f981b86d63a5d3aa84ae2448e297f41a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sk_fly_camera/icons/fly_camera.png" +dest_files=["res://.godot/imported/fly_camera.png-f981b86d63a5d3aa84ae2448e297f41a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 diff --git a/addons/sk_fly_camera/icons/fly_camera.svg b/addons/sk_fly_camera/icons/fly_camera.svg new file mode 100644 index 0000000..3eb4a44 --- /dev/null +++ b/addons/sk_fly_camera/icons/fly_camera.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + diff --git a/addons/sk_fly_camera/icons/fly_camera.svg.import b/addons/sk_fly_camera/icons/fly_camera.svg.import new file mode 100644 index 0000000..ef227e0 --- /dev/null +++ b/addons/sk_fly_camera/icons/fly_camera.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dma1meqanq6lr" +path="res://.godot/imported/fly_camera.svg-197f6cff73611fb9b2753ae8bc3c4adb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sk_fly_camera/icons/fly_camera.svg" +dest_files=["res://.godot/imported/fly_camera.svg-197f6cff73611fb9b2753ae8bc3c4adb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 diff --git a/addons/sk_fly_camera/plugin.cfg b/addons/sk_fly_camera/plugin.cfg new file mode 100644 index 0000000..4c9ba04 --- /dev/null +++ b/addons/sk_fly_camera/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Fly Camera" +description="A camera for when you need to quickly fly around while prototyping games." +author="Skaruts" +version="0.1" +script="plugin.gd" diff --git a/addons/sk_fly_camera/plugin.gd b/addons/sk_fly_camera/plugin.gd new file mode 100644 index 0000000..81b6b1d --- /dev/null +++ b/addons/sk_fly_camera/plugin.gd @@ -0,0 +1,5 @@ +@tool +extends EditorPlugin + + +# nothing to see here diff --git a/addons/sk_fly_camera/plugin.gd.uid b/addons/sk_fly_camera/plugin.gd.uid new file mode 100644 index 0000000..8a2265c --- /dev/null +++ b/addons/sk_fly_camera/plugin.gd.uid @@ -0,0 +1 @@ +uid://ctjbk1djxsko6 diff --git a/addons/sk_fly_camera/src/fly_camera.gd b/addons/sk_fly_camera/src/fly_camera.gd new file mode 100644 index 0000000..6bf122b --- /dev/null +++ b/addons/sk_fly_camera/src/fly_camera.gd @@ -0,0 +1,314 @@ +@icon("../icons/fly_camera.svg") +class_name FlyCamera +extends CharacterBody3D + +## +## A free flying camera, handy for prototyping. +## [br][br] +## +## +## This camera allows to quickly be able to fly around at runtime. +## Just put it in a scene and it should be good to go. You can optionally +## tweak its settings in the inspector. +## [br][br] +## +## The camera node itself is not an actual camera, but a [CharacterBody3D], so +## it has no visual preview in the inspector. You can still align it to the +## camera in the 3D View, by clicking [param Perspective > Align Transform With View]. +## [br][br] +## +## You will also see a warning in the [param Scene] tree about the [CharacterBody3D] +## not having a shape. Normally a flying camera doesn't need any collisions, +## and you can ignore the warning. The camera still supports collisions, though, +## either by turning on [param Use Collisions] in the inspector, or by +## manually adding a [CollisionShape3D] node with a shape of your choice. +## [br][br] +##[color=white][b]Note:[/b][/color] the collisions are added at runtime, so +## turning on [param Use Collisions] will not suppress the warning. +## [br][br] +## +## The camera controls can be changed. By default it uses the [param WASD] +## keys for movement, [param Shift] to move faster, [param Ctrl] to move slower, and +## the [param Right Mouse Button] to activate/deactivate the mouse controls +## (capturing/uncapturing the mouse pointer). +## [br][br] +## +## This camera was intended for quick use, so the default controls are easy to +## change in the camera script by hand (in the [param _actions_to_key] dictionary). +## However, if you prefer, you can also set the following input actions in +## your project settings, and the camera will automatically use them instead: +## [codeblock] +##cam_forward +##cam_backward +##cam_left +##cam_right +##cam_faster +##cam_slower +##cam_activate +## [/codeblock] +## [color=white][b]Note:[/b][/color] the mouse button used to activate the +## camera can easily be changed in the inspector, so for that end you don't +## need to use [param cam_activate] input action. +## This action is provided in case you'd like to use a keyboard key instead. +## +## + + +## How to activate mouse controls. +enum ActivationMode { + ON_CLICK, ## Click to activate, click again to deactivate. + ON_HOLD, ## Hold mouse button to activate, release to deactivate. +} + +## Where to revert the mouse pointer when releasing mouse controls. +enum RevertMouseOption { + CLICK_POSITION, ## The position where the mouse was initially clicked. + VIEWPORT_CENTER, ## The center of the viewport. +} + +enum MouseButton { + LEFT = 1, + RIGHT, + MIDDLE, +} + + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= + +# User Properties / Settings + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= +#region user_settings +@export_group("Mouse Settings") + +## How to activate the mouse controls. +@export var activation_mode := ActivationMode.ON_CLICK + +## Where the mouse pointer should be at when releasing mouse controls. +@export var revert_mouse_to := RevertMouseOption.CLICK_POSITION + +## Which mouse button activates mouse control. +@export var mouse_button := MouseButton.RIGHT + + +## The mouse sensitivity in each axis. +@export var mouse_sensitivity := Vector2(2.2, 2.2) + +## If true the mouse's vertical axis will be inverted. +@export var invert_y := false + +## If true, the key controls will still work when the mouse controls +## are inactive. +@export var keep_key_controls := true + + +@export_group("Camera Settings") +## The camera's movement speed. +@export var fly_speed := 20.0 + +## The camera's acceleration. +## [br][br] +## For simplicity, this also doubles as friction. +@export var acceleration : int = 10 + +## The factor by which to multiply or divide the camera speed in order to +## move faster or slower. +@export var speed_factor : int = 3 + +## Adds a sphere collision shape to the camera. You can setup +## the collision layers as you please. +@export var use_collision := false: + set(enable): + use_collision = enable + _set_collisions(enable) + +## If true, the camera will use the default controls and ignore any +## input actions defined in the project settings. +@export var use_default_controls := false + + +#endregion + + + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= + +# Internals + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= +#region internal_Stuff +const _ACTION_FORWARD := "cam_forward" +const _ACTION_BACKWARD := "cam_backward" +const _ACTION_LEFT := "cam_left" +const _ACTION_RIGHT := "cam_right" +const _ACTION_FASTER := "cam_faster" +const _ACTION_SLOWER := "cam_slower" +const _ACTION_ACTIVATE := "cam_activate" + +var _actions_to_key := { + _ACTION_FORWARD : KEY_W, + _ACTION_BACKWARD : KEY_S, + _ACTION_LEFT : KEY_A, + _ACTION_RIGHT : KEY_D, + _ACTION_FASTER : KEY_SHIFT, + _ACTION_SLOWER : KEY_CTRL, + _ACTION_ACTIVATE : mouse_button, +} + +const _PITCH_LIMIT : int = 90 + + +var _mouse_click_pos : Vector2 +var _mouse_hidden : bool + +var _coll : CollisionShape3D +var _camera : Camera3D # The actual, internal camera node. +var _cam_pivot: Node3D # The Y rotation pivot node + +var _yaw : float = 0 +var _pitch : float = 0 + + + +func _ready() -> void: + _cam_pivot = Node3D.new() + add_child(_cam_pivot) + + _camera = Camera3D.new() + _cam_pivot.add_child(_camera) + _camera.current = true + + # if this node was rotated in the editor, use that as default rotation + var rot := rotation_degrees + rotation = Vector3.ZERO + set_rot(rot) + + +func _unhandled_input(event: InputEvent) -> void: + _check_mouse_capture(event) + + if not _mouse_hidden: + return + + ## Camera motion + if event is InputEventMouseMotion: + _yaw = fmod(_yaw - event.relative.x * mouse_sensitivity.x/10, 360) + + if not invert_y: _pitch = max(min(_pitch - event.relative.y * mouse_sensitivity.y/10.0, _PITCH_LIMIT), -_PITCH_LIMIT) + else: _pitch = max(min(_pitch + event.relative.y * mouse_sensitivity.y/10.0, _PITCH_LIMIT), -_PITCH_LIMIT) + + _cam_pivot.rotation.y = deg_to_rad(_yaw) + _camera.rotation.x = deg_to_rad(_pitch) + + +func _physics_process(delta: float) -> void: + var aim : Basis = _camera.get_camera_transform().basis + + var dir := Vector3() + var spd := fly_speed + + if _mouse_hidden or keep_key_controls: + if _is_cam_action_pressed(_ACTION_FORWARD): dir -= aim[2] + if _is_cam_action_pressed(_ACTION_BACKWARD): dir += aim[2] + if _is_cam_action_pressed(_ACTION_LEFT): dir -= aim[0] + if _is_cam_action_pressed(_ACTION_RIGHT): dir += aim[0] + if _is_cam_action_pressed(_ACTION_FASTER): spd *= speed_factor + if _is_cam_action_pressed(_ACTION_SLOWER): spd /= speed_factor + + dir = dir.normalized() + + var target := dir * spd + velocity = velocity.lerp( target, acceleration*delta ) + move_and_slide() + + if is_zero_approx(velocity.length()): + velocity = Vector3.ZERO + + +func _is_cam_action_pressed(action:String) -> bool: + if not use_default_controls and InputMap.has_action(action): + return Input.is_action_pressed(action) + return Input.is_key_pressed(_actions_to_key[action]) + + +func _set_collisions(enable:bool) -> void: + if enable: + _coll = CollisionShape3D.new() + _coll.shape = SphereShape3D.new() + add_child(_coll) + else: + _coll.queue_free() + _coll = null + + +func _check_mouse_capture(event:InputEvent) -> void: + var button_state := 0 # 0- unchaged, 1- pressed, 2- released + + if not use_default_controls and InputMap.has_action(_ACTION_ACTIVATE): + if event.is_action_pressed(_ACTION_ACTIVATE): button_state = 1 + elif event.is_action_released(_ACTION_ACTIVATE): button_state = 2 + elif event is InputEventMouseButton and event.button_index == mouse_button: + button_state = 1 if event.pressed else 2 + + if button_state == 0: return + + match activation_mode: + ActivationMode.ON_HOLD: + set_active(button_state == 1) + ActivationMode.ON_CLICK: + if button_state == 1: + set_active(not _mouse_hidden) + + +func _revert_mouse_pos() -> void: + var vp := get_viewport() + match revert_mouse_to: + RevertMouseOption.CLICK_POSITION: + vp.warp_mouse( _mouse_click_pos ) + RevertMouseOption.VIEWPORT_CENTER: + vp.warp_mouse(vp.get_visible_rect().size/2) + + +#endregion + + + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= + +# Public API + +#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#= +## Returns the actual camera that is used internally. +func get_camera() -> Camera3D: + return _camera + + +## Sets the FlyCamera's rotation to [param rot]. +## [br][br] +## [color=white][b]Note:[/b][/color] don't set the rotation directly, as the +## rotation of the root node doesn't represent the rotation of the actual camera. +func set_rot(rot:Vector3) -> void: + _yaw = rot.y + _pitch = rot.x + _cam_pivot.rotation_degrees.y = _yaw + _camera.rotation_degrees.x = _pitch + + +## Returns the rotation of the camera. +## [br][br] +## [color=white][b]Note:[/b][/color] don't get the rotation directly, as the +## rotation of the root node doesn't represent the rotation of the actual camera. +func get_rot() -> Vector3: + return Vector3(_camera.rotation.x, _cam_pivot.rotation.y, 0) + + +## Activate or deactivate the mouse controls +func set_active(enable:bool) -> void: + if enable: + _mouse_click_pos = get_viewport().get_mouse_position() + _mouse_hidden = true + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + else: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + _mouse_hidden = false + _revert_mouse_pos() diff --git a/addons/sk_fly_camera/src/fly_camera.gd.uid b/addons/sk_fly_camera/src/fly_camera.gd.uid new file mode 100644 index 0000000..695dd32 --- /dev/null +++ b/addons/sk_fly_camera/src/fly_camera.gd.uid @@ -0,0 +1 @@ +uid://cte4jalives85 diff --git a/maps/camera.gd b/maps/camera.gd new file mode 100644 index 0000000..645f4f2 --- /dev/null +++ b/maps/camera.gd @@ -0,0 +1,28 @@ +extends "res://addons/Free fly camera/Src/free_fly_startup.gd" + + +const SPEED = 5.0 +const JUMP_VELOCITY = 4.5 + + +func _physics_process(delta: float) -> void: + # Add the gravity. + if not is_on_floor(): + velocity += get_gravity() * delta + + # Handle jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + velocity.x = direction.x * SPEED + velocity.z = direction.z * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.z = move_toward(velocity.z, 0, SPEED) + + move_and_slide() diff --git a/maps/camera.gd.uid b/maps/camera.gd.uid new file mode 100644 index 0000000..49097d8 --- /dev/null +++ b/maps/camera.gd.uid @@ -0,0 +1 @@ +uid://e6ihddcgve8c diff --git a/maps/enemies.tscn b/maps/enemies.tscn new file mode 100644 index 0000000..fb73fbd --- /dev/null +++ b/maps/enemies.tscn @@ -0,0 +1,95 @@ +[gd_scene load_steps=5 format=3 uid="uid://cohmqsk3s70yp"] + +[ext_resource type="Script" uid="uid://cte4jalives85" path="res://addons/sk_fly_camera/src/fly_camera.gd" id="1_aj441"] + +[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_aj441"] + +[sub_resource type="Sky" id="Sky_o2inx"] +sky_material = SubResource("PhysicalSkyMaterial_aj441") + +[sub_resource type="Environment" id="Environment_i46j0"] +background_mode = 2 +sky = SubResource("Sky_o2inx") +ambient_light_source = 2 +ambient_light_color = Color(0.77807873, 0.8451813, 0.8615737, 1) +ambient_light_energy = 0.5 +ssao_enabled = true +ssao_radius = 2.0 +fog_light_color = Color(1, 1, 1, 1) + +[node name="Enemies" type="Node3D"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_i46j0") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.6725735, -0.5947325, 0.44038418, -0.74003035, -0.5405202, 0.40024132, 0, -0.5950894, -0.8036596, 0, 0, 0) + +[node name="DirectionalLight3D2" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.098757595, -0.94823945, -0.30180964, 0.25508866, -0.26903492, 0.92873573, -0.96186113, -0.16870806, 0.21531586, 0, 0, 0) +light_energy = 0.2 + +[node name="CharacterBody3D" type="CharacterBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.231003, 12.216311, 0) +script = ExtResource("1_aj441") + +[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] +size = Vector3(100, 1, 100) + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.389802, -9.536743e-07, -17.424805) +size = Vector3(2, 10, 2) + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.554723, 0, -14.582476) +size = Vector3(2, 10, 2) + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.554723, 0, 8.672777) +size = Vector3(2, 10, 2) + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.4320955, 0, 8.672777) +size = Vector3(2, 10, 2) + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.400285, 0, -3.0115404) +size = Vector3(2, 10, 2) + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.3954687, -9.536743e-07, -8.965862) +size = Vector3(10, 2, 10) + +[node name="CSGBox3D8" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.063101, -9.536743e-07, -6.855488) +size = Vector3(10, 3, 10) + +[node name="CSGBox3D9" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.932084, 0, -3.5338726) +size = Vector3(10, 4, 10) + +[node name="CSGBox3D10" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.932084, 0, 1.561698) +size = Vector3(10, 5, 10) + +[node name="CSGBox3D11" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.3916206, -1.9073486e-06, 9.662505) +size = Vector3(10, 6, 10) + +[node name="CSGBox3D12" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.696065, -9.536743e-07, 12.753594) +size = Vector3(10, 7, 10) + +[node name="CSGBox3D13" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.025868, -9.536743e-07, 8.954356) +size = Vector3(10, 8, 10) + +[node name="CSGBox3D14" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.727036, -9.536743e-07, 0.6610918) +size = Vector3(10, 9, 10) + +[node name="CSGBox3D15" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.384857, -9.536743e-07, -3.8720686) +size = Vector3(10, 10, 10)