This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

here is my code:

extends KinematicBody

enum State {IDLE, RUN, JUMP, FALL}

const JUMPSPEED = 10
const JUMP
FRAMES = 5
const HOP_FRAMES = 5

export var mouseysens = .19
export var mousexsens = .19
export var movespeed = 20
export var acceleration = 20
export var gravity = -10
export var friction = 1.15
export var max
climbangle = .6
export var angle
offreedom = 80
export var boost
accumulationspeed = 1
export var max
boost_multiplier = 2

Called when the node enters the scene tree for the first time.

func ready():
Input.set
mousemode(Input.MOUSEMODECAPTURED)
$Tween.connect("tween
allcompleted", self, "ontweenall_completed")

func physicsprocess(delta):
processinput(delta)
processmovement(delta)

Handles mouse movement

func input(event):
if event is InputEventMouseMotion && Input.get
mousemode() == Input.MOUSEMODECAPTURED:
rotate
y(deg2rad(event.relative.x * mouseysens * -1))
$UpperCollider/Camera.rotatex(deg2rad(event.relative.y * mousex_sens * -1))

    var camera_rot = $UpperCollider/Camera.rotation_degrees
    camera_rot.x = clamp(camera_rot.x, 90 + angle_of_freedom * -1, 90 + angle_of_freedom)
    $UpperCollider/Camera.rotation_degrees = camera_rot

var inbetween = false
func ontweenallcompleted():
inbetween = false
crouch_floor = false

var state = State.FALL
var onfloor = false
var frames = 0
var crouching = false
var crouch
floor = false #true if started crouching on the floor
var inputdir = Vector3(0, 0, 0)
func _process
input(delta):
# Toggle mouse capture
if Input.isactionjustpressed("uicancel"):
if Input.getmousemode() == Input.MOUSEMODEVISIBLE:
Input.setmousemode(Input.MOUSEMODECAPTURED)
else:
Input.setmousemode(Input.MOUSEMODEVISIBLE)

# Jump
if Input.is_action_pressed("jump") && on_floor && state != State.FALL && (frames == 0 || frames > JUMP_FRAMES + 1):
    frames = 0
    state = State.JUMP

# Crouch
if Input.is_action_just_pressed("crouch"):
    if on_floor:
        crouch_floor = true
    crouching = true
    $Tween.interpolate_property($LowerCollider, "translation", 
            Vector3(0, -.25, 0), Vector3(0,.25, 0), .1, Tween.TRANS_LINEAR)
    $Tween.start()
    inbetween = true

if Input.is_action_just_released("crouch"):
    crouching = false
    $Tween.interpolate_property($LowerCollider, "translation", 
            Vector3(0, .25, 0), Vector3(0, -.25, 0), .1, Tween.TRANS_LINEAR)
    $Tween.start()
    inbetween = true

# WASD
input_dir = Vector3(Input.get_action_strength("right") - Input.get_action_strength("left"), 
        0,
        Input.get_action_strength("back") - Input.get_action_strength("forward")).normalized()

var collision : KinematicCollision # Stores the collision from moveandcollide
var velocity := Vector3(0, 0, 0)
var rotationbuf = rotation # used to calculate rotation delta for air strafing
var turn
boost = 1
func processmovement(delta):
# state management
if !collision:
onfloor = false
if state != State.JUMP:
state = State.FALL
else:
if state == State.JUMP:
pass
elif Vector3.UP.dot(collision.normal) < max
climbangle:
state = State.FALL
else:
on
floor = true
if inputdir.length() > .1 && (frames > JUMPFRAMES+HOPFRAMES || frames == 0):
state = State.RUN
turn
boost = 1
else:
state = State.IDLE

#jump state
if state == State.JUMP && frames < JUMP_FRAMES:
    velocity.y = JUMP_SPEED
    frames += 1 * delta * 60
elif state == State.JUMP:
    state = State.FALL

#fall state
if state == State.FALL:
    if inbetween && crouching && crouch_floor:
        velocity.y = gravity;
    if velocity.y > gravity:
        velocity.y += gravity * delta * 4

#run state
if state == State.RUN:
    velocity += input_dir.rotated(Vector3(0, 1, 0), rotation.y) * acceleration
    if Vector2(velocity.x, velocity.z).length() > (move_speed/2 if crouching else move_speed):
        velocity = velocity.normalized() * (move_speed/2 if crouching else move_speed)
    velocity.y = ((Vector3(velocity.x, 0, velocity.z).dot(collision.normal)) * -1)

    # fake gravity to keep character on the ground
    # increase if player is falling down slopes instead of running
    velocity.y -= .0001 + (int(velocity.y < 0) * 1.1)  


#idle state
if state == State.IDLE && frames < HOP_FRAMES + JUMP_FRAMES:
    frames += 1 * delta * 60
elif state == State.IDLE:
    turn_boost = 1
    if velocity.length() > .5:
        velocity /= friction
        velocity.y = ((Vector3(velocity.x, 0, velocity.z).dot(collision.normal)) * -1) - .0001

#air strafe
if state > 2:
    #x axis movement
    var rotation_d = rotation - rotation_buf
    if input_dir.x > .1 && rotation_d.y < 0:
        velocity = velocity.rotated(Vector3.UP, rotation_d.y )
        turn_boost += boost_accumulation_speed * delta 
    elif input_dir.x < -.1 && rotation_d.y > 0:
        velocity = velocity.rotated(Vector3.UP, rotation_d.y ) 
        turn_boost += boost_accumulation_speed * delta 

    if abs(input_dir.x) < .1 && on_floor:
        #z axis movement
        var movement_vector = Vector3(0,0,input_dir.z).rotated(Vector3(0, 1, 0), rotation.y) * move_speed /2
        if movement_vector.length() < .1:
            velocity = velocity
        elif Vector2(velocity.x, velocity.z).length() < move_speed:
            var xy = Vector2(movement_vector.x , movement_vector.z).normalized()
            velocity += Vector3(xy.x, 0, xy.y) * acceleration

    turn_boost = clamp(turn_boost, 1, max_boost_multiplier)
    rotation_buf = rotation

#apply
if velocity.length() >= .5 || inbetween:
    collision = move_and_collide(velocity * Vector3(turn_boost, 1, turn_boost) * delta)
else:
    velocity = Vector3(0, velocity.y, 0)
if collision:
    if Vector3.UP.dot(collision.normal) < .5:
        velocity.y += delta * gravity
        clamp(velocity.y, gravity, 9999)
        velocity = velocity.slide(collision.normal).normalized() * velocity.length()
    elif turn_boost > 1.01:
        velocity = Vector3(velocity.x, velocity.y + ((Vector3(velocity.x, 0, velocity.z).dot(collision.normal)) * - 2) , velocity.z)
    else:
        velocity = velocity
Godot version 3.5.1
in Engine by (39 points)
edited by

1 Answer

0 votes

I don't know about state machine but make a if statement

for example
if Input.isactionpressed("uiright") :
-< motion.x = speed
-< $AnimatedSprite.play("Walk")
-< if Input.is
action_pressed("Shift") :
-<-< motion.x = speed * 2
-<-< $AnimatedSprite.play("Run")

by (59 points)
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 Frequently asked questions and 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 [email protected] with your username.