godot_voxel/doc/source/blocky_terrain.md
2021-02-14 21:52:39 +00:00

2.5 KiB

Blocky terrains

This page focuses more in detail on blocky terrains, Minecraft-like, or made of cubes.

VoxelMesherBlocky

Creating voxel types

TODO

Texturing

TODO

VoxelMesherCubes

TODO

Fast collisions alternative

Move and slide

Mesh-based collisions are quite accurate and feature-rich in Godot, however it has some drawbacks:

  • Trimesh collision shapes have to be built each time the terrain is modified, which is very slow.
  • The physics engine has to process arbitrary triangles near the player, which can't take advantage of particular situations, such as everything being cubes
  • Sometimes you may also want a simpler, more game-oriented collision system

The VoxelBoxMover class provides a Minecraft-like collision system, which can be used in a similar way to move_and_slide(). It is more limited, but is extremely fast and is not affected by tunnelling.

The code below shows how to use it, but see the blocky demo for the full code.

var box_mover = VoxelBoxMover.new()
var character_box  = AABB(Vector3(-0.4, -0.9, -0.4), Vector3(0.8, 1.8, 0.8))
var terrain = get_node("VoxelTerrain")

func _physics_process(delta):
	# ... Input commands that set velocity go here ...

    # Apply terrain collision
	var motion : Vector3 = velocity * delta
	motion = box_mover.get_motion(get_translation(), motion, character_box, terrain)
	global_translate(motion)
	velocity = motion / delta

!!! note this technique mainly works if you use VoxelMesherBlocky, because it gets information about which block is collidable from the VoxelLibrary used with it. It might have some limited support in other meshers though.

Raycast

An alternative raycast function exists as well, which returns voxel-specific results. It may be useful if you turned off classic collisions as well. This is accessible with the VoxelTool class. An instance of it bound to the terrain can be obtained with get_voxel_tool().

var terrain : VoxelTerrain = get_node("VoxelTerrain")
var vt : VoxelTool = terrain.get_voxel_tool()
var hit = vt.raycast(origin, direction, 10)

if hit != null:
    # The returned position is in voxel coordinates,
    # and can be used to access the value of the voxel with other functions of `VoxelTool`
    print("Hit voxel ", hit.position)