0 votes

Hi,
I'm programming a first person character for a 3D game. I followed the tutorial from KidsCanCode. Here is my code:

extends KinematicBody

onready var camera : Camera = $HeadPivot/Camera

var gravity :float = -30.0
var max_speed : float = 8.0
var jump_speed :float = 12.0
var jump : bool = false
var mouse_sensitivity : float = 0.002 # radians/pixel

var mouse_captured : bool = false

var velocity : Vector3 = Vector3()

func _init():
    # capture mouse
    Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
    mouse_captured = true


func get_input():

    # we want to move in the direction that the camera is facing
    # we maybe already moving
    var input_direction : Vector3 = Vector3()

    jump = false

    if Input.is_action_just_pressed("jump"):
        jump = true

    if Input.is_action_pressed("move_forward"):
        input_direction -= camera.global_transform.basis.z
    if Input.is_action_pressed("move_backwards"):
        input_direction += camera.global_transform.basis.z
    if Input.is_action_pressed("move_rightwards"):
        input_direction += camera.global_transform.basis.x
    if Input.is_action_pressed("move_leftwards"):
        input_direction -= camera.global_transform.basis.x

    input_direction = input_direction.normalized()

    return input_direction


func _unhandled_input(event):

    # rotation
    if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
        rotate_y(-event.relative.x*mouse_sensitivity)
        $HeadPivot.rotate_x(-event.relative.y*mouse_sensitivity)
        # avoid turn
        $HeadPivot.rotation.x = clamp($HeadPivot.rotation.x, -1.2, 1.2)

    # mouse capture
    if event.is_action_pressed("capture_mouse") and not event.is_echo():
        mouse_captured = not mouse_captured
        if not mouse_captured: # if not capture, release it
            Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
        else:
            Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)


func _physics_process(delta):

    velocity.y += gravity*delta
    if jump and is_on_floor():
        velocity.y += jump_speed

    var desired_velocity = get_input()*max_speed

    velocity.x = desired_velocity.x
    velocity.z = desired_velocity.z
    velocity = move_and_slide(velocity, Vector3.UP, true)

It works more or less. When the character is over a surface of many voxels, strange things happen, see this video. CollisionShapes are shown. This may also help: video.

The voxels CollisionShapes are created using Mesh.create_trimesh_shape(). Only visible faces are computed.

Any idea? Thanks!

Edit:

Tree structure:
root
- GameManager
- - Experimental
- - - VoxelsContainer (here there are all voxels as children, StaticBodys)
- - - Character (KinematicBody)
All voxels are children of VoxelsContainer, even the one in the middle of the floor. It seems that the problem arise when there is a flat surface of voxels.

Godot version 3.4
in Engine by (236 points)
edited by

create a new scene. Or clean the scene. And add two Static Body. One for the floor and one for the cube (upstairs) and try again

Or set the player's initial position on the scene relative to the floor and try again

See the edit. That is not the tree structure: all voxels are children of an Spatial and they are StaticBodys. The character is a sibling of that Spatial and it is a KinematicBody. I tried to put the character inside the voxels container, but the problem persists.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.