Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e2651d5
Broke Fog of war manager to vision manager and fog of war node
amitnos123 Apr 19, 2025
9b74bf7
removed add addons/rts_framework/features/vision/unit_vision_data_wea…
amitnos123 Apr 19, 2025
5eeb5eb
I worte await vision_manager and forgot .ready
amitnos123 Apr 19, 2025
4435b90
Enchanced how null treated in UnitVisionData class
amitnos123 Apr 19, 2025
532b524
Enchanced how UnitVisionData class position sync func chekck if emit …
amitnos123 Apr 19, 2025
3ea9fde
Changed according to coderabbitai PR
amitnos123 Apr 19, 2025
5160968
fixed typo
amitnos123 Apr 19, 2025
2d96fc4
Changed according to coderabbitai PR
amitnos123 Apr 19, 2025
57f70bd
Changed according to coderabbitai PR
amitnos123 Apr 19, 2025
0398535
Added guard material_override in getters
amitnos123 Apr 19, 2025
0f55b31
Updated comments in code
amitnos123 Apr 19, 2025
7a74ac1
demo/game.tscn
amitnos123 Apr 19, 2025
30565c8
Merge branch 'rluders:main' into enhancement/vision
amitnos123 Apr 21, 2025
43f517a
Connected VisibilityField's signals to VisionManager
amitnos123 Apr 21, 2025
13de27f
Added draw_node_on_minimap function for other scripts to able to draw…
amitnos123 Apr 23, 2025
aa9f3e3
Fixed bug. Prefore this commit, the function adds as child to wrong n…
amitnos123 Apr 24, 2025
6b2fba1
Merge branch 'rluders:main' into enhancement/vision
amitnos123 May 7, 2025
d3a7235
Minimap now validate in ready function, if vision_data from vision ma…
amitnos123 May 7, 2025
f481f22
cleaning units which stop revealing
amitnos123 May 7, 2025
9f09b63
removed comments in code
amitnos123 May 7, 2025
2c97cf5
Changes according to Coderabbitai PR
amitnos123 May 7, 2025
24476c3
currected starting values of fog_circle_color and shroud_circle_color
amitnos123 May 7, 2025
926d363
Disable physics processing on _vision_data == null
amitnos123 May 7, 2025
aa66716
on adding new circle, sync circle's position
amitnos123 May 7, 2025
1e80d81
changed how handles vision_manager == null
amitnos123 May 7, 2025
ede0e45
when fails to draw circle on minimap delete the node
amitnos123 May 7, 2025
eb6d812
when vision_manager is null, pause both physics and normal proccessing
amitnos123 May 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions addons/rts_framework/features/vision/fog_of_war.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
@tool
extends MeshInstance3D
class_name FogOfWarManager

@export var vision_manager : VisionManager:
set(value):
_vision_manager = value
if _vision_manager:
_apply_fog_texture_from_vision_manager()
get:
return _vision_manager

# Private backing field
var _vision_manager : VisionManager

@export_category("Fog Values")

## The size of a single pixel in the 3D world
var _texture_units_per_world_unit: int = 2
@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int = 2 : # px/length
set(value):
if material_override:
material_override.set_shader_parameter("texture_units_per_world_unit", value)
_texture_units_per_world_unit = value
get:
return _texture_units_per_world_unit

## Color of the generated fog
@export var fog_color : Color :
set(value):
if material_override:
material_override.set_shader_parameter("color", value)
get:
if material_override:
return material_override.get_shader_parameter("color")
return Color.BLACK

## Controls the size of the fade-out effect at the edges of the visible area, creating a smooth transition between visible and fog areas.
@export var outer_margin_for_fade_out : float :
set(value):
if material_override:
material_override.set_shader_parameter("outer_margin_for_fade_out", value)
get:
if material_override:
return material_override.get_shader_parameter("outer_margin_for_fade_out")
return 0.0

@export_category("Debug Values")
## Shows small texture of the fog
@export var debug_texture_view : bool = false:
set(value):
if material_override:
material_override.set_shader_parameter("debug_texture_view", value)
get:
if material_override:
return material_override.get_shader_parameter("debug_texture_view")
return false

## Controls the size of the debug texture view when enabled
@export_range(0, 1) var debug_texture_view_size : float = 0.2:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
set(value):
if material_override:
material_override.set_shader_parameter("debug_texture_view_size", value)
get:
if material_override:
return material_override.get_shader_parameter("debug_texture_view_size")
return 0.2

# Private backing field to store the texture
var _fog_texture : ViewportTexture
var fog_texture : ViewportTexture:
set(value):
_fog_texture = value # Store in backing field
if material_override: # Check if material exists
material_override.set_shader_parameter("world_visibility_texture", value)
get:
return _fog_texture # Return from backing field


func _ready() -> void:
if vision_manager:
await vision_manager.ready
var fog_texture_result = vision_manager.get_fog_texture()
if fog_texture_result:
fog_texture = fog_texture_result
else:
push_warning("FogOfWarManager: 'vision_manager' is not assigned – fog texture cannot be applied.")

func _apply_fog_texture_from_vision_manager() -> void:
if _vision_manager == null:
return
var fog_texture_result = _vision_manager.get_fog_texture()
if fog_texture_result:
fog_texture = fog_texture_result
28 changes: 28 additions & 0 deletions addons/rts_framework/features/vision/fog_of_war.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[gd_scene load_steps=6 format=3 uid="uid://71g6dowvqb5i"]

[ext_resource type="Script" uid="uid://de87xn1b8u07i" path="res://addons/rts_framework/features/vision/fog_of_war.gd" id="1_vrsar"]
[ext_resource type="Shader" uid="uid://cbo2vdgrqc60a" path="res://addons/rts_framework/features/vision/detailed_fog_of_war.gdshader" id="2_oehrr"]

[sub_resource type="ViewportTexture" id="ViewportTexture_m5cnj"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_imaik"]
resource_local_to_scene = true
render_priority = 2
shader = ExtResource("2_oehrr")
shader_parameter/color = Color(0, 0, 0, 1)
shader_parameter/world_visibility_texture = SubResource("ViewportTexture_m5cnj")
shader_parameter/texture_units_per_world_unit = 2
shader_parameter/outer_margin_for_fade_out = 0.0
shader_parameter/debug_texture_view = false
shader_parameter/debug_texture_view_size = 0.2

[sub_resource type="QuadMesh" id="QuadMesh_3f4cn"]
flip_faces = true
size = Vector2(2, 2)

[node name="FogOfWar" type="MeshInstance3D"]
material_override = SubResource("ShaderMaterial_imaik")
cast_shadow = 0
extra_cull_margin = 16384.0
mesh = SubResource("QuadMesh_3f4cn")
script = ExtResource("1_vrsar")
28 changes: 0 additions & 28 deletions addons/rts_framework/features/vision/fog_of_war_manager.gdshader

This file was deleted.

This file was deleted.

101 changes: 52 additions & 49 deletions addons/rts_framework/features/vision/minimap.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class_name Minimap

const DynamicCircle2D : PackedScene = preload("res://addons/rts_framework/features/vision/dynamic_circle_2d.tscn")

@export var fog_of_war_manager : FogOfWarManager
@export var vision_manager : VisionManager

var _unit_to_circles_mapping : Dictionary = {}
var _vision_data : Dictionary

## Texture representing the fog of war alpha layer
##
Expand All @@ -35,70 +35,73 @@ var fog_texture : Texture2D : # fog_texture multiply the images above. This to f
@onready var _minimap_viewport: SubViewport = find_child("CombinedViewport") as SubViewport

func _ready() -> void:
assert(fog_of_war_manager != null, "Minimap missing fog of war manager node. Minimap Node Name: " + self.name)
var fog_of_war_combined_viewport = fog_of_war_manager.combined_viewport
if fog_of_war_combined_viewport:
var fog_texture_result = fog_of_war_manager.combined_viewport.get_texture()
if fog_texture_result:
fog_texture = fog_texture_result
else:
push_error("Failed to retrieve fog of war texture. Minimap Node Name: " + self.name)
if vision_manager == null:
push_error("Minimap missing VisionManager – minimap will be disabled. Minimap Node Name: " + self.name)
set_physics_process(false)
set_process(false)
return
var fog_texture_result = vision_manager.get_fog_texture()
if fog_texture_result:
fog_texture = fog_texture_result
else:
push_error("Failed to retrieve fog of war combined viewport. Minimap Node Name: " + self.name)
push_error("Failed to retrieve fog of war texture. Minimap Node Name: " + self.name)
_vision_data = vision_manager.get_vision_data()
if _vision_data == null:
push_error("VisionManager returned null vision data. Minimap Node Name: " + self.name)
set_physics_process(false) # Disable physics processing to prevent runtime errors
return # Abort further initialisation – minimap cannot function without data

if not Engine.is_editor_hint():
var circle = find_child("EditorOnlyCircle")
if circle:
circle.queue_free()

func _physics_process(_delta : float) -> void:
var visible_units : Dictionary = {}
var units_to_sync = fog_of_war_manager.get_visible_units()
for unit in units_to_sync:
for unit in _vision_data.keys():
if not unit.is_revealing():
continue
visible_units[unit] = 1
if not _unit_is_mapped(unit):
if not _unit_is_minimap_mapped(unit):
_map_unit_to_new_circles_body(unit)
_sync_vision_to_unit(unit)
for mapped_unit in _unit_to_circles_mapping:
if not mapped_unit in visible_units:
_cleanup_mapping(mapped_unit)

Comment thread
amitnos123 marked this conversation as resolved.
func _unit_is_mapped(unit : BaseEntity) -> bool:
return unit in _unit_to_circles_mapping
func _unit_is_minimap_mapped(unit : BaseEntity) -> bool:
if _vision_data != null:
if unit in _vision_data:
return _vision_data[unit].minimap_circle != null # If unit has minimap_circle
return false

## Creates visibility representation for a unit on the minimap
## Parameters:
## - unit: The entity to create visibility for
## - default_color: The default color of the visibility circle
## - default_radius: The default radius of visibility
func _map_unit_to_new_circles_body(unit : BaseEntity, default_color : Color = Color.BLUE, default_radius : int = 5) -> void:
var minimap_circle = DynamicCircle2D.instantiate() # Make a white circle 2D

if unit.has_method("get_team_color"): # If unit has get_team_color, use that color
minimap_circle.color = unit.get_team_color()
else: # if doesn't have the function, use the default one
minimap_circle.color = default_color # Set color

if unit.has_method("get_sight_range"): # Set circle size to world units and unit sight range
minimap_circle.radius = unit.get_sight_range() # If has sight range, then use it
else:
minimap_circle.radius = default_radius # If doesn't have sight range, then use default
if _vision_data != null:
var minimap_circle = DynamicCircle2D.instantiate() # Make a white circle 2D

_minimap_viewport.add_child(minimap_circle) # Add the view circle 2D to fog of war viewport. In the fog of war viewport it create an image for the fog of war.
_unit_to_circles_mapping[unit] = minimap_circle # Keep map to connect unit with fog of war view

func _sync_vision_to_unit(unit : BaseEntity) -> void:
var unit_pos_3d = unit.global_transform.origin
var unit_pos_2d = Vector2(unit_pos_3d.x, unit_pos_3d.z) * fog_of_war_manager.texture_units_per_world_unit
_unit_to_circles_mapping[unit].position = unit_pos_2d

func _cleanup_mapping(unit : BaseEntity) -> void:
_unit_to_circles_mapping[unit].queue_free()
_unit_to_circles_mapping.erase(unit)
if unit.has_method("get_team_color"): # If unit has get_team_color, use that color
minimap_circle.color = unit.get_team_color()
else: # if doesn't have the function, use the default one
minimap_circle.color = default_color # Set color

if unit.has_method("get_sight_range"): # Set circle size to world units and unit sight range
minimap_circle.radius = unit.get_sight_range() # If has sight range, then use it
else:
minimap_circle.radius = default_radius # If doesn't have sight range, then use default

var did_draw : bool = draw_node_on_minimap(minimap_circle) # Add the view circle 2D to fog of war viewport. In the fog of war viewport it create an image for the fog of war.

if did_draw:
_vision_data[unit].minimap_circle = minimap_circle # Keep map to connect unit with fog of war view
# place at the correct coordinates straight away
_vision_data[unit].sync_position(vision_manager.texture_units_per_world_unit)
else:
minimap_circle.queue_free()

func _exit_tree() -> void:
# Clean up all remaining circles
for unit in _unit_to_circles_mapping.keys():
_cleanup_mapping(unit)
_unit_to_circles_mapping.clear()
## Addes draw_node(:CanvasItem) in way to draw it over other (preview) things in the minimap
##
## Return true on success, false on fail
func draw_node_on_minimap(draw_node : CanvasItem) -> bool:
if _minimap_viewport:
_minimap_viewport.add_child(draw_node)
return true
return false
Loading
Loading