we just chat


using Godot;

public partial class RtsPlayerNEW : CharacterBody3D
{
	private const float LERP_VALUE = 0.15f; // Smoothing rotation speed

	// Movement properties
	[Export] public float WalkSpeed = 1.0f;  // Speed for walking
	[Export] public float RunSpeed = 2.0f;  // Speed for running
	[Export] public float GravityForce = 50.0f;  // Gravity strength

	// Player states
	public bool IsIdle { get; private set; } = true;  // Is the player idle
	public bool IsWalking { get; private set; } = false;  // Is the player walking
	public bool IsRunning { get; private set; } = false;  // Is the player running
	public bool IsGrounded { get; private set; } = true;  // Is the player grounded

	// Player movement and navigation
	private bool _isMoving = false; // Tracks whether the player is navigating
	private bool _isRunning = false; // Toggles between walking and running
	private float _currentSpeed; // Current movement speed

	// Cached child nodes
	private NavigationAgent3D _navigationAgent;
	private Node3D _playerMesh;
	private AnimationTree _animationTree; // Integrated AnimationTree logic

	public override void _Ready()
	{
		// Cache nodes
		_navigationAgent = GetNode<NavigationAgent3D>("NavigationAgent3D");
		_playerMesh = GetNode<Node3D>("Mesh");
		_animationTree = GetNode<AnimationTree>("AnimationTree"); // AnimationTree directly under RTSPlayer

		// Activate AnimationTree
		if (_animationTree != null)
		{
			_animationTree.Active = true;
			GD.Print("AnimationTree initialized and active!");
		}
		else
		{
			GD.PrintErr("AnimationTree node not found! Ensure it's correctly set up in the scene.");
		}

		_currentSpeed = WalkSpeed; // Initialize movement speed
		GD.Print("RtsPlayerNEW initialized and ready with animation handling!");
	}

	public override void _PhysicsProcess(double delta)
	{
		Vector3 velocity = Velocity; // Copy the current velocity

		// Apply gravity when player is not on the ground
		if (!IsOnFloor())
		{
			velocity.Y -= GravityForce * (float)delta;
			IsGrounded = false;
		}
		else
		{
			velocity.Y = 0; // Reset vertical movement when grounded
			IsGrounded = true;
		}

		// Process movement
		if (_isMoving)
		{
			MoveAlongPath(ref velocity);
		}
		else
		{
			velocity.X = 0;
			velocity.Z = 0; // Stop horizontal movement if not navigating
		}

		// Assign new velocity
		Velocity = velocity;

		// Apply the calculated movement and resolve collisions
		MoveAndSlide();

		// Update player states and play corresponding animations
		UpdateAnimations(IsGrounded, !_isMoving, _isMoving && !_isRunning, _isMoving && _isRunning);
	}

	public void MoveTo(Vector3 targetPosition)
	{
		// Set the target position for navigation
		_navigationAgent.TargetPosition = targetPosition;

		// Ensure the target is reachable
		if (!_navigationAgent.IsTargetReachable())
		{
			GD.PrintErr($"Target position {targetPosition} is unreachable! Check the navigation mesh or target validity.");
			return;
		}

		_isMoving = true; // Start moving
		GD.Print($"Navigating to target: {targetPosition}");
	}

	private void MoveAlongPath(ref Vector3 velocity)
	{
		// Stop movement if navigation is completed
		if (_navigationAgent.IsNavigationFinished())
		{
			_isMoving = false;
			GD.Print("Player reached the destination.");
			return;
		}

		// Get the next path point from the navigation agent
		Vector3 nextPathPoint = _navigationAgent.GetNextPathPosition();
		Vector3 moveDirection = (nextPathPoint - GlobalTransform.Origin).Normalized();

		// Update velocity for horizontal movement
		velocity.X = moveDirection.X * _currentSpeed;
		velocity.Z = moveDirection.Z * _currentSpeed;

		// Rotate the player smoothly to face movement direction
		Vector3 targetRotation = Basis.LookingAt(moveDirection, Vector3.Up).GetEuler();
		_playerMesh.RotationDegrees = new Vector3(
			_playerMesh.RotationDegrees.X,
			Mathf.LerpAngle(_playerMesh.RotationDegrees.Y, Mathf.RadToDeg(targetRotation.Y), LERP_VALUE),
			_playerMesh.RotationDegrees.Z
		);

		GD.Print($"Moving to {nextPathPoint}, Velocity: {velocity}");
	}

	private void UpdateAnimations(bool isGrounded, bool isIdle, bool isWalking, bool isRunning)
	{
		if (_animationTree == null)
		{
			GD.PrintErr("AnimationTree reference is null. Unable to update animations.");
			return;
		}

		// Update grounded/airborne state in AnimationTree
		_animationTree.Set("parameters/Transition/grounded", isGrounded);

		// Update BlendTree states based on movement
		if (isGrounded)
		{
			if (isIdle)
			{
				_animationTree.Set("parameters/BlendTree/blend_position", -1.0f); // Idle
				GD.Print("Idle animation playing");
			}
			else if (isWalking)
			{
				_animationTree.Set("parameters/BlendTree/blend_position", 0.0f); // Walk
				GD.Print("Walking animation playing");
			}
			else if (isRunning)
			{
				_animationTree.Set("parameters/BlendTree/blend_position", 1.0f); // Run
				GD.Print("Running animation playing");
			}
		}
		else
		{
			// Play Air (fall/jump) animation if airborne
			GD.Print("Airborne animation playing");
		}
	}

	public override void _Input(InputEvent @event)
	{
		// Handle right-click for setting navigation targets
		if (@event is InputEventMouseButton mouseEvent && mouseEvent.Pressed && mouseEvent.ButtonIndex == MouseButton.Right)
		{
			Vector3 targetPosition = GetClickedWorldPosition(mouseEvent.Position);
			MoveTo(targetPosition); // Set navigation target
		}
	}

	private Vector3 GetClickedWorldPosition(Vector2 screenPosition)
	{
		// Calculate the world position of a mouse click using raycast
		Camera3D camera = GetViewport().GetCamera3D();
		Vector3 rayOrigin = camera.ProjectRayOrigin(screenPosition);
		Vector3 rayDirection = camera.ProjectRayNormal(screenPosition);
		Vector3 rayEnd = rayOrigin + rayDirection * 1000;

		// Perform raycast to detect where the mouse clicked
		var spaceState = GetViewport().GetWorld3D().DirectSpaceState;
		var query = PhysicsRayQueryParameters3D.Create(rayOrigin, rayEnd);
		var result = spaceState.IntersectRay(query);

		if (result.Count > 0 && result.TryGetValue("position", out var position))
		{
			return (Vector3)position;
		}

		GD.PrintErr("Mouse click did not hit a walkable surface.");
		return rayEnd; // Default to ray end if no valid surface
	}
}


this is script

so my player is facing backwards direction when he move , also when he move hes playing idle animation wlays, but he must play walk animation

its godot 4.3 

if you need more info to made it work just ask, i mean like hows scene looks and other stuff