emirthab / third-person-controller

This addon includes 3rd person perspective locomotion and blockout materials, sky.
MIT License
37 stars 5 forks source link

ThirdPerson Character Controller doesn't move as is, and motion_velocity isn't defined #1

Closed CodeGuru12 closed 1 year ago

CodeGuru12 commented 2 years ago

This doesn't work in Godot 4 Alpha 7. Needs to also set_velocity(motion_velocity) prior to calling move_and_slide(), and define var motion_velocity = Vector3.ZERO at the top of the ThirdPersonController script.

ooo-mmm commented 2 years ago

It works after changing "motion_velocity" to "velocity" everywhere in scripts

CheapMeow commented 2 years ago

Totally, it needs three changes

1.Pivot.gd

extends Node3D

@onready var Player = get_parent()

func _input(event):
    if event is InputEventMouseMotion && Input.get_mouse_mode() != 0:
        var resultant = sqrt((event.relative.x * event.relative.x ) + (event.relative.y * event.relative.y ))
        var rot = Vector3(event.relative.y,-event.relative.x,0).normalized()
        rotate_object_local(rot , resultant * Player.MouseSensitivity)
        rotation.z = clamp(rotation.z,deg_to_rad(-0),deg_to_rad(0))
        rotation.x = clamp(rotation.x,deg_to_rad(-30),deg_to_rad(30))

2.LocomationStrafe.gd

extends AnimationTree

@onready var Player = get_parent()
@onready var StateMachine = get("parameters/playback")
@onready var Armature = Player.get_node("Armature")

func _process(delta):
    if active:
        var directionalSpeedMagnitude : float = sqrt( pow(Player.velocity.x, 2) + pow(Player.velocity.z, 2) )
        var movementState : Vector2 = directionalSpeedMagnitude * Player.inputDir / Player.SpeedUp
        var state = getMovementState()
        var x = lerp(state.x, movementState.x, 10 * delta)
        var y = lerp(state.y, movementState.y, 10 * delta)
        SetMovementState(Vector2(x,y))

        var rotationDir = Player.Pivot.rotation.y
        Armature.rotation.y = lerp_angle(Armature.rotation.y, rotationDir, delta * 5)

        if Player.is_on_floor():
            if StateMachine.get_current_node() == "FallingIdle":
                setJumping(false)
                StateMachine.travel("JumpingDown")
            if Player.direction:
                setJumping(false)
        elif (Player.velocity.y < Player.JumpForce):
            setJumping(true)
            StateMachine.travel("FallingIdle")

func SetMovementState(state) : set("parameters/Movement/Movement/blend_position",state)
func getMovementState() -> Vector2: return get("parameters/Movement/Movement/blend_position")

func setJumping(state) : set("parameters/Movement/JumpEvent/active",state)
func getJumping() : return get("parameters/Movement/JumpEvent/active")

3.CharacterController.gd

@tool
extends CharacterBody3D

@export_enum("Rotate", "Strafe") var LocomationType = 0
@export var Gravity : float = 25
@export var JumpForce : float = 10
@export var DefaultSpeed : float = 3.5
@export var SpeedUp : float = 7.0
@export var MouseSensitivity : float = 0.004
@export var DecelerationFactor : float = 10.0
@export var AccelerationFactor : float = 5.0    
@export var PivotPath : NodePath = "Pivot"

var SPEED : float
@onready var Pivot = get_node(PivotPath)

var inputDir : Vector2
var direction : Vector3

func _enter_tree():
    var armature = preload("res://addons/ThirdPersonTemplate/Character/Nodes/Armature.gltf").instantiate()
    var collider = preload("res://addons/ThirdPersonTemplate/Character/Nodes/CollisionShape3D.res")
    var locoStrafe = preload("res://addons/ThirdPersonTemplate/Character/Nodes/LocomationStrafe.res")
    var locoRot = preload("res://addons/ThirdPersonTemplate/Character/Nodes/LocomationRotate.res")
    var pivot = preload("res://addons/ThirdPersonTemplate/Character/Nodes/Pivot.res")
    var interpolatedCamera = preload("res://addons/ThirdPersonTemplate/Character/Nodes/InterPolatedCamera.tscn")

    armature.scale = Vector3(0.02, 0.02, 0.02)
    #armature.size = Vector3(0.02,0.02,0.02)
    add_child(armature)
    add_child(collider.instantiate())
    add_child(locoStrafe.instantiate())
    add_child(locoRot.instantiate())
    add_child(pivot.instantiate())
    add_child(interpolatedCamera.instantiate())

func _ready():
    if !Engine.is_editor_hint():
        if LocomationType == 1:
            get_node("LocomationStrafe").active = true
        else:
            get_node("LocomationRotate").active = true

        Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _physics_process(delta):
    if !Engine.is_editor_hint():
        if not is_on_floor():
            velocity.y -= Gravity * delta

        if Input.is_action_just_pressed("ui_accept") and is_on_floor():
            velocity.y = JumpForce

        inputDir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
        direction = -( (Pivot.transform.basis * global_transform.basis) * Vector3(inputDir.x, 0, inputDir.y)).normalized()
        SPEED = SpeedUp if Input.is_key_pressed(KEY_SHIFT) else DefaultSpeed

        if direction:
            velocity.x = lerpf(velocity.x, direction.x * SPEED, AccelerationFactor * delta)
            velocity.z = lerpf(velocity.z, direction.z * SPEED, AccelerationFactor * delta)
        else:
            velocity.x = lerpf(velocity.x, 0, DecelerationFactor * delta)
            velocity.z = lerpf(velocity.z, 0, DecelerationFactor * delta)

        move_and_slide()

func _input(event):
    var just_pressed = event.is_pressed() and not event.is_echo()
    if Input.is_key_pressed(KEY_ESCAPE) and just_pressed:
        if Input.get_mouse_mode() == 0:
            Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
        else:
            Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
emirthab commented 1 year ago

thanks for helps...