using System.Diagnostics; using Godot; namespace Babushka.scripts.CSharp.Common.CharacterControls; public partial class Player3D : CharacterBody3D { [Export] private float _speed = 1.0f; [Export] private Camera3D _camera; /// /// The sprite arrays are all setup like this: /// 0 - idle /// 1 - walking /// [Export] private AnimatedSprite3D[] _frontSpritesAnimated; [Export] private AnimatedSprite3D[] _sideSpritesAnimated; [Export] private AnimatedSprite3D[] _backSpritesAnimated; private bool _sideFlipped; private Vector2 _lastDirection; public override void _PhysicsProcess(double delta) { var inputDir = Input.GetVector("move_left", "move_right", "move_down", "move_up"); if (inputDir == Vector2.Zero) { if(_lastDirection != Vector2.Zero) SwitchIdleSprites(); return; } MoveOnInput(inputDir, delta); SwitchMovementSprites(inputDir); } private void MoveOnInput(Vector2 inputDir, double delta) { var direction = (Transform.Basis * new Vector3(inputDir.X, 0, inputDir.Y * (-1))).Normalized(); if (direction != Vector3.Zero) Velocity = new Vector3(direction.X * _speed * (float) delta * Scale.X, Velocity.Y, direction.Z * _speed * (float) delta * Scale.Z); else Velocity = Velocity.MoveToward(new Vector3(0, 0, 0), _speed); MoveAndSlide(); } private void SwitchIdleSprites() { if (_lastDirection.X != 0) { ActivateSprite(0, false, true, false); return; } if(_lastDirection.Y <= 0.0f) ActivateSprite(0, true, false, false); if(_lastDirection.Y > 0.0f) ActivateSprite(0, false, false, true); _lastDirection = Vector2.Zero; } private void SwitchMovementSprites(Vector2 inputDir) { float X = inputDir.X; float Y = inputDir.Y; _lastDirection = new Vector2(X, Y); if (X != 0) { ActivateSprite(1, false, true, false); if (X > 0.0f) { _sideFlipped = false; } if (X < 0.0f) { _sideFlipped = true; } foreach (var animatedSprite in _sideSpritesAnimated) { animatedSprite.FlipH = _sideFlipped; } return; } if (Y != 0) { if (Y > 0.0f) { ActivateSprite(1, false, false, true); } if (Y < 0.0f) { ActivateSprite(1, true, false, false); } } } private void ActivateSprite(int index, bool frontActive, bool sideActive, bool backActive) { DeactivateAll(); _frontSpritesAnimated[index].Visible = frontActive; _sideSpritesAnimated[index].Visible = sideActive; _backSpritesAnimated[index].Visible = backActive; } private void DeactivateAll() { foreach (var animatedSprite in _frontSpritesAnimated) { animatedSprite.Visible = false; } foreach (var animatedSprite in _sideSpritesAnimated) { animatedSprite.Visible = false; } foreach (var animatedSprite in _backSpritesAnimated) { animatedSprite.Visible = false; } } }