Mini maps are often very important to visualize the world from above. In some games, they are just used to determine the position of enemies on the map that are not in our view. Sometimes, we need accurate view of the world from top-down perspective.
My approach in was to render the world from the top, using a second camera. And then later we can add more effects on top, such as displaying enemies as red dots on their actual positions, and so on.
This post is part of godot RTS tutorial series.
Creating Minimap in 3D game
Create a folder named “MinimapSystem”. Then create a scene inside it for the minimap module. The scene should have a structure like this:
Node
SubViewportContainer
SubViewport
Panel
Attach a script to the root node as shown. In that script, I used Godot’s RenderingServer
to attach a second camera to the viewport. Basically, Godot does not have any option of rending with multiple cameras at once, so we have to use the lower-level API, which is the rendering server, to use multiple cameras at once.
extends Node
# Top-down camera used for minimap
@export var minimap_camera: Camera3D
# player instance to make the camera follow
@export var player: Node3D
# Thanks to: https://stackoverflow.com/questions/77315722/split-screen-in-godot-3d-with-a-single-scene-containing-2-cameras
# For teaching me how to render with 2 cameras without scene replication as in general SubViewport usage
func _ready():
var sub_viewport: SubViewport = $SubViewportContainer/SubViewport
var normal_camera: Camera3D = get_viewport().get_camera_3d()
var minimap_camera_rid = minimap_camera.get_camera_rid()
var normal_camera_rid = normal_camera.get_camera_rid()
var sub_viewport_rid = sub_viewport.get_viewport_rid()
var viewport_rid = get_viewport().get_viewport_rid()
RenderingServer.viewport_attach_camera(sub_viewport_rid, minimap_camera_rid)
RenderingServer.viewport_attach_camera(viewport_rid, normal_camera_rid)
func _process(delta):
minimap_camera.global_position.x = player.global_position.x
minimap_camera.global_position.z = player.global_position.z
in the code, we have taken RIDs of main viewport, sub-viewport, main camera & our second camera. We then used RenderingServer.viewport_attach_camera
to attach main camera to main viewport 7 second (mini-map camera) for sub-viewport.
Finally, the position of minimap camera (second camera) is set to be centered on the player. See _process
above.
That’s all. Just instance mini-map on the main level as a child scene.
Thank you for reading <3