created fog of war
This commit is contained in:
1
addons/anthonyec.camera_preview/GuiResizerTopLeft.svg
Normal file
1
addons/anthonyec.camera_preview/GuiResizerTopLeft.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 11V4h7" fill="none" stroke="#fff" stroke-width="2" stroke-linejoin="round" stroke-linecap="round" stroke-opacity=".6"/></svg>
|
||||||
|
After Width: | Height: | Size: 221 B |
37
addons/anthonyec.camera_preview/GuiResizerTopLeft.svg.import
Normal file
37
addons/anthonyec.camera_preview/GuiResizerTopLeft.svg.import
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://btc01wc11tiid"
|
||||||
|
path="res://.godot/imported/GuiResizerTopLeft.svg-eb563f557424c74239e878a1213a5bf4.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/anthonyec.camera_preview/GuiResizerTopLeft.svg"
|
||||||
|
dest_files=["res://.godot/imported/GuiResizerTopLeft.svg-eb563f557424c74239e878a1213a5bf4.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=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
1
addons/anthonyec.camera_preview/GuiResizerTopRight.svg
Normal file
1
addons/anthonyec.camera_preview/GuiResizerTopRight.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M12 11V4h-7" fill="none" stroke="#fff" stroke-opacity=".6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||||
|
After Width: | Height: | Size: 223 B |
@@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://04l05jxuyt7k"
|
||||||
|
path="res://.godot/imported/GuiResizerTopRight.svg-cc1dc8556d51357c5eb0b01d09d8f049.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/anthonyec.camera_preview/GuiResizerTopRight.svg"
|
||||||
|
dest_files=["res://.godot/imported/GuiResizerTopRight.svg-cc1dc8556d51357c5eb0b01d09d8f049.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=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
1
addons/anthonyec.camera_preview/Pin.svg
Normal file
1
addons/anthonyec.camera_preview/Pin.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1v1l1 1v3h6v-3l1-1v-1zm1 6-2 3h10l-2-3zm2 4v2l1 2 1-2v-2z" fill="#e0e0e0"/></svg>
|
||||||
|
After Width: | Height: | Size: 177 B |
37
addons/anthonyec.camera_preview/Pin.svg.import
Normal file
37
addons/anthonyec.camera_preview/Pin.svg.import
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://do6d60od41vmg"
|
||||||
|
path="res://.godot/imported/Pin.svg-83b09f5c00a829c5d8b136bf5bae65bc.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/anthonyec.camera_preview/Pin.svg"
|
||||||
|
dest_files=["res://.godot/imported/Pin.svg-83b09f5c00a829c5d8b136bf5bae65bc.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=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
7
addons/anthonyec.camera_preview/plugin.cfg
Normal file
7
addons/anthonyec.camera_preview/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Little Camera Preview"
|
||||||
|
description="Shows a picture-in-picture preview of the selected 2D or 3D camera"
|
||||||
|
author="Anthony Cossins"
|
||||||
|
version="1.3"
|
||||||
|
script="plugin.gd"
|
||||||
87
addons/anthonyec.camera_preview/plugin.gd
Normal file
87
addons/anthonyec.camera_preview/plugin.gd
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
const preview_scene = preload("res://addons/anthonyec.camera_preview/preview.tscn")
|
||||||
|
|
||||||
|
var preview: CameraPreview
|
||||||
|
var current_main_screen_name: String
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
main_screen_changed.connect(_on_main_screen_changed)
|
||||||
|
EditorInterface.get_selection().selection_changed.connect(_on_editor_selection_changed)
|
||||||
|
|
||||||
|
# Initialise preview panel and add to main screen.
|
||||||
|
preview = preview_scene.instantiate() as CameraPreview
|
||||||
|
preview.request_hide()
|
||||||
|
|
||||||
|
var main_screen = EditorInterface.get_editor_main_screen()
|
||||||
|
main_screen.add_child(preview)
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
if preview:
|
||||||
|
preview.queue_free()
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# TODO: Currently there is no API to get the main screen name without
|
||||||
|
# listening to the `EditorPlugin.main_screen_changed` signal:
|
||||||
|
# https://github.com/godotengine/godot-proposals/issues/2081
|
||||||
|
EditorInterface.set_main_screen_editor("Script")
|
||||||
|
EditorInterface.set_main_screen_editor("3D")
|
||||||
|
|
||||||
|
func _on_main_screen_changed(screen_name: String) -> void:
|
||||||
|
current_main_screen_name = screen_name
|
||||||
|
|
||||||
|
# TODO: Bit of a hack to prevent pinned staying between view changes on the same scene.
|
||||||
|
preview.unlink_camera()
|
||||||
|
_on_editor_selection_changed()
|
||||||
|
|
||||||
|
func _on_editor_selection_changed() -> void:
|
||||||
|
if not is_main_screen_viewport():
|
||||||
|
# This hides the preview "container" and not the preview itself, allowing
|
||||||
|
# any locked previews to remain visible once switching back to 3D tab.
|
||||||
|
preview.visible = false
|
||||||
|
return
|
||||||
|
|
||||||
|
preview.visible = true
|
||||||
|
|
||||||
|
var selected_nodes = EditorInterface.get_selection().get_selected_nodes()
|
||||||
|
|
||||||
|
var selected_camera_3d: Camera3D = find_camera_3d_or_null(selected_nodes)
|
||||||
|
var selected_camera_2d: Camera2D = find_camera_2d_or_null(selected_nodes)
|
||||||
|
|
||||||
|
if selected_camera_3d and current_main_screen_name == "3D":
|
||||||
|
preview.link_with_camera_3d(selected_camera_3d)
|
||||||
|
preview.request_show()
|
||||||
|
|
||||||
|
elif selected_camera_2d and current_main_screen_name == "2D":
|
||||||
|
preview.link_with_camera_2d(selected_camera_2d)
|
||||||
|
preview.request_show()
|
||||||
|
|
||||||
|
else:
|
||||||
|
preview.request_hide()
|
||||||
|
|
||||||
|
func is_main_screen_viewport() -> bool:
|
||||||
|
return current_main_screen_name == "3D" or current_main_screen_name == "2D"
|
||||||
|
|
||||||
|
func find_camera_3d_or_null(nodes: Array[Node]) -> Camera3D:
|
||||||
|
var camera: Camera3D
|
||||||
|
|
||||||
|
for node in nodes:
|
||||||
|
if node is Camera3D:
|
||||||
|
camera = node as Camera3D
|
||||||
|
break
|
||||||
|
|
||||||
|
return camera
|
||||||
|
|
||||||
|
func find_camera_2d_or_null(nodes: Array[Node]) -> Camera2D:
|
||||||
|
var camera: Camera2D
|
||||||
|
|
||||||
|
for node in nodes:
|
||||||
|
if node is Camera2D:
|
||||||
|
camera = node as Camera2D
|
||||||
|
break
|
||||||
|
|
||||||
|
return camera
|
||||||
|
|
||||||
|
func _on_selected_camera_3d_tree_exiting() -> void:
|
||||||
|
preview.unlink_camera()
|
||||||
404
addons/anthonyec.camera_preview/preview.gd
Normal file
404
addons/anthonyec.camera_preview/preview.gd
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
@tool
|
||||||
|
|
||||||
|
class_name CameraPreview
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
enum CameraType {
|
||||||
|
CAMERA_2D,
|
||||||
|
CAMERA_3D
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PinnedPosition {
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum InteractionState {
|
||||||
|
NONE,
|
||||||
|
RESIZE,
|
||||||
|
DRAG,
|
||||||
|
|
||||||
|
# Animation is split into 2 seperate states so that the tween is only
|
||||||
|
# invoked once in the "start" state.
|
||||||
|
START_ANIMATE_INTO_PLACE,
|
||||||
|
ANIMATE_INTO_PLACE,
|
||||||
|
}
|
||||||
|
|
||||||
|
const margin_3d: Vector2 = Vector2(10, 10)
|
||||||
|
const margin_2d: Vector2 = Vector2(20, 15)
|
||||||
|
const panel_margin: float = 2
|
||||||
|
const min_panel_size: float = 250
|
||||||
|
|
||||||
|
@onready var panel: Panel = %Panel
|
||||||
|
@onready var placeholder: Panel = %Placeholder
|
||||||
|
@onready var preview_camera_3d: Camera3D = %Camera3D
|
||||||
|
@onready var preview_camera_2d: Camera2D = %Camera2D
|
||||||
|
@onready var sub_viewport: SubViewport = %SubViewport
|
||||||
|
@onready var sub_viewport_text_rect: TextureRect = %TextureRect
|
||||||
|
@onready var resize_left_handle: Button = %ResizeLeftHandle
|
||||||
|
@onready var resize_right_handle: Button = %ResizeRightHandle
|
||||||
|
@onready var lock_button: Button = %LockButton
|
||||||
|
@onready var gradient: TextureRect = %Gradient
|
||||||
|
@onready var viewport_margin_container: MarginContainer = %ViewportMarginContainer
|
||||||
|
@onready var overlay_margin_container: MarginContainer = %OverlayMarginContainer
|
||||||
|
@onready var overlay_container: Control = %OverlayContainer
|
||||||
|
|
||||||
|
var camera_type: CameraType = CameraType.CAMERA_3D
|
||||||
|
var pinned_position: PinnedPosition = PinnedPosition.RIGHT
|
||||||
|
var viewport_ratio: float = 1
|
||||||
|
var editor_scale: float = EditorInterface.get_editor_scale()
|
||||||
|
var is_locked: bool
|
||||||
|
var show_controls: bool
|
||||||
|
var selected_camera_3d: Camera3D
|
||||||
|
var selected_camera_2d: Camera2D
|
||||||
|
|
||||||
|
var state: InteractionState = InteractionState.NONE
|
||||||
|
var initial_mouse_position: Vector2
|
||||||
|
var initial_panel_size: Vector2
|
||||||
|
var initial_panel_position: Vector2
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# Set initial width.
|
||||||
|
panel.size.x = min_panel_size * editor_scale
|
||||||
|
|
||||||
|
# Setting texture to viewport in code instead of directly in the editor
|
||||||
|
# because otherwise an error "Path to node is invalid: Panel/SubViewport"
|
||||||
|
# on first load. This is harmless but doesn't look great.
|
||||||
|
#
|
||||||
|
# This is a known issue:
|
||||||
|
# https://github.com/godotengine/godot/issues/27790#issuecomment-499740220
|
||||||
|
sub_viewport_text_rect.texture = sub_viewport.get_texture()
|
||||||
|
|
||||||
|
# From what I can tell there's something wrong with how an editor theme
|
||||||
|
# scales when used within a plugin. It seems to ignore the screen scale.
|
||||||
|
# For instance, a 30x30px button will appear tiny on a retina display.
|
||||||
|
#
|
||||||
|
# Someone else had the issue with no luck:
|
||||||
|
# https://forum.godotengine.org/t/how-to-scale-plugin-controls-to-look-the-same-in-4k-as-1080p/36151
|
||||||
|
#
|
||||||
|
# And seems Dialogic also scales buttons manually:
|
||||||
|
# https://github.com/dialogic-godot/dialogic/blob/master/addons/dialogic/Editor/Common/sidebar.gd#L25C6-L38
|
||||||
|
#
|
||||||
|
# Maybe I don't know the correct way to do it, so for now the workaround is
|
||||||
|
# to set the correct size in code using screen scale.
|
||||||
|
var button_size = Vector2(30, 30) * editor_scale
|
||||||
|
var margin_size: float = panel_margin * editor_scale
|
||||||
|
|
||||||
|
resize_left_handle.size = button_size
|
||||||
|
resize_left_handle.pivot_offset = Vector2(0, 0) * editor_scale
|
||||||
|
|
||||||
|
resize_right_handle.size = button_size
|
||||||
|
resize_right_handle.pivot_offset = Vector2(30, 30) * editor_scale
|
||||||
|
|
||||||
|
lock_button.size = button_size
|
||||||
|
lock_button.pivot_offset = Vector2(0, 30) * editor_scale
|
||||||
|
|
||||||
|
viewport_margin_container.add_theme_constant_override("margin_left", margin_size)
|
||||||
|
viewport_margin_container.add_theme_constant_override("margin_top", margin_size)
|
||||||
|
viewport_margin_container.add_theme_constant_override("margin_right", margin_size)
|
||||||
|
viewport_margin_container.add_theme_constant_override("margin_bottom", margin_size)
|
||||||
|
|
||||||
|
overlay_margin_container.add_theme_constant_override("margin_left", margin_size)
|
||||||
|
overlay_margin_container.add_theme_constant_override("margin_top", margin_size)
|
||||||
|
overlay_margin_container.add_theme_constant_override("margin_right", margin_size)
|
||||||
|
overlay_margin_container.add_theme_constant_override("margin_bottom", margin_size)
|
||||||
|
|
||||||
|
# Parent node overlay size is not available on first ready, need to wait a
|
||||||
|
# frame for it to be drawn.
|
||||||
|
await get_tree().process_frame
|
||||||
|
|
||||||
|
# Anchors are set in code because setting them in the editor UI doesn't take
|
||||||
|
# editor scale into account.
|
||||||
|
resize_left_handle.position = Vector2(0, 0)
|
||||||
|
resize_right_handle.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||||
|
|
||||||
|
resize_right_handle.position = Vector2(overlay_container.size.x - button_size.x, 0)
|
||||||
|
resize_right_handle.set_anchors_preset(Control.PRESET_TOP_RIGHT)
|
||||||
|
|
||||||
|
lock_button.position = Vector2(0, overlay_container.size.y - button_size.y)
|
||||||
|
lock_button.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if not visible: return
|
||||||
|
|
||||||
|
match state:
|
||||||
|
InteractionState.NONE:
|
||||||
|
panel.size = get_clamped_size(panel.size)
|
||||||
|
panel.position = get_pinned_position(pinned_position)
|
||||||
|
|
||||||
|
InteractionState.RESIZE:
|
||||||
|
var delta_mouse_position = initial_mouse_position - get_global_mouse_position()
|
||||||
|
var resized_size = panel.size
|
||||||
|
|
||||||
|
if pinned_position == PinnedPosition.LEFT:
|
||||||
|
resized_size = initial_panel_size - delta_mouse_position
|
||||||
|
|
||||||
|
if pinned_position == PinnedPosition.RIGHT:
|
||||||
|
resized_size = initial_panel_size + delta_mouse_position
|
||||||
|
|
||||||
|
panel.size = get_clamped_size(resized_size)
|
||||||
|
panel.position = get_pinned_position(pinned_position)
|
||||||
|
|
||||||
|
InteractionState.DRAG:
|
||||||
|
placeholder.size = panel.size
|
||||||
|
|
||||||
|
var global_mouse_position = get_global_mouse_position()
|
||||||
|
var offset = initial_mouse_position - initial_panel_position
|
||||||
|
|
||||||
|
panel.global_position = global_mouse_position - offset
|
||||||
|
|
||||||
|
if global_mouse_position.x < global_position.x + size.x / 2:
|
||||||
|
pinned_position = PinnedPosition.LEFT
|
||||||
|
else:
|
||||||
|
pinned_position = PinnedPosition.RIGHT
|
||||||
|
|
||||||
|
placeholder.position = get_pinned_position(pinned_position)
|
||||||
|
|
||||||
|
InteractionState.START_ANIMATE_INTO_PLACE:
|
||||||
|
var final_position: Vector2 = get_pinned_position(pinned_position)
|
||||||
|
var tween = get_tree().create_tween()
|
||||||
|
|
||||||
|
tween.set_ease(Tween.EASE_OUT)
|
||||||
|
tween.set_trans(Tween.TRANS_CUBIC)
|
||||||
|
tween.tween_property(panel, "position", final_position, 0.3)
|
||||||
|
|
||||||
|
tween.finished.connect(func():
|
||||||
|
panel.position = final_position
|
||||||
|
state = InteractionState.NONE
|
||||||
|
)
|
||||||
|
|
||||||
|
state = InteractionState.ANIMATE_INTO_PLACE
|
||||||
|
|
||||||
|
# I couldn't get `mouse_entered` and `mouse_exited` events to work
|
||||||
|
# nicely, so I use rect method instead. Plus using this method it's easy to
|
||||||
|
# grow the hit area size.
|
||||||
|
var panel_hover_rect = Rect2(panel.global_position, panel.size)
|
||||||
|
panel_hover_rect = panel_hover_rect.grow(40)
|
||||||
|
|
||||||
|
var mouse_position = get_global_mouse_position()
|
||||||
|
|
||||||
|
show_controls = state != InteractionState.NONE or panel_hover_rect.has_point(mouse_position)
|
||||||
|
|
||||||
|
# UI visibility.
|
||||||
|
resize_left_handle.visible = show_controls and pinned_position == PinnedPosition.RIGHT
|
||||||
|
resize_right_handle.visible = show_controls and pinned_position == PinnedPosition.LEFT
|
||||||
|
lock_button.visible = show_controls or is_locked
|
||||||
|
placeholder.visible = state == InteractionState.DRAG or state == InteractionState.ANIMATE_INTO_PLACE
|
||||||
|
gradient.visible = show_controls
|
||||||
|
|
||||||
|
# Sync camera settings.
|
||||||
|
if camera_type == CameraType.CAMERA_3D and selected_camera_3d:
|
||||||
|
sub_viewport.size = panel.size
|
||||||
|
|
||||||
|
# Sync position and rotation without using a `RemoteTransform` node
|
||||||
|
# because if you save a camera as a scene, the remote transform node will
|
||||||
|
# be stored within the scene. Also it's harder to keep the remote
|
||||||
|
# transform `remote_path` up-to-date with scene changes, which causes
|
||||||
|
# many errors.
|
||||||
|
preview_camera_3d.global_position = selected_camera_3d.global_position
|
||||||
|
preview_camera_3d.global_rotation = selected_camera_3d.global_rotation
|
||||||
|
|
||||||
|
preview_camera_3d.fov = selected_camera_3d.fov
|
||||||
|
preview_camera_3d.projection = selected_camera_3d.projection
|
||||||
|
preview_camera_3d.size = selected_camera_3d.size
|
||||||
|
preview_camera_3d.cull_mask = selected_camera_3d.cull_mask
|
||||||
|
preview_camera_3d.keep_aspect = selected_camera_3d.keep_aspect
|
||||||
|
preview_camera_3d.near = selected_camera_3d.near
|
||||||
|
preview_camera_3d.far = selected_camera_3d.far
|
||||||
|
preview_camera_3d.h_offset = selected_camera_3d.h_offset
|
||||||
|
preview_camera_3d.v_offset = selected_camera_3d.v_offset
|
||||||
|
preview_camera_3d.attributes = selected_camera_3d.attributes
|
||||||
|
preview_camera_3d.environment = selected_camera_3d.environment
|
||||||
|
|
||||||
|
if camera_type == CameraType.CAMERA_2D and selected_camera_2d:
|
||||||
|
var project_window_size = get_project_window_size()
|
||||||
|
var ratio = project_window_size.x / panel.size.x
|
||||||
|
|
||||||
|
# TODO: Is there a better way to fix this?
|
||||||
|
# The camera border is visible sometimes due to pixel rounding.
|
||||||
|
# Subtract 1px from right and bottom to hide this.
|
||||||
|
var hide_camera_border_fix = Vector2(1, 1)
|
||||||
|
|
||||||
|
sub_viewport.size = panel.size
|
||||||
|
sub_viewport.size_2d_override = (panel.size - hide_camera_border_fix) * ratio
|
||||||
|
sub_viewport.size_2d_override_stretch = true
|
||||||
|
|
||||||
|
preview_camera_2d.global_position = selected_camera_2d.global_position
|
||||||
|
preview_camera_2d.global_rotation = selected_camera_2d.global_rotation
|
||||||
|
|
||||||
|
preview_camera_2d.offset = selected_camera_2d.offset
|
||||||
|
preview_camera_2d.zoom = selected_camera_2d.zoom
|
||||||
|
preview_camera_2d.ignore_rotation = selected_camera_2d.ignore_rotation
|
||||||
|
preview_camera_2d.anchor_mode = selected_camera_2d.anchor_mode
|
||||||
|
preview_camera_2d.limit_left = selected_camera_2d.limit_left
|
||||||
|
preview_camera_2d.limit_right = selected_camera_2d.limit_right
|
||||||
|
preview_camera_2d.limit_top = selected_camera_2d.limit_top
|
||||||
|
preview_camera_2d.limit_bottom = selected_camera_2d.limit_bottom
|
||||||
|
|
||||||
|
func link_with_camera_3d(camera_3d: Camera3D) -> void:
|
||||||
|
# TODO: Camera may not be ready since this method is called in `_enter_tree`
|
||||||
|
# in the plugin because of a workaround for:
|
||||||
|
# https://github.com/godotengine/godot-proposals/issues/2081
|
||||||
|
if not preview_camera_3d:
|
||||||
|
return request_hide()
|
||||||
|
|
||||||
|
var is_different_camera = camera_3d != preview_camera_3d
|
||||||
|
|
||||||
|
# TODO: A bit messy.
|
||||||
|
if is_different_camera:
|
||||||
|
if preview_camera_3d.tree_exiting.is_connected(unlink_camera):
|
||||||
|
preview_camera_3d.tree_exiting.disconnect(unlink_camera)
|
||||||
|
|
||||||
|
if not camera_3d.tree_exiting.is_connected(unlink_camera):
|
||||||
|
camera_3d.tree_exiting.connect(unlink_camera)
|
||||||
|
|
||||||
|
sub_viewport.disable_3d = false
|
||||||
|
sub_viewport.world_3d = camera_3d.get_world_3d()
|
||||||
|
|
||||||
|
selected_camera_3d = camera_3d
|
||||||
|
camera_type = CameraType.CAMERA_3D
|
||||||
|
|
||||||
|
func link_with_camera_2d(camera_2d: Camera2D) -> void:
|
||||||
|
if not preview_camera_2d:
|
||||||
|
return request_hide()
|
||||||
|
|
||||||
|
var is_different_camera = camera_2d != preview_camera_2d
|
||||||
|
|
||||||
|
# TODO: A bit messy.
|
||||||
|
if is_different_camera:
|
||||||
|
if preview_camera_2d.tree_exiting.is_connected(unlink_camera):
|
||||||
|
preview_camera_2d.tree_exiting.disconnect(unlink_camera)
|
||||||
|
|
||||||
|
if not camera_2d.tree_exiting.is_connected(unlink_camera):
|
||||||
|
camera_2d.tree_exiting.connect(unlink_camera)
|
||||||
|
|
||||||
|
sub_viewport.disable_3d = true
|
||||||
|
sub_viewport.world_2d = camera_2d.get_world_2d()
|
||||||
|
|
||||||
|
selected_camera_2d = camera_2d
|
||||||
|
camera_type = CameraType.CAMERA_2D
|
||||||
|
|
||||||
|
func unlink_camera() -> void:
|
||||||
|
if selected_camera_3d:
|
||||||
|
selected_camera_3d = null
|
||||||
|
|
||||||
|
if selected_camera_2d:
|
||||||
|
selected_camera_2d = null
|
||||||
|
|
||||||
|
is_locked = false
|
||||||
|
lock_button.button_pressed = false
|
||||||
|
|
||||||
|
func request_hide() -> void:
|
||||||
|
if is_locked: return
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
func request_show() -> void:
|
||||||
|
visible = true
|
||||||
|
|
||||||
|
func get_pinned_position(pinned_position: PinnedPosition) -> Vector2:
|
||||||
|
var margin: Vector2 = margin_3d * editor_scale
|
||||||
|
|
||||||
|
if camera_type == CameraType.CAMERA_2D:
|
||||||
|
margin = margin_2d * editor_scale
|
||||||
|
|
||||||
|
match pinned_position:
|
||||||
|
PinnedPosition.LEFT:
|
||||||
|
return Vector2.ZERO - Vector2(0, panel.size.y) - Vector2(-margin.x, margin.y)
|
||||||
|
PinnedPosition.RIGHT:
|
||||||
|
return size - panel.size - margin
|
||||||
|
_:
|
||||||
|
assert(false, "Unknown pinned position %s" % str(pinned_position))
|
||||||
|
|
||||||
|
return Vector2.ZERO
|
||||||
|
|
||||||
|
func get_clamped_size(desired_size: Vector2) -> Vector2:
|
||||||
|
var viewport_ratio = get_project_window_ratio()
|
||||||
|
var editor_viewport_size = get_editor_viewport_size()
|
||||||
|
|
||||||
|
var max_bounds = Vector2(
|
||||||
|
editor_viewport_size.x * 0.6,
|
||||||
|
editor_viewport_size.y * 0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
var clamped_size = desired_size
|
||||||
|
|
||||||
|
# Apply aspect ratio.
|
||||||
|
clamped_size = Vector2(clamped_size.x, clamped_size.x * viewport_ratio)
|
||||||
|
|
||||||
|
# Clamp the max size while respecting the aspect ratio.
|
||||||
|
if clamped_size.y >= max_bounds.y:
|
||||||
|
clamped_size.x = max_bounds.y / viewport_ratio
|
||||||
|
clamped_size.y = max_bounds.y
|
||||||
|
|
||||||
|
if clamped_size.x >= max_bounds.x:
|
||||||
|
clamped_size.x = max_bounds.x
|
||||||
|
clamped_size.y = max_bounds.x * viewport_ratio
|
||||||
|
|
||||||
|
# Clamp the min size based on if it's portrait or landscape. Portrait min
|
||||||
|
# size should be based on it's height. Landscape min size is based on it's
|
||||||
|
# width instead. Applying min width to a portrait size would make it too big.
|
||||||
|
var is_portrait = viewport_ratio > 1
|
||||||
|
|
||||||
|
if is_portrait and clamped_size.y <= min_panel_size * editor_scale:
|
||||||
|
clamped_size.x = min_panel_size / viewport_ratio
|
||||||
|
clamped_size.y = min_panel_size
|
||||||
|
clamped_size = clamped_size * editor_scale
|
||||||
|
|
||||||
|
if not is_portrait and clamped_size.x <= min_panel_size * editor_scale:
|
||||||
|
clamped_size.x = min_panel_size
|
||||||
|
clamped_size.y = min_panel_size * viewport_ratio
|
||||||
|
clamped_size = clamped_size * editor_scale
|
||||||
|
|
||||||
|
# Round down to avoid sub-pixel artifacts, mainly seen around the margins.
|
||||||
|
return clamped_size.floor()
|
||||||
|
|
||||||
|
func get_project_window_size() -> Vector2:
|
||||||
|
var window_width = float(ProjectSettings.get_setting("display/window/size/viewport_width"))
|
||||||
|
var window_height = float(ProjectSettings.get_setting("display/window/size/viewport_height"))
|
||||||
|
|
||||||
|
return Vector2(window_width, window_height)
|
||||||
|
|
||||||
|
func get_project_window_ratio() -> float:
|
||||||
|
var project_window_size = get_project_window_size()
|
||||||
|
|
||||||
|
return project_window_size.y / project_window_size.x
|
||||||
|
|
||||||
|
func get_editor_viewport_size() -> Vector2:
|
||||||
|
var fallback_size = EditorInterface.get_editor_main_screen().size
|
||||||
|
|
||||||
|
# There isn't an API for getting the viewport node. Instead it has to be
|
||||||
|
# found by checking the parent's parent of the subviewport and find
|
||||||
|
# the correct node based on name and class.
|
||||||
|
var editor_sub_viewport_3d = EditorInterface.get_editor_viewport_3d(0)
|
||||||
|
var editor_viewport_container = editor_sub_viewport_3d.get_parent().get_parent().get_parent()
|
||||||
|
|
||||||
|
# Early return incase editor tree structure has changed.
|
||||||
|
if editor_viewport_container.get_class() != "Node3DEditorViewportContainer":
|
||||||
|
return fallback_size
|
||||||
|
|
||||||
|
return editor_viewport_container.size
|
||||||
|
|
||||||
|
func _on_resize_handle_button_down() -> void:
|
||||||
|
if state != InteractionState.NONE: return
|
||||||
|
|
||||||
|
state = InteractionState.RESIZE
|
||||||
|
initial_mouse_position = get_global_mouse_position()
|
||||||
|
initial_panel_size = panel.size
|
||||||
|
|
||||||
|
func _on_resize_handle_button_up() -> void:
|
||||||
|
state = InteractionState.NONE
|
||||||
|
|
||||||
|
func _on_drag_handle_button_down() -> void:
|
||||||
|
if state != InteractionState.NONE: return
|
||||||
|
|
||||||
|
state = InteractionState.DRAG
|
||||||
|
initial_mouse_position = get_global_mouse_position()
|
||||||
|
initial_panel_position = panel.global_position
|
||||||
|
|
||||||
|
func _on_drag_handle_button_up() -> void:
|
||||||
|
if state != InteractionState.DRAG: return
|
||||||
|
|
||||||
|
state = InteractionState.START_ANIMATE_INTO_PLACE
|
||||||
|
|
||||||
|
func _on_lock_button_pressed() -> void:
|
||||||
|
is_locked = !is_locked
|
||||||
200
addons/anthonyec.camera_preview/preview.tscn
Normal file
200
addons/anthonyec.camera_preview/preview.tscn
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
[gd_scene load_steps=8 format=3 uid="uid://xybmfvufjuv"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/anthonyec.camera_preview/preview.gd" id="1_6b32r"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://do6d60od41vmg" path="res://addons/anthonyec.camera_preview/Pin.svg" id="2_p0pa8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://btc01wc11tiid" path="res://addons/anthonyec.camera_preview/GuiResizerTopLeft.svg" id="2_t64ej"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://04l05jxuyt7k" path="res://addons/anthonyec.camera_preview/GuiResizerTopRight.svg" id="3_6yuab"]
|
||||||
|
|
||||||
|
[sub_resource type="ViewportTexture" id="ViewportTexture_hchdq"]
|
||||||
|
viewport_path = NodePath("Panel/SubViewport")
|
||||||
|
|
||||||
|
[sub_resource type="Gradient" id="Gradient_11p6r"]
|
||||||
|
offsets = PackedFloat32Array(0, 0.3, 0.6, 1)
|
||||||
|
colors = PackedColorArray(0, 0, 0, 0.235294, 0, 0, 0, 0.0784314, 0, 0, 0, 0.0784314, 0, 0, 0, 0.235294)
|
||||||
|
|
||||||
|
[sub_resource type="GradientTexture2D" id="GradientTexture2D_4dkve"]
|
||||||
|
gradient = SubResource("Gradient_11p6r")
|
||||||
|
width = 256
|
||||||
|
height = 256
|
||||||
|
fill_to = Vector2(2.08165e-12, 1)
|
||||||
|
|
||||||
|
[node name="Preview" type="Control"]
|
||||||
|
z_index = 999
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_6b32r")
|
||||||
|
|
||||||
|
[node name="Placeholder" type="Panel" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
modulate = Color(1, 1, 1, 0.705882)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -40.0
|
||||||
|
offset_top = -40.0
|
||||||
|
offset_right = 410.0
|
||||||
|
offset_bottom = 410.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
|
||||||
|
[node name="Panel" type="Panel" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -520.0
|
||||||
|
offset_top = -908.889
|
||||||
|
offset_right = -20.0
|
||||||
|
offset_bottom = -20.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
pivot_offset = Vector2(450, 300)
|
||||||
|
|
||||||
|
[node name="SubViewport" type="SubViewport" parent="Panel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
handle_input_locally = false
|
||||||
|
gui_disable_input = true
|
||||||
|
size_2d_override_stretch = true
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="Panel/SubViewport"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
current = true
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="Panel/SubViewport"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
ignore_rotation = false
|
||||||
|
|
||||||
|
[node name="ViewportMarginContainer" type="MarginContainer" parent="Panel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_constants/margin_left = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 4
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="TextureRect" type="TextureRect" parent="Panel/ViewportMarginContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
texture = SubResource("ViewportTexture_hchdq")
|
||||||
|
expand_mode = 1
|
||||||
|
|
||||||
|
[node name="Gradient" type="TextureRect" parent="Panel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = SubResource("GradientTexture2D_4dkve")
|
||||||
|
|
||||||
|
[node name="OverlayMarginContainer" type="MarginContainer" parent="Panel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_constants/margin_left = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 4
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="OverlayContainer" type="Control" parent="Panel/OverlayMarginContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="DragHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
focus_mode = 0
|
||||||
|
flat = true
|
||||||
|
|
||||||
|
[node name="ResizeLeftHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
offset_right = 60.0
|
||||||
|
offset_bottom = 60.0
|
||||||
|
size_flags_horizontal = 0
|
||||||
|
size_flags_vertical = 0
|
||||||
|
mouse_default_cursor_shape = 12
|
||||||
|
icon = ExtResource("2_t64ej")
|
||||||
|
flat = true
|
||||||
|
icon_alignment = 1
|
||||||
|
expand_icon = true
|
||||||
|
|
||||||
|
[node name="ResizeRightHandle" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -60.0
|
||||||
|
offset_bottom = 60.0
|
||||||
|
pivot_offset = Vector2(60, 60)
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
size_flags_vertical = 0
|
||||||
|
mouse_default_cursor_shape = 11
|
||||||
|
icon = ExtResource("3_6yuab")
|
||||||
|
flat = true
|
||||||
|
icon_alignment = 1
|
||||||
|
expand_icon = true
|
||||||
|
|
||||||
|
[node name="LockButton" type="Button" parent="Panel/OverlayMarginContainer/OverlayContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -60.0
|
||||||
|
offset_right = 60.0
|
||||||
|
pivot_offset = Vector2(0, 60)
|
||||||
|
size_flags_horizontal = 0
|
||||||
|
size_flags_vertical = 8
|
||||||
|
tooltip_text = "Always Show Preview"
|
||||||
|
toggle_mode = true
|
||||||
|
icon = ExtResource("2_p0pa8")
|
||||||
|
flat = true
|
||||||
|
icon_alignment = 1
|
||||||
|
expand_icon = true
|
||||||
|
|
||||||
|
[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_button_down"]
|
||||||
|
[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_button_up"]
|
||||||
|
[connection signal="renamed" from="Panel/OverlayMarginContainer/OverlayContainer/DragHandle" to="." method="_on_drag_handle_renamed"]
|
||||||
|
[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeLeftHandle" to="." method="_on_resize_handle_button_down"]
|
||||||
|
[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeLeftHandle" to="." method="_on_resize_handle_button_up"]
|
||||||
|
[connection signal="button_down" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeRightHandle" to="." method="_on_resize_handle_button_down"]
|
||||||
|
[connection signal="button_up" from="Panel/OverlayMarginContainer/OverlayContainer/ResizeRightHandle" to="." method="_on_resize_handle_button_up"]
|
||||||
|
[connection signal="pressed" from="Panel/OverlayMarginContainer/OverlayContainer/LockButton" to="." method="_on_lock_button_pressed"]
|
||||||
21
addons/godot_debug_environments/LICENSE
Normal file
21
addons/godot_debug_environments/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Vladi
|
||||||
|
|
||||||
|
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.
|
||||||
2
addons/godot_debug_environments/README.md
Normal file
2
addons/godot_debug_environments/README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Debug_environments
|
||||||
|
A simple Godot addon that allows to add context (extra scene) to scenes in "Run Current Scene" mode.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
@tool
|
||||||
|
extends EditorInspectorPlugin
|
||||||
|
|
||||||
|
func _can_handle(object):
|
||||||
|
return object is Node and object == EditorInterface.get_edited_scene_root()
|
||||||
|
|
||||||
|
func _parse_begin(object):
|
||||||
|
add_custom_control(create_ui(object))
|
||||||
|
|
||||||
|
func create_ui(node: Node) -> Control:
|
||||||
|
var path = DebugEnvironmentLib.get_debug_path(node)
|
||||||
|
var button = Button.new()
|
||||||
|
button.icon = load("res://addons/godot_debug_environments/flask.svg")
|
||||||
|
if(FileAccess.file_exists(path)):
|
||||||
|
button.text = "Edit testing environment"
|
||||||
|
button.pressed.connect(func(): edit_env(path), CONNECT_DEFERRED)
|
||||||
|
else:
|
||||||
|
button.text = "Create testing environment"
|
||||||
|
button.pressed.connect(func(): create_env(path), CONNECT_DEFERRED)
|
||||||
|
return button
|
||||||
|
|
||||||
|
func edit_env(path: String):
|
||||||
|
EditorInterface.open_scene_from_path(path)
|
||||||
|
|
||||||
|
func create_env(path: String):
|
||||||
|
if !DirAccess.dir_exists_absolute(path.get_base_dir()):
|
||||||
|
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
|
||||||
|
var env = Node.new()
|
||||||
|
env.name = path.get_file().replace(".tscn", "")
|
||||||
|
var target = Node.new()
|
||||||
|
target.name = "$DEBUG_TARGET$"
|
||||||
|
env.add_child(target)
|
||||||
|
target.owner = env
|
||||||
|
var scene = PackedScene.new()
|
||||||
|
scene.pack(env)
|
||||||
|
ResourceSaver.save(scene, path)
|
||||||
|
edit_env(path)
|
||||||
6
addons/godot_debug_environments/debug_environment_lib.gd
Normal file
6
addons/godot_debug_environments/debug_environment_lib.gd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class_name DebugEnvironmentLib extends Object
|
||||||
|
|
||||||
|
const debug_environment_path = "res://editor/debug_environments/debug_env_$SCENE$"
|
||||||
|
|
||||||
|
static func get_debug_path(node:Node) -> String:
|
||||||
|
return debug_environment_path.replace("$SCENE$", node.scene_file_path.get_file())
|
||||||
10
addons/godot_debug_environments/debug_environment_watcher.gd
Normal file
10
addons/godot_debug_environments/debug_environment_watcher.gd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# Get loaded scene
|
||||||
|
var node = get_tree().current_scene
|
||||||
|
# Check if debug environment is stored
|
||||||
|
var path = DebugEnvironmentLib.get_debug_path(node)
|
||||||
|
if not FileAccess.file_exists(path): return
|
||||||
|
# Replace instance with debug environment
|
||||||
|
get_tree().call_deferred("change_scene_to_file",path)
|
||||||
1
addons/godot_debug_environments/flask.svg
Normal file
1
addons/godot_debug_environments/flask.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff" class="icon icon-tabler icons-tabler-filled icon-tabler-flask"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 2a1 1 0 0 1 0 2v4.826l3.932 10.814l.034 .077a1.7 1.7 0 0 1 -.002 1.193l-.07 .162a1.7 1.7 0 0 1 -1.213 .911l-.181 .017h-11l-.181 -.017a1.7 1.7 0 0 1 -1.285 -2.266l.039 -.09l3.927 -10.804v-4.823a1 1 0 1 1 0 -2h6zm-2 2h-2v4h2v-4z" /></svg>
|
||||||
|
After Width: | Height: | Size: 467 B |
37
addons/godot_debug_environments/flask.svg.import
Normal file
37
addons/godot_debug_environments/flask.svg.import
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://clfknatufch1h"
|
||||||
|
path="res://.godot/imported/flask.svg-2fc53ef5b1742277dd2e351a1ac292cf.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/godot_debug_environments/flask.svg"
|
||||||
|
dest_files=["res://.godot/imported/flask.svg-2fc53ef5b1742277dd2e351a1ac292cf.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
|
||||||
19
addons/godot_debug_environments/launchSettingsBase.json
Normal file
19
addons/godot_debug_environments/launchSettingsBase.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Godot Debug": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$EDITOR$",
|
||||||
|
"commandLineArgs": "--path . --verbose",
|
||||||
|
"workingDirectory": ".",
|
||||||
|
"nativeDebugging": true
|
||||||
|
},
|
||||||
|
"Godot Debug $NAME$": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$EDITOR$",
|
||||||
|
"commandLineArgs": "--upwards $PATH$ --verbose",
|
||||||
|
"workingDirectory": ".",
|
||||||
|
"nativeDebugging": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
addons/godot_debug_environments/plugin.cfg
Normal file
10
addons/godot_debug_environments/plugin.cfg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Debug environments"
|
||||||
|
description="
|
||||||
|
A simple script that loads a given scene in a specified environment.
|
||||||
|
Good to test scenes in a certain context without having to manually select the right test scene.
|
||||||
|
"
|
||||||
|
author="Douwe Ravers"
|
||||||
|
version="1.0"
|
||||||
|
script="plugin.gd"
|
||||||
13
addons/godot_debug_environments/plugin.gd
Normal file
13
addons/godot_debug_environments/plugin.gd
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
var plugin
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
plugin = preload("res://addons/godot_debug_environments/debug_environment_editor_inspector.gd").new()
|
||||||
|
add_autoload_singleton("DebugEnvironmentWatcher", "res://addons/godot_debug_environments/debug_environment_watcher.gd")
|
||||||
|
add_inspector_plugin(plugin)
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
remove_autoload_singleton("DebugEnvironmentWatcher")
|
||||||
|
remove_inspector_plugin(plugin)
|
||||||
5
addons/scene-library/icons/thumb_placeholder.svg
Normal file
5
addons/scene-library/icons/thumb_placeholder.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 192">
|
||||||
|
<path fill="#ccc" d="m24.863 51.73 5.274 89.665 72.375 31.894 57.93-37.187 5.038-87.993-74.902-16.453" />
|
||||||
|
<path fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="6" d="m24.862 51.731 5.274 89.665 72.375 31.893 57.93-37.186 5.039-87.992-74.903-16.453L24.862 51.73m140.618-3.62-62.372 25.705" />
|
||||||
|
<path fill="none" stroke="black" stroke-width="6" d="m24.862 51.731 78.242 22.086-.593 99.472" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 502 B |
37
addons/scene-library/icons/thumb_placeholder.svg.import
Normal file
37
addons/scene-library/icons/thumb_placeholder.svg.import
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cqln7j6oifypf"
|
||||||
|
path="res://.godot/imported/thumb_placeholder.svg-81a80a6d7c59edb9d7ce28b01f213c5c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/scene-library/icons/thumb_placeholder.svg"
|
||||||
|
dest_files=["res://.godot/imported/thumb_placeholder.svg-81a80a6d7c59edb9d7ce28b01f213c5c.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
|
||||||
7
addons/scene-library/plugin.cfg
Normal file
7
addons/scene-library/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Scene Library"
|
||||||
|
description="A tool for easy work with your scenes"
|
||||||
|
author="Mansur Isaev and contributors"
|
||||||
|
version="0.7.0-dev"
|
||||||
|
script="plugin.gd"
|
||||||
65
addons/scene-library/plugin.gd
Normal file
65
addons/scene-library/plugin.gd
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Copyright (c) 2023-2024 Mansur Isaev and contributors - MIT License
|
||||||
|
# See `LICENSE.md` included in the source distribution for details.
|
||||||
|
|
||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
|
||||||
|
const SceneLibrary = preload("res://addons/scene-library/scripts/scene_library.gd")
|
||||||
|
|
||||||
|
const BUTTON_NAME: String = "Scene Library"
|
||||||
|
|
||||||
|
|
||||||
|
var _editor: SceneLibrary = null
|
||||||
|
var _button: Button = null
|
||||||
|
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
_editor = SceneLibrary.new()
|
||||||
|
_button = add_control_to_bottom_panel(_editor, BUTTON_NAME)
|
||||||
|
_editor.open_asset_request.connect(_on_open_asset_request)
|
||||||
|
_editor.show_in_file_system_request.connect(_on_show_in_file_system_request)
|
||||||
|
_editor.show_in_file_manager_request.connect(_on_show_in_file_manager_request)
|
||||||
|
_editor.library_saved.connect(_on_library_saved)
|
||||||
|
_editor.library_unsaved.connect(_on_library_unsaved)
|
||||||
|
|
||||||
|
get_parent().connect(&"scene_saved", _editor.handle_scene_saved)
|
||||||
|
EditorInterface.get_file_system_dock().files_moved.connect(_editor.handle_file_moved)
|
||||||
|
EditorInterface.get_file_system_dock().file_removed.connect(_editor.handle_file_removed)
|
||||||
|
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
remove_control_from_bottom_panel(_editor)
|
||||||
|
_editor.queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
func _save_external_data() -> void:
|
||||||
|
if _editor.is_saved():
|
||||||
|
return
|
||||||
|
|
||||||
|
var library_path: String = _editor.get_current_library_path()
|
||||||
|
if library_path.is_empty():
|
||||||
|
return
|
||||||
|
|
||||||
|
_editor.save_library(library_path)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_library_saved() -> void:
|
||||||
|
_button.set_text(BUTTON_NAME)
|
||||||
|
|
||||||
|
func _on_library_unsaved() -> void:
|
||||||
|
_button.set_text(BUTTON_NAME + "(*)")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_open_asset_request(path: String) -> void:
|
||||||
|
EditorInterface.open_scene_from_path(path)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_show_in_file_system_request(path: String) -> void:
|
||||||
|
EditorInterface.get_file_system_dock().navigate_to_path(path)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_show_in_file_manager_request(path: String) -> void:
|
||||||
|
var error := OS.shell_show_in_file_manager(ProjectSettings.globalize_path(path), true)
|
||||||
|
if error:
|
||||||
|
push_warning(error_string(error))
|
||||||
4
addons/scene-library/scene_library.cfg
Normal file
4
addons/scene-library/scene_library.cfg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
library=Array[Dictionary]([{
|
||||||
|
"assets": Array[Dictionary]([]),
|
||||||
|
"name": "Props"
|
||||||
|
}])
|
||||||
1469
addons/scene-library/scripts/scene_library.gd
Normal file
1469
addons/scene-library/scripts/scene_library.gd
Normal file
File diff suppressed because it is too large
Load Diff
39
editor/debug_environments/debug_env_player.tscn
Normal file
39
editor/debug_environments/debug_env_player.tscn
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
[gd_scene load_steps=8 format=3 uid="uid://y6j3eke6bhws"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/game.gd" id="1_xginw"]
|
||||||
|
[ext_resource type="PackedScene" path="res://player/player.tscn" id="2_qkysy"]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_tx3qi"]
|
||||||
|
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_mmhs2"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_tx3qi")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_r8f2r"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_mmhs2")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ob58c"]
|
||||||
|
albedo_color = Color(0, 0.46, 0.145667, 1)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_alxwk"]
|
||||||
|
material = SubResource("StandardMaterial3D_ob58c")
|
||||||
|
size = Vector2(20, 20)
|
||||||
|
|
||||||
|
[node name="debug_env_player" type="Node3D"]
|
||||||
|
script = ExtResource("1_xginw")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_r8f2r")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("PlaneMesh_alxwk")
|
||||||
|
|
||||||
|
[node name="Player" parent="." instance=ExtResource("2_qkysy")]
|
||||||
11
entities/faction/enemy/enemy.gd
Normal file
11
entities/faction/enemy/enemy.gd
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
extends Faction
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
13
entities/faction/faction.gd
Normal file
13
entities/faction/faction.gd
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class_name Faction extends Node
|
||||||
|
|
||||||
|
var buildings:Array[Node3D]:
|
||||||
|
get:
|
||||||
|
var buildings:Array[Node3D]
|
||||||
|
buildings.assign($Buildings.get_children())
|
||||||
|
return buildings
|
||||||
|
|
||||||
|
var units:Array[Node3D]:
|
||||||
|
get:
|
||||||
|
var buildings:Array[Node3D]
|
||||||
|
buildings.assign($Units.get_children())
|
||||||
|
return buildings
|
||||||
47
entities/faction/fog_of_war.gd
Normal file
47
entities/faction/fog_of_war.gd
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
class_name FogOfWar extends Node
|
||||||
|
|
||||||
|
@export var visual:bool = true
|
||||||
|
@export var width:int = 20
|
||||||
|
@export var height:int = 20
|
||||||
|
|
||||||
|
var size:int:
|
||||||
|
get: return width*height
|
||||||
|
|
||||||
|
var faction:Faction:
|
||||||
|
get: return get_parent() as Faction
|
||||||
|
|
||||||
|
var grid:Array[bool] = []
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
if not visual: $FogOfWarVisual.queue_free()
|
||||||
|
generate_new_grid()
|
||||||
|
visualize_grid()
|
||||||
|
|
||||||
|
func _on_tick() -> void:
|
||||||
|
update_fog_of_war()
|
||||||
|
visualize_grid()
|
||||||
|
|
||||||
|
func generate_new_grid()->void:
|
||||||
|
grid.resize(size)
|
||||||
|
for i in range(size):
|
||||||
|
grid[i] = true
|
||||||
|
|
||||||
|
func visualize_grid()->void:
|
||||||
|
if not has_node("FogOfWarVisual"): return
|
||||||
|
var fog_of_war_visual := $FogOfWarVisual as GridMap
|
||||||
|
for i in range(size):
|
||||||
|
var item := 0 if grid[i] else -1
|
||||||
|
fog_of_war_visual.set_cell_item(c2p(i2c(i)), item)
|
||||||
|
|
||||||
|
func update_fog_of_war()->void:
|
||||||
|
var entities := faction.buildings + faction.units
|
||||||
|
for i in range(size):
|
||||||
|
grid[i] = grid[i] and not entities.map(
|
||||||
|
func(entity:Node3D)->bool:
|
||||||
|
return entity.position.distance_squared_to(c2p(i2c(i))) < 10
|
||||||
|
).has(true)
|
||||||
|
|
||||||
|
# Converters from coordinates to index values
|
||||||
|
func c2i(coor:Vector2i)->int: return coor.x+coor.y*width
|
||||||
|
func i2c(index:int)->Vector2i: return Vector2i(index%width, index/width)
|
||||||
|
func c2p(coor:Vector2i)->Vector3i: return Vector3i(coor.x-width/2, 0, coor.y-height/2)
|
||||||
18
entities/faction/fog_of_war.tscn
Normal file
18
entities/faction/fog_of_war.tscn
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://ch7ug2prgwyyn"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/fog_of_war.gd" id="1_bm7vn"]
|
||||||
|
[ext_resource type="MeshLibrary" uid="uid://cesuajklj4ds4" path="res://resources/meshlib.tres" id="2_5docv"]
|
||||||
|
|
||||||
|
[node name="FogOfWar" type="Node"]
|
||||||
|
script = ExtResource("1_bm7vn")
|
||||||
|
|
||||||
|
[node name="TickTimer" type="Timer" parent="."]
|
||||||
|
wait_time = 0.5
|
||||||
|
autostart = true
|
||||||
|
|
||||||
|
[node name="FogOfWarVisual" type="GridMap" parent="."]
|
||||||
|
mesh_library = ExtResource("2_5docv")
|
||||||
|
cell_size = Vector3(1, 1, 1)
|
||||||
|
metadata/_editor_floor_ = Vector3(0, 0, 0)
|
||||||
|
|
||||||
|
[connection signal="timeout" from="TickTimer" to="." method="_on_tick"]
|
||||||
11
entities/faction/player/player.gd
Normal file
11
entities/faction/player/player.gd
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
extends Faction
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
33
entities/faction/player/player_camera.gd
Normal file
33
entities/faction/player/player_camera.gd
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
extends Camera3D
|
||||||
|
|
||||||
|
var move_speed : float = 5
|
||||||
|
var tilt_speed : float = 2
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
process_movement_speed()
|
||||||
|
process_movement(delta)
|
||||||
|
process_camera_tilt(delta)
|
||||||
|
|
||||||
|
func process_movement(delta:float) -> void:
|
||||||
|
var input_vector := Vector3.ZERO;
|
||||||
|
input_vector += Vector3.UP * Input.get_axis("move_down", "move_up")
|
||||||
|
input_vector += Vector3.FORWARD * Input.get_axis("move_back", "move_forward")
|
||||||
|
input_vector += Vector3.RIGHT * Input.get_axis("move_left", "move_right")
|
||||||
|
translate(input_vector * move_speed * delta)
|
||||||
|
position.y = clampf(position.y, 2, 20)
|
||||||
|
|
||||||
|
func process_movement_speed() -> void:
|
||||||
|
if Input.is_action_just_released("move_increase"):
|
||||||
|
move_speed = clampf(move_speed + 1, 1, 10)
|
||||||
|
if Input.is_action_just_released("move_decrease"):
|
||||||
|
move_speed = clampf(move_speed-1, 1, 10)
|
||||||
|
|
||||||
|
func process_camera_tilt(delta: float) -> void:
|
||||||
|
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
var mouse_move := -Input.get_last_mouse_velocity().normalized()
|
||||||
|
mouse_move *= tilt_speed * delta
|
||||||
|
rotation.y = rotation.y + mouse_move.x
|
||||||
|
rotation.x =clampf(rotation.x + mouse_move.y, -PI/2, 0)
|
||||||
|
else:
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
@@ -11,5 +11,72 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="RomAnts"
|
config/name="RomAnts"
|
||||||
|
run/main_scene="res://scenes/game.tscn"
|
||||||
config/features=PackedStringArray("4.3")
|
config/features=PackedStringArray("4.3")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
DebugEnvironmentWatcher="*res://addons/godot_debug_environments/debug_environment_watcher.gd"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
gdscript/warnings/untyped_declaration=2
|
||||||
|
gdscript/warnings/unsafe_property_access=1
|
||||||
|
gdscript/warnings/unsafe_method_access=1
|
||||||
|
gdscript/warnings/unsafe_cast=1
|
||||||
|
gdscript/warnings/unsafe_call_argument=1
|
||||||
|
gdscript/warnings/return_value_discarded=1
|
||||||
|
|
||||||
|
[editor]
|
||||||
|
|
||||||
|
movie_writer/movie_file="D:/Projects/movie.avi"
|
||||||
|
|
||||||
|
[editor_plugins]
|
||||||
|
|
||||||
|
enabled=PackedStringArray("res://addons/anthonyec.camera_preview/plugin.cfg", "res://addons/godot_debug_environments/plugin.cfg", "res://addons/scene-library/plugin.cfg")
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
move_up={
|
||||||
|
"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":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":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":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_down={
|
||||||
|
"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":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":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":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_forward={
|
||||||
|
"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":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_back={
|
||||||
|
"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,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_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,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_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,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_increase={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_decrease={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
28
resources/meshlib.tres
Normal file
28
resources/meshlib.tres
Normal file
File diff suppressed because one or more lines are too long
13
resources/meshlib.tscn
Normal file
13
resources/meshlib.tscn
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://bucaq3d3kowwa"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1o0cn"]
|
||||||
|
albedo_color = Color(0.22, 0.22, 0.22, 1)
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_dj03r"]
|
||||||
|
material = SubResource("StandardMaterial3D_1o0cn")
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||||
|
mesh = SubResource("BoxMesh_dj03r")
|
||||||
159
scenes/gam5CAE.tmp
Normal file
159
scenes/gam5CAE.tmp
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
[gd_scene load_steps=17 format=3 uid="uid://rnmcx0o0hdgb"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/game.gd" id="1_3n5gp"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player_camera.gd" id="2_1etxd"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player.gd" id="2_ba5k2"]
|
||||||
|
[ext_resource type="MeshLibrary" uid="uid://cesuajklj4ds4" path="res://resources/meshlib.tres" id="2_wyom5"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/fog_of_war.gd" id="4_8hagq"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/enemy/enemy.gd" id="6_y7ter"]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_tx3qi"]
|
||||||
|
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_mmhs2"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_tx3qi")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_r8f2r"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_mmhs2")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_e001c"]
|
||||||
|
width = 16
|
||||||
|
height = 16
|
||||||
|
|
||||||
|
[sub_resource type="PrismMesh" id="PrismMesh_dw2jx"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nljwt"]
|
||||||
|
albedo_color = Color(1, 0, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xv1v4"]
|
||||||
|
albedo_color = Color(0, 0.766667, 1, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ob58c"]
|
||||||
|
albedo_color = Color(0, 0.46, 0.145667, 1)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_alxwk"]
|
||||||
|
material = SubResource("StandardMaterial3D_ob58c")
|
||||||
|
size = Vector2(20, 20)
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_3yo4a"]
|
||||||
|
|
||||||
|
[node name="Game" type="Node3D"]
|
||||||
|
script = ExtResource("1_3n5gp")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_r8f2r")
|
||||||
|
|
||||||
|
[node name="Player" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_ba5k2")
|
||||||
|
|
||||||
|
[node name="PlayerCamera" type="Camera3D" parent="Player"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.965926, 0.258819, 0, -0.258819, 0.965926, 2.38419e-07, 1.98981, 3.94427)
|
||||||
|
script = ExtResource("2_1etxd")
|
||||||
|
|
||||||
|
[node name="Sprite3D" type="Sprite3D" parent="Player/PlayerCamera"]
|
||||||
|
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 1, 0)
|
||||||
|
cast_shadow = 0
|
||||||
|
axis = 1
|
||||||
|
billboard = 2
|
||||||
|
texture = SubResource("NoiseTexture2D_e001c")
|
||||||
|
|
||||||
|
[node name="PlayerUI" type="Control" parent="Player"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="SubViewportContainer" type="SubViewportContainer" parent="Player/PlayerUI"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -206.0
|
||||||
|
offset_top = -206.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
stretch = true
|
||||||
|
|
||||||
|
[node name="SubViewport" type="SubViewport" parent="Player/PlayerUI/SubViewportContainer"]
|
||||||
|
handle_input_locally = false
|
||||||
|
size = Vector2i(206, 206)
|
||||||
|
render_target_update_mode = 4
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="Player/PlayerUI/SubViewportContainer/SubViewport"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0)
|
||||||
|
projection = 1
|
||||||
|
size = 20.0
|
||||||
|
|
||||||
|
[node name="FogOfWar" type="Node" parent="Player"]
|
||||||
|
script = ExtResource("4_8hagq")
|
||||||
|
|
||||||
|
[node name="FogOfWarVisual" type="GridMap" parent="Player/FogOfWar"]
|
||||||
|
mesh_library = ExtResource("2_wyom5")
|
||||||
|
cell_size = Vector3(1, 1, 1)
|
||||||
|
metadata/_editor_floor_ = Vector3(0, 0, 0)
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="PlayerCamp" type="MeshInstance3D" parent="Player/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 0.40872, 7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_nljwt")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="Enemy" type="Node" parent="."]
|
||||||
|
script = ExtResource("6_y7ter")
|
||||||
|
|
||||||
|
[node name="FogOfWar" type="Node" parent="Enemy"]
|
||||||
|
script = ExtResource("4_8hagq")
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D3" type="MeshInstance3D" parent="Enemy/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0.40872, -7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_xv1v4")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="Environment" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="Terrain" type="MeshInstance3D" parent="Environment"]
|
||||||
|
mesh = SubResource("PlaneMesh_alxwk")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
|
[node name="Food" type="Node" parent="Environment"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.41598, 0.40872, -3.16507)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D4" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57951, 0.40872, 2.67711)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D5" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.39705, 0.408719, -3.50521)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D6" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0892634, 0.408719, 5.57122)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
159
scenes/gam77C8.tmp
Normal file
159
scenes/gam77C8.tmp
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
[gd_scene load_steps=17 format=3 uid="uid://rnmcx0o0hdgb"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/game.gd" id="1_3n5gp"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player_camera.gd" id="2_1etxd"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player.gd" id="2_ba5k2"]
|
||||||
|
[ext_resource type="MeshLibrary" uid="uid://cesuajklj4ds4" path="res://resources/meshlib.tres" id="2_wyom5"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/fog_of_war.gd" id="4_8hagq"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/enemy/enemy.gd" id="6_y7ter"]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_tx3qi"]
|
||||||
|
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_mmhs2"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_tx3qi")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_r8f2r"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_mmhs2")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_e001c"]
|
||||||
|
width = 16
|
||||||
|
height = 16
|
||||||
|
|
||||||
|
[sub_resource type="PrismMesh" id="PrismMesh_dw2jx"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nljwt"]
|
||||||
|
albedo_color = Color(1, 0, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xv1v4"]
|
||||||
|
albedo_color = Color(0, 0.766667, 1, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ob58c"]
|
||||||
|
albedo_color = Color(0, 0.46, 0.145667, 1)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_alxwk"]
|
||||||
|
material = SubResource("StandardMaterial3D_ob58c")
|
||||||
|
size = Vector2(20, 20)
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_3yo4a"]
|
||||||
|
|
||||||
|
[node name="Game" type="Node3D"]
|
||||||
|
script = ExtResource("1_3n5gp")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_r8f2r")
|
||||||
|
|
||||||
|
[node name="Player" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_ba5k2")
|
||||||
|
|
||||||
|
[node name="PlayerCamera" type="Camera3D" parent="Player"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.965926, 0.258819, 0, -0.258819, 0.965926, 2.38419e-07, 1.98981, 3.94427)
|
||||||
|
script = ExtResource("2_1etxd")
|
||||||
|
|
||||||
|
[node name="Sprite3D" type="Sprite3D" parent="Player/PlayerCamera"]
|
||||||
|
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 1, 0)
|
||||||
|
cast_shadow = 0
|
||||||
|
axis = 1
|
||||||
|
billboard = 2
|
||||||
|
texture = SubResource("NoiseTexture2D_e001c")
|
||||||
|
|
||||||
|
[node name="PlayerUI" type="Control" parent="Player"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="SubViewportContainer" type="SubViewportContainer" parent="Player/PlayerUI"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -206.0
|
||||||
|
offset_top = -206.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
stretch = true
|
||||||
|
|
||||||
|
[node name="SubViewport" type="SubViewport" parent="Player/PlayerUI/SubViewportContainer"]
|
||||||
|
handle_input_locally = false
|
||||||
|
size = Vector2i(206, 206)
|
||||||
|
render_target_update_mode = 4
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="Player/PlayerUI/SubViewportContainer/SubViewport"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0)
|
||||||
|
projection = 1
|
||||||
|
size = 20.0
|
||||||
|
|
||||||
|
[node name="FogOfWar" type="Node" parent="Player"]
|
||||||
|
script = ExtResource("4_8hagq")
|
||||||
|
|
||||||
|
[node name="FogOfWarVisual" type="GridMap" parent="Player/FogOfWar"]
|
||||||
|
mesh_library = ExtResource("2_wyom5")
|
||||||
|
cell_size = Vector3(1, 1, 1)
|
||||||
|
metadata/_editor_floor_ = Vector3(0, 0, 0)
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="PlayerCamp" type="MeshInstance3D" parent="Player/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 0.40872, 7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_nljwt")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="Enemy" type="Node" parent="."]
|
||||||
|
script = ExtResource("6_y7ter")
|
||||||
|
|
||||||
|
[node name="FogOfWar" type="Node" parent="Enemy"]
|
||||||
|
script = ExtResource("4_8hagq")
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D3" type="MeshInstance3D" parent="Enemy/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0.40872, -7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_xv1v4")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="Environment" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="Terrain" type="MeshInstance3D" parent="Environment"]
|
||||||
|
mesh = SubResource("PlaneMesh_alxwk")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
|
[node name="Food" type="Node" parent="Environment"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.41598, 0.40872, -3.16507)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D4" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57951, 0.40872, 2.67711)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D5" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.39705, 0.408719, -3.50521)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D6" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0892634, 0.408719, 5.57122)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
9
scenes/game.gd
Normal file
9
scenes/game.gd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class_name Game extends Node3D
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
234
scenes/game.tscn
Normal file
234
scenes/game.tscn
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
[gd_scene load_steps=21 format=3 uid="uid://rnmcx0o0hdgb"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/game.gd" id="1_3n5gp"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player_camera.gd" id="2_1etxd"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/player/player.gd" id="2_ba5k2"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ch7ug2prgwyyn" path="res://entities/faction/fog_of_war.tscn" id="5_8a5ny"]
|
||||||
|
[ext_resource type="Script" path="res://entities/faction/enemy/enemy.gd" id="6_y7ter"]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_tx3qi"]
|
||||||
|
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_mmhs2"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_tx3qi")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_r8f2r"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_mmhs2")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_e001c"]
|
||||||
|
width = 16
|
||||||
|
height = 16
|
||||||
|
|
||||||
|
[sub_resource type="PrismMesh" id="PrismMesh_dw2jx"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nljwt"]
|
||||||
|
albedo_color = Color(1, 0, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_api38"]
|
||||||
|
albedo_color = Color(0.53, 0, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleMesh" id="CapsuleMesh_cpeim"]
|
||||||
|
lightmap_size_hint = Vector2i(17, 14)
|
||||||
|
material = SubResource("StandardMaterial3D_api38")
|
||||||
|
radius = 0.25
|
||||||
|
height = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_qp8oi"]
|
||||||
|
resource_name = "db_anim"
|
||||||
|
length = 12.0
|
||||||
|
step = 0.5
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("MeshInstance3D:position")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 2, 2.5, 4, 4.5, 6, 7, 9, 9.5, 12),
|
||||||
|
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(-5.16842, 0.25, 6.861), Vector3(-5.16842, 0.25, -0.139), Vector3(-4.16842, 0.25, -0.139), Vector3(4.83158, 0.249999, -0.139), Vector3(5.83158, 0.249999, -1.139), Vector3(5.83158, 0.249999, -7.139), Vector3(4.83158, 0.249999, -7.139), Vector3(-5.16842, 0.249999, -7.139), Vector3(-6.16842, 0.249999, -6.139), Vector3(-6.16841, 0.249998, 4.861)]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("MeshInstance3D:rotation")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 2, 2.5, 4, 4.5, 6, 7, 9, 9.5, 12),
|
||||||
|
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(-1.5708, 0, 0), Vector3(-1.5708, 0, 0), Vector3(-1.5708, -1.5708, 0), Vector3(-1.5708, -1.5708, 0), Vector3(-1.5708, -7.17753e-23, 0), Vector3(-1.5708, -7.17753e-23, 0), Vector3(-1.5708, 1.5708, 0), Vector3(-1.5708, 1.5708, 0), Vector3(-1.5708, -3.14159, 0), Vector3(-1.5708, -3.14159, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_27gua"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("MeshInstance3D:position")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(-5.16842, 0.25, 6.861)]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("MeshInstance3D:rotation")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(-1.5708, 0, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ae667"]
|
||||||
|
_data = {
|
||||||
|
"RESET": SubResource("Animation_27gua"),
|
||||||
|
"db_anim": SubResource("Animation_qp8oi")
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xv1v4"]
|
||||||
|
albedo_color = Color(0, 0.766667, 1, 1)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ob58c"]
|
||||||
|
albedo_color = Color(0, 0.46, 0.145667, 1)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_alxwk"]
|
||||||
|
material = SubResource("StandardMaterial3D_ob58c")
|
||||||
|
size = Vector2(20, 20)
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_3yo4a"]
|
||||||
|
|
||||||
|
[node name="Game" type="Node3D"]
|
||||||
|
script = ExtResource("1_3n5gp")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_r8f2r")
|
||||||
|
|
||||||
|
[node name="Player" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_ba5k2")
|
||||||
|
|
||||||
|
[node name="PlayerCamera" type="Camera3D" parent="Player"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.965926, 0.258819, 0, -0.258819, 0.965926, 2.38419e-07, 1.98981, 3.94427)
|
||||||
|
script = ExtResource("2_1etxd")
|
||||||
|
|
||||||
|
[node name="Sprite3D" type="Sprite3D" parent="Player/PlayerCamera"]
|
||||||
|
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 1, 0)
|
||||||
|
cast_shadow = 0
|
||||||
|
axis = 1
|
||||||
|
billboard = 2
|
||||||
|
texture = SubResource("NoiseTexture2D_e001c")
|
||||||
|
|
||||||
|
[node name="PlayerUI" type="Control" parent="Player"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="SubViewportContainer" type="SubViewportContainer" parent="Player/PlayerUI"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -206.0
|
||||||
|
offset_top = -206.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
stretch = true
|
||||||
|
|
||||||
|
[node name="SubViewport" type="SubViewport" parent="Player/PlayerUI/SubViewportContainer"]
|
||||||
|
handle_input_locally = false
|
||||||
|
size = Vector2i(206, 206)
|
||||||
|
render_target_update_mode = 4
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="Player/PlayerUI/SubViewportContainer/SubViewport"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0)
|
||||||
|
projection = 1
|
||||||
|
size = 20.0
|
||||||
|
|
||||||
|
[node name="FogOfWar" parent="Player" instance=ExtResource("5_8a5ny")]
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="PlayerCamp" type="MeshInstance3D" parent="Player/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 0.40872, 7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_nljwt")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Player"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Player/Units"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -5.16842, 0.25, 6.861)
|
||||||
|
mesh = SubResource("CapsuleMesh_cpeim")
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="Player"]
|
||||||
|
root_node = NodePath("../Units")
|
||||||
|
libraries = {
|
||||||
|
"": SubResource("AnimationLibrary_ae667")
|
||||||
|
}
|
||||||
|
autoplay = "db_anim"
|
||||||
|
|
||||||
|
[node name="Enemy" type="Node" parent="."]
|
||||||
|
script = ExtResource("6_y7ter")
|
||||||
|
|
||||||
|
[node name="FogOfWar" parent="Enemy" instance=ExtResource("5_8a5ny")]
|
||||||
|
visual = false
|
||||||
|
|
||||||
|
[node name="Buildings" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D3" type="MeshInstance3D" parent="Enemy/Buildings"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0.40872, -7)
|
||||||
|
mesh = SubResource("PrismMesh_dw2jx")
|
||||||
|
skeleton = NodePath("../../../Environment/Terrain")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_xv1v4")
|
||||||
|
|
||||||
|
[node name="Units" type="Node" parent="Enemy"]
|
||||||
|
|
||||||
|
[node name="Environment" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="Terrain" type="MeshInstance3D" parent="Environment"]
|
||||||
|
mesh = SubResource("PlaneMesh_alxwk")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
|
[node name="Food" type="Node" parent="Environment"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.41598, 0.40872, -3.16507)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D4" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57951, 0.40872, 2.67711)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D5" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.39705, 0.408719, -3.50521)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D6" type="MeshInstance3D" parent="Environment/Food"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0892634, 0.408719, 5.57122)
|
||||||
|
mesh = SubResource("SphereMesh_3yo4a")
|
||||||
|
skeleton = NodePath("../../Terrain")
|
||||||
Reference in New Issue
Block a user