|
|
|
 |
Reply From: |
Tim Martin |
Hello,
One idea for this. You could start with four top-level nodes
- A MeshInstance called Wall with your wall mesh.
- A StaticBody called Floor. Add a MeshInstance as a child of Floor, and give this a new PlaneMesh. Then select this new MeshInstance and click (top-middle of screen) Mesh->Create Single Convex Collision Sibling
- A Spatial called BuildingManager with a GDScript attached.
- A Camera called Camera
BuildingManager could have script like (note: this isn’t tested, might have typos…)
extends Spatial
onready var current_wall = $"../Wall".duplicate()
onready var camera = $"../Camera"
func _ready():
add_child(current_wall)
func _physics_process(var _delta : float):
var mouse_pos = get_viewport().get_mouse_position()
var from = camera.project_ray_origin(mouse_pos)
var to = from + camera.project_ray_normal(mouse_pos) * 1000.0
var result = get_world().direct_space_state.intersect_ray(from, to)
if not result.empty():
current_wall.translation = result.position
if Input.is_action_just_pressed("ui_accept"):
current_wall = $"../Wall".duplicate()
add_child(current_wall)
Should keep the wall following the mouse as you move the mouse over the floor, until you press whatever you have bound to “ui_accept” at which point it will “fix” the wall in place and spawn a new one, which can also then be placed, and so on…
You will probably need to adjust the translation.y after the ray-cast so that the Wall is not half-embedded in the floor. And then you might want to add the option to rotate the wall, and also to start snapping the position you get back from the ray-cast to a grid.
You then probably want to make Wall a StaticBody (like Floor), with its own MeshInstance and CollisionShape children. Otherwise your player character could run right through it. These Wall StaticBody instances might need to be on a different collision_layer
from Floor, which you could then exclude when you call intersect_ray
. Or not… it depends on if you want to be able to build walls-on-walls…
EDIT: BuildingManager Node → Spatial
EDIT2: Add camera. Complete example at DemoBuilding.tscn - Pastebin.com
Thank you, Tim! Cheers!!
jm4rcos | 2020-05-08 19:44
but tim, it says that get_world() is not declared. can you help with that?
jm4rcos | 2020-05-08 20:36
I was trying to call the camera that is inside the player scene and the $“…/Wall”. But it shows "Attempt to call “duplicate()” in base “null instance” on a null instance. Is the camera used in camera.project_ray… the same as the player? And I created A MeshInstance, called floor in the main.scene, than a Static also in the scene and the Spatial (BuildingManager). Used singleton to call the scenes but did not worked
jm4rcos | 2020-05-10 01:04
Hello jm4rcos,
Yep, another typo. Forgot to mention that you need to add a Camera node too. The dangers of typing and not testing…
Here is the full example of the prototype above, I added some simple (x,z) snapping and rotation on LEFT and RIGHT buttons too.
It remains super basic, but hopefully it can give you a starting point from which you can expand.
Scene file: save this as DemoBuilding.tscn
inside your existing project DemoBuilding.tscn - Pastebin.com

Tim Martin | 2020-05-10 12:40
Thank you so much, Tim!!! Very helpful. I am already changind some thins to make the style i wanted. Just getting trouble when trying to modulate the “wall”. Cheers!!
jm4rcos | 2020-05-10 23:56