I'm trying to make a system where you are placing buildings in a small level, and ideally I would like it to be able to handle different elevations. I'm aiming for something like in an RTS or city-building game.
I understand that what I need to do is cast a ray from the camera, through the mouse, and wherever it intersects the ground get that location. Then have a 'ghost' version of the building tracked to that location, until the user clicks, at which point the ghost disappears and that building is instanced in the 'main' scene, at the location corresponding to the mouse. I also understand that I need to use signals between the camera controller and the main scene, so that the instanced building stays where it is in the level.
I understand the concepts, but I'm early in my learning process. My efforts so far have resulted in a weird offset from the mouse, and no buildings spawning at all.
My current code is a mish-mash of different tutorials, and I'll try to only share the relevant bits:
[in script of the Camera Controller]
signal place_building(building, direction, location)
onready var house1 = preload("res://scenes/House1.tscn")
onready var ghost = $ghost
func _process(delta: float) -> void:
if _placing_building == true:
_building()
func _building():
var ghost_position = _get_ground_click_location()
ghost.translation = temp_position
if Input.is_action_pressed("scroll_wheel_up"):
ghost.rotation_degrees.y += rotation_speed * 0.2
if Input.is_action_pressed("scroll_wheel_down"):
ghost.rotation_degrees.y -= rotation_speed * 0.2
# this rotation isn't working either, but that's low priority at the moment #
if Input.is_action_pressed("mouse_select"):
var pos = ghost_position
var rot = ghost.rotation_degrees
Events.emit_signal("place_building", house1, rot, pos)
func _get_ground_click_location() -> Vector3:
var mouse_pos = get_viewport().get_mouse_position()
var ray_from = camera.project_ray_origin(mouse_pos)
var ray_to = ray_from + camera.project_ray_normal(mouse_pos) * RAY_LENGTH
return GROUND_PLANE.intersects_ray(ray_from, ray_to)
# this is used for part of the camera zoom code, and is based on a ground plane. If I have to use this then
so be it, but I would prefer to use the collision data for the ground #
[in script of the Main Scene]
func _on_CameraController_place_building(building, direction, location):
var b = building.instance()
add_child(b)
b.rotation = direction
b.position = location
Am I on the right track here, and where do I go from here? Any guidance, or links to tutorials is much appreciated, though I've been unable to find a relevant tutorial for this that doesn't use a gridmap, which I'm hesitant to use, but will if it's my only option.
Thanks for taking the time to read and have a lovely day.