Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | olivierwierda |
Hey Godot community,
Over the last few weeks I’ve been very impressed with how intuitive everything is.
Currently I’m implementing a simple 3D runtime building system with which you can :
- Select an object to place from a GUI Toolbar
- Click on a tile within a different TileMap to place the selected object on top of that tile
This current code has no errors, and seems to work correctly when I check values in debugger but nothing happens when I try to place an Object.
func _process(delta):
if Input.is_mouse_button_pressed(BUTTON_LEFT) and buildModeOn :
mousePosition = get_viewport().get_mouse_position()
clickLocation = world_to_map(Vector3(mousePosition.x, mousePosition.y, 1))
set_cell_item(clickLocation.x, clickLocation.y, 3, selectedObject, 1)
if Input.is_mouse_button_pressed(BUTTON_RIGHT) and buildModeOn :
buildModeOn = false func _on_Lathe_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
var objLathe = 5
selectedObject = objLathe
buildModeOn = true
Anyone else who has built a building system with 3D tilemap that can assist?
Thanks in advance,
Olivier
No answers yet unfortunately, if anyone can help me with this I’ll post a detailed write-up on Reddit to show how to do it for other game devs too!
olivierwierda | 2019-11-04 22:48
If you’ve not got it yet, an extension to the previous answer. As previous says, you will need to add colliders by Mesh->Mesh tab center top ish screen->create convex static body.
Then re-convert and re-add the new meshlib to your gridmap.
I believe your debug results are a false positive. Your result is the viewport mouse position converted to a map, so I think you are placing your objects in a space relative to the viewport.
We want to convert the object collider selected to a map coord, so we can place relative to the existing object.
You were close in the direction of thinking, but to select an object in such a way, with an event, requires a collision(or an expensive pathfinding loop) afaik.
So we use rays and colliders.
Then, here is a bit more complete extension of the previous answer, with some basic explanation of what the methods are doing.
extends GridMap
const raylength = 4444 #Arbitrarily large ray
# warning-ignore:unused_argument
func _input(event):
if Input.is_mouse_button_pressed(BUTTON_LEFT):
var mouse_pos = get_viewport().get_mouse_position() #gets mouse position
var from = $".."/Camera.project_ray_origin(mouse_pos) #create a ray origin at the mouse position
var to = from + $".."/Camera.project_ray_normal(mouse_pos) * raylength #Extend the ray by raylength
var space_state = get_world().direct_space_state #Gets AABB/Physics information
var result = space_state.intersect_ray(from, to, [], 1) #Get ray intersection object, exclude colliders except layer 1 - this is our object
if result:
var selection = world_to_map(Vector3(result.position.x, result.position.y, result.position.z)) #Convert result object position to gridmap coordinate
print(selection)
Now it should be the proper map coordinate of the actual object/tile. So now we’ll be placing objects relative to the tile’s map position, rather than the viewport.
(1, 0, 4)
(1, 0, 3)
(0, 0, 3)
AI | 2019-12-07 09:01