–1 vote

I am trying to have different animations play depending on movement direction and speed. I have been trying to get this to work for a while now, but to no avail.

The Animation Tree Player does seem to work fine when in preview mode, but animation simply does not run in Play.

Animation Tree Player does seem to move between the different animations, but just does not play each of the animations after switching.

I have no idea what's causing this.

Is my code missing something? I set the animation tree player as active and I made the code change the value of the BlendSpace2D, not accurately (just to test it for now).

The following is a video of the issue that I am experiencing.
https://drive.google.com/file/d/1FRttNpUonKL2GNWl8CZvBVJI-QN3Dx7K/view?usp=sharing

Any help will be really appreciated. This is really frustrating me.

Godot version 3.2.3
in Engine by (11 points)

The code is visible if you download the video and play it. If you play it directly on google drive, it won't be visible.

The code I have, the parts concerning the animation tree player is as follows:

onready var animationPlayer = $CharacterGraphic/AnimationPlayer
onready var animationTree = $AnimationTree

func _ready():

    animationTree.active = true

func _physics_process(delta):

    if is_on_floor():
        velocity.x = move_toward(velocity.x,maxMovementSpeed*moveDirection.x,movementAcceleration)
        velocity.z = move_toward(velocity.z,maxMovementSpeed*moveDirection.z,movementAcceleration)
        var currentSpeed = velocity.length()
        var max1Speed = currentSpeed/maxMovementSpeed

        animationTree.set("parameters/BlendSpace2D/blend_position",Vector2(moveDirection.x,moveDirection.z))
        print(animationTree.get("parameters/BlendSpace2D/blend_position"))

Thank you, your sarcasm is much appreciated.

Actually, the fact that I am soliciting help from strangers and keeping it as easy as possible is precisely why I uploaded a google video and kept it down to the 15 lines of code that had anything to do with the animation tree player or the animation player, so that these helpful strangers don't have to go through hundreds of lines of code.

I was hoping that it is a very obvious oversight or problem with another setting in the UI, not in the code, that I, being an inexperienced developer that I am, simply overlooked, and that someone more experienced could spot right away with the video clip I uploaded, which, again, can be downloaded and played (or you can just click the gear (setting) icon and set the video quality to 1080p and you should be able to see the code as well)

Also, I kept it down to those lines of codes, because the animation plays just fine if I am just using animation player instead of animation tree player (e.g. "animationPlayer.play("WalkForward")" - this can be seen in the code in the video as well, but I commented out those lines in the demonstration). So I am thinking the issue must be from those lines of code or not because of the code at all.

My bad. I don't understand why it isn't giving you a better resolution. It is readable watching through google drive from my end (using a different browser)
enter image description here

If you still wouldn't mind taking a look at it.

This is the code in "BaseCharacter" scene (I left out targeting related codes that have nothing to do with the animation or the character movement (at the moment)):

extends KinematicBody

var projectile = preload("res://Assets/Weapons/Projectiles/Projectile.tscn")
var calibrationProjectile = preload("res://Assets/Weapons/Projectiles/Projectile.tscn")
var calibrationProjectile2 = preload("res://Assets/Weapons/Projectiles/Projectile.tscn")
var calibrationProjectile3 = preload("res://Assets/Weapons/Projectiles/Projectile.tscn")
var rng = RandomNumberGenerator.new()


#Environmental Parameters
onready var gravitationalAcceleration = get_parent().gravitationalAcceleration
onready var gravitationalDirection = get_parent().gravitationalDirection
onready var terminalFreeFallVelocity
onready var terrainDetect = $TerrainDetect
onready var vectorUp = self.translation - 1*gravitationalDirection

#Physics Variables
onready var velocity = Vector3.ZERO
onready var oldPosition = Vector3.ZERO
onready var newPosition = Vector3.ZERO
onready var actualVelocity = Vector3.ZERO

#Movement Variables
onready var moveDirection = Vector3.ZERO

onready var moveInputVector = Vector3.ZERO
onready var jumpInput = false
onready var triggerDown = false


#Character Parameters
var strength = 0.0
var agility = 0.0
var bodyweight = 0.0
var jumpHeight = 0.0
var hitPoint = 0.0

#Secondary Physics Variables
onready var maxMovementSpeed = 0.0
onready var terminalVelocity = 100.0
onready var movementAcceleration = 0.0

#Components
onready var arm = $Arm
onready var armElevator = $Arm/ArmElevator
onready var armRotationReference = $Arm/ArmRotationReference
onready var targetPoint = $TargetPoint
onready var muzzle = $Arm/ArmElevator/Weapon/Muzzle
onready var pointer = $Arm/ArmElevator/Pointer
onready var animationPlayer = $CharacterGraphic/AnimationPlayer
onready var animationTree = $AnimationTree
onready var currentWeapon = $Arm/ArmElevator/Weapon


onready var ghostArm = $GhostArm
onready var ghostArmElevator = $GhostArm/GhostArmElevator
onready var ghostArmRotationReference = $GhostArm/GhostArmRotationReference
onready var ghostWeapon = $GhostArm/GhostArmElevator/GhostWeapon
onready var ghostWeaponMuzzle = $GhostArm/GhostArmElevator/GhostWeapon/GhostWeaponMuzzle


onready var timeElapsed = 0.0
onready var currentCooldown = 0.0
onready var muzzleVelocity = 300.0
onready var rateOfFire = 600 #Per minute
onready var calibrateFrequency = 10 #Per second
onready var calibrateCooldown = 0.0
onready var currentCalibrateCooldown = 0.0
onready var projectileExpiration = 10.0
onready var cooldown1 = 0.0
onready var targetLocation = Vector3.ZERO
onready var calibrationVector = Vector3.ZERO
onready var lastMuzzlePointLocation = Vector3.ZERO
onready var muzzlePointVelocity = Vector3.ZERO

onready var ghostArmCurrentAngle = 0.0
onready var ghostArmNewVAngle = 0.0
onready var ghostArmElevatorCurrentAngle = 0.0
onready var ghostArmElevatorNewAngle = 0.0
onready var oldCalibrationMarker = Vector3.UP
onready var newCalibrationMarker = Vector3.DOWN
onready var calibrationMarkerChange = Vector3.ZERO
onready var ghostArmAdjustment = 0.0
onready var ghostArmElevatorAdjustment = 0.0
onready var calibrationCounter = 0
onready var calibrationPeriod = 3
onready var lastFlatVector = Vector2.ZERO
onready var lastSliceVector = Vector2.ZERO
onready var oldCalibrationDistance = 0.0
onready var newCalibrationDistance = 0.0
onready var ghostTargetAgreement = false
onready var sprintInput = false
onready var groundMovementVector = Vector2.ZERO
onready var SprintingMultiplier = 5
onready var maxSprintSpeed = 0
onready var maxWalkingSpeed = 0

var damageQueue = {}


var gravitationalAccelerationValue = 9.81
var gravitationalAccelerationDirection = Vector3.DOWN

enum {
    PROJECTILE,
    CALIBRATE
}
enum {
    DIRECTFIRE,
    INDIRECTFIRE
}
enum {
    SOLUTION1,
    SOLUTION2
}

# Called when the node enters the scene tree for the first time.
func _ready():
    strength = 100.0
    agility = 10.0
    bodyweight = 60.0
    hitPoint = 100.0
    movementAcceleration = strength*agility/200/bodyweight
    maxWalkingSpeed = agility/5
    maxSprintSpeed = maxWalkingSpeed*SprintingMultiplier

    jumpHeight = movementAcceleration*10


    #Weapon Cooldown Setup
    cooldown1 = 60.0/rateOfFire
    calibrateCooldown = 1.0/calibrateFrequency
    pass # Replace with function body.

    #Ghost weapon alignment
    ghostArm.translation = arm.translation
    ghostArm.transform = arm.transform
    ghostArmElevator.translation = armElevator.translation
    ghostArmElevator.transform = armElevator.transform
    ghostWeapon.translation = currentWeapon.translation
    ghostWeapon.transform = currentWeapon.transform
    ghostWeaponMuzzle.translation = muzzle.translation
    ghostWeaponMuzzle.transform = muzzle.transform
    animationTree.active = true
    #animationTree.set("parameters/BlendSpace2D/blend_position",Vector2(1,0.5))

    pass # Replace with function body.

func _physics_process(delta):


    #Actions
    ordersToActions()

    #Movement actions

    #animationPlayer.play("WalkForward")
    #if moveDirection != Vector3.ZERO:
    #   animationPlayer.play("WalkForward")
    #else:
    #   animationPlayer.play("Idle")

    velocity.y = move_toward(velocity.y,-1*terminalVelocity,delta*gravitationalAcceleration)

    maxMovementSpeed = maxWalkingSpeed
    if sprintInput:
        maxMovementSpeed = maxSprintSpeed

    maxMovementSpeed
    if is_on_floor():
        velocity.x = move_toward(velocity.x,maxMovementSpeed*moveDirection.x,movementAcceleration)
        velocity.z = move_toward(velocity.z,maxMovementSpeed*moveDirection.z,movementAcceleration)
        var currentSpeed = velocity.length()
        var max1Speed = currentSpeed/maxMovementSpeed

        animationTree.set("parameters/BlendSpace2D/blend_position",Vector2(moveDirection.x,moveDirection.z))
        print(animationTree.get("parameters/BlendSpace2D/blend_position"))

        if jumpInput:
            velocity.y = velocity.y + jumpHeight



    velocity = move_and_slide(velocity,vectorUp)


func ordersToActions():
    inputGetter()

    moveDirection = moveInputVector






func inputGetter():
    #moveInputVector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
    #moveInputVector.z = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
    #jumpInput = Input.is_action_just_pressed("jump")

    #moveInputVector = moveInputVector.normalized()
    #triggerDown = Input.is_action_pressed("LeftClick")
    pass

And there is a singleton running:

extends Node


# Declare member variables here. Examples:
# var a = 2
# var b = "text"
onready var moveInputVector = Vector3.ZERO
onready var jumpInput = false
onready var triggerDown = false
onready var currentMainScene
onready var sprintInput
var playerCharacter


# Called when the node enters the scene tree for the first time.
func _ready():
    pass # Replace with function body.
    currentMainScene = $root/TestField

func _physics_process(delta):


    inputGetter()


func inputGetter():



    moveInputVector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
    moveInputVector.z = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
    jumpInput = Input.is_action_just_pressed("jump")
    sprintInput = Input.is_action_pressed("sprint")

    playerCharacter.moveInputVector = moveInputVector.normalized()
    playerCharacter.jumpInput = jumpInput
    playerCharacter.triggerDown = Input.is_action_pressed("LeftClick")
    playerCharacter.sprintInput = sprintInput

    moveInputVector = moveInputVector.normalized()

# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#   pass

The "BaseCharacter" scene is instanced into the main scene "TestField" with the following code:

extends Spatial

var player = preload("res://Characters/BaseCharacter.tscn")
export var gravitationalAcceleration = 9.81
export var gravitationalDirection = Vector3.DOWN
# Declare member variables here. Examples:
# var a = 2
# var b = "text"

onready var camera = $WorldCamera
onready var playerTargetingRayCast = $PlayerTargetingRayCast
onready var characterTargetingRayCast = $CharacterTargetingRayCast
onready var baseCharacter = $BaseCharacter
onready var targetPoint = Vector3.ZERO
onready var targetHeight = 1
onready var playerControllerSingleton = get_node("/root/PlayerController")

var playerTargetingRayOrigin = Vector3.ZERO
var playerTargetingRayEnd = Vector3.ZERO
var characterTargetingRayOrigin = Vector3.ZERO
var characterTargetingRayEnd = Vector3.ZERO

var characterInstance

# UI elements
onready var cursorGroundMarker = $CursorGroundMarker


func _ready():

    characterInstance = player.instance()
    characterInstance.translation = Vector3.UP*2

    playerControllerSingleton.playerCharacter = characterInstance
    add_child(characterInstance)

    pass # Replace with function body.


func _physics_process(delta):
    var space_state = get_world().direct_space_state
    var mouse_position = get_viewport().get_mouse_position()
    playerTargetingRayOrigin = camera.project_ray_origin(mouse_position)
    playerTargetingRayEnd = playerTargetingRayOrigin + camera.project_ray_normal(mouse_position) *400000



    playerTargetingRayCast.translation = playerTargetingRayOrigin
    playerTargetingRayCast.cast_to = playerTargetingRayEnd


    if playerTargetingRayCast.is_colliding():
        cursorGroundMarker.translation = playerTargetingRayCast.get_collision_point()+Vector3.UP*0
        targetPoint = playerTargetingRayCast.get_collision_point() - gravitationalDirection*targetHeight




    characterTargetingRayOrigin = characterInstance.translation
    characterTargetingRayEnd = targetPoint - characterTargetingRayOrigin
    characterTargetingRayCast.translation = characterTargetingRayOrigin
    characterTargetingRayCast.cast_to = characterTargetingRayEnd

    characterInstance.targetPoint.translation =  targetPoint

The two scenes set up:
TestField setup

BaseCharacter setup

Animation Tree Player Setup
AnimationTreeSetup
BlendSpace2D

Just to make it easier, this is a sample of the printout of the movedirection vector (it is a normalized 2D vector of keyboard direction input):
(0, -1)
(0, -1)
(0, -1)
(0, -1)
(0, -1)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-1, 0)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(-0.707107, 0.707107)
(0, 1)
(0, 1)
(0, 1)
(0, 1)
(0, 1)
(0, 0)

As I have previously said, the video demonstrates the character does seem to switch to different animations, just not playing them. As mentioned, the animations do play when played using AnimationPlayer methods, just not with AnimationTree Player.

Let me know if you would like any additional detail or if the images are not displaying properly.

One drive share folder containing the images and the video preview:
https://1drv.ms/u/s!AotdvshH6vn6gdV565eoaFPTWFDKIQ?e=VEXixV

One Drive video preview appears to support better resolution, so please check it out if you don't mind, thank you.

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.