mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
Player movement and camera
This commit is contained in:
parent
ed656f00bb
commit
a324f2e347
43 changed files with 1777 additions and 316 deletions
|
|
@ -16,24 +16,29 @@ public partial class CreateEmitterPattern : AttackPattern
|
|||
|
||||
[Export] public double LifeTime { get; set; } = 10d;
|
||||
|
||||
public override IPatternMachine MakeMachine(Node2D parent)
|
||||
public override IPatternMachine MakeMachine(Node parent)
|
||||
{
|
||||
return new EmitterPatternMachine(this, parent);
|
||||
}
|
||||
|
||||
public class EmitterPatternMachine(CreateEmitterPattern pattern, Node2D parent) : IPatternMachine
|
||||
public class EmitterPatternMachine(CreateEmitterPattern pattern, Node parent) : IPatternMachine
|
||||
{
|
||||
private bool _active = false;
|
||||
public Node2D Parent => parent;
|
||||
public Node Parent => parent;
|
||||
public AutonomousBulletEmitter Emitter { get; private set; }
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (parent is not Node2D parent2d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Emitter = pattern.CreateAsChild
|
||||
? parent.CreateChild<AutonomousBulletEmitter>(pattern.Prefab,
|
||||
parent.GlobalPosition + pattern.SpawnOffset)
|
||||
: parent.CreateSibling<AutonomousBulletEmitter>(pattern.Prefab,
|
||||
parent.GlobalPosition + pattern.SpawnOffset);
|
||||
? parent2d.CreateChild<AutonomousBulletEmitter>(pattern.Prefab,
|
||||
parent2d.GlobalPosition + pattern.SpawnOffset)
|
||||
: parent2d.CreateSibling<AutonomousBulletEmitter>(pattern.Prefab,
|
||||
parent2d.GlobalPosition + pattern.SpawnOffset);
|
||||
Emitter.Script = pattern.Script;
|
||||
Emitter.EmitOnStart = true;
|
||||
Emitter.LifeTime = pattern.LifeTime;
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ public partial class MovementPattern : AttackPattern
|
|||
[Export] public Tween.EaseType easeType = Tween.EaseType.InOut;
|
||||
[Export] public AttackPattern shootingPattern;
|
||||
|
||||
public override IPatternMachine MakeMachine(Node2D parent)
|
||||
public override IPatternMachine MakeMachine(Node parent)
|
||||
{
|
||||
return new MovementPatternMachine(this, parent);
|
||||
}
|
||||
|
||||
public class MovementPatternMachine(MovementPattern pattern, Node2D parent) : IPatternMachine
|
||||
public class MovementPatternMachine(MovementPattern pattern, Node parent) : IPatternMachine
|
||||
{
|
||||
public Node2D Parent => parent;
|
||||
public Node Parent => parent;
|
||||
public MovementPattern Pattern { get; } = pattern;
|
||||
|
||||
private IPatternMachine _machine;
|
||||
|
|
@ -39,10 +39,11 @@ public partial class MovementPattern : AttackPattern
|
|||
Boss = boss;
|
||||
tween = parent.CreateTween();
|
||||
isComplete = false;
|
||||
|
||||
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? boss.ParentObject.GlobalPosition) + Pattern.relativeTargetPosition;
|
||||
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? parent.GlobalPosition) + Pattern.relativeTargetPosition;
|
||||
|
||||
tween.TweenProperty(Parent, "position", targetPosition, Pattern.moveDuration)
|
||||
tween.TweenProperty(boss.ParentObject, "position", targetPosition, Pattern.moveDuration)
|
||||
.SetTrans(Pattern.transitionType)
|
||||
.SetEase(Pattern.easeType)
|
||||
.Finished += () => isComplete = true;
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ public partial class NodeMovementPattern : AttackPattern
|
|||
// [Export] private Tween.TransitionType transitionType = Tween.TransitionType.Linear;
|
||||
[Export] public GTweens.Easings.Easing EaseType { get; private set; } = Easing.Linear;
|
||||
|
||||
public override IPatternMachine MakeMachine(Node2D parent)
|
||||
public override IPatternMachine MakeMachine(Node parent)
|
||||
{
|
||||
return new NodeMovementPatternMachine(this, parent);
|
||||
}
|
||||
|
||||
public class NodeMovementPatternMachine(NodeMovementPattern pattern, Node2D parent) : IPatternMachine
|
||||
public class NodeMovementPatternMachine(NodeMovementPattern pattern, Node parent) : IPatternMachine
|
||||
{
|
||||
public Node2D Parent => parent;
|
||||
public Node Parent => parent;
|
||||
|
||||
private GTween _tween;
|
||||
private bool isComplete = false;
|
||||
|
|
@ -37,11 +37,12 @@ public partial class NodeMovementPattern : AttackPattern
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
_tween?.Complete();
|
||||
|
||||
isComplete = false;
|
||||
|
||||
Vector2 targetPosition = (scriptHost?.HomePosition ?? Parent.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
Vector2 targetPosition = (scriptHost?.HomePosition ?? scriptHost.ParentObject.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
|
||||
_tween = GTweenSequenceBuilder.New()
|
||||
.Append(scriptHost.ParentObject.TweenGlobalPosition(targetPosition, pattern.moveDuration))
|
||||
|
|
|
|||
|
|
@ -112,14 +112,15 @@ public partial class SpiralPattern : AttackPattern
|
|||
// };
|
||||
}
|
||||
|
||||
public override IPatternMachine MakeMachine(Node2D parent)
|
||||
public override IPatternMachine MakeMachine(Node parent)
|
||||
{
|
||||
return new SpiralPatternMachine(this, parent);
|
||||
}
|
||||
|
||||
public class SpiralPatternMachine(SpiralPattern pattern, Node2D parent) : IPatternMachine
|
||||
public class SpiralPatternMachine(SpiralPattern pattern, Node parent) : IPatternMachine
|
||||
{
|
||||
public Node2D Parent => parent;
|
||||
public Node Parent => parent;
|
||||
public IScriptHost ScriptHost { get; private set; }
|
||||
private double timer;
|
||||
private double burstTimer;
|
||||
//private double _burstRateTimer;
|
||||
|
|
@ -131,6 +132,8 @@ public partial class SpiralPattern : AttackPattern
|
|||
|
||||
public void Start()
|
||||
{
|
||||
ScriptHost = Parent as IScriptHost;
|
||||
|
||||
timer = 0;
|
||||
_burstBullets = pattern.ShotsPerBurst;
|
||||
burstTimer = pattern.burstInterval; // start immediately
|
||||
|
|
@ -231,21 +234,21 @@ public partial class SpiralPattern : AttackPattern
|
|||
{
|
||||
if (pattern._predictPlayer && GameManager.Instance.PlayerVelocity.HasValue)
|
||||
{
|
||||
var predictedDirection = MathFunctions.PredictInterceptPosition(Parent.GlobalPosition,
|
||||
var predictedDirection = MathFunctions.PredictInterceptPosition(ScriptHost.ParentObject.GlobalPosition,
|
||||
GameManager.Instance.PlayerPosition.Value, GameManager.Instance.PlayerVelocity.Value,
|
||||
pattern.BulletResource.BulletSpeed);
|
||||
if (predictedDirection.HasValue)
|
||||
{
|
||||
direction = (predictedDirection.Value - Parent.GlobalPosition).Normalized();
|
||||
direction = (predictedDirection.Value - ScriptHost.ParentObject.GlobalPosition).Normalized();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
direction = (GameManager.Instance.PlayerPosition.Value - Parent.GlobalPosition).Normalized();
|
||||
direction = (GameManager.Instance.PlayerPosition.Value - ScriptHost.ParentObject.GlobalPosition).Normalized();
|
||||
}
|
||||
}
|
||||
|
||||
var bullet = pattern.MakeBullet(Parent.GlobalPosition + pattern.EmitterOffset, pattern.bulletCount,
|
||||
var bullet = pattern.MakeBullet(ScriptHost.ParentObject.GlobalPosition + pattern.EmitterOffset, pattern.bulletCount,
|
||||
pattern.spread, angleOffset);
|
||||
|
||||
bullet.Direction = direction;
|
||||
|
|
|
|||
|
|
@ -43,11 +43,17 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
||||
CallDeferred(MethodName.DelayedRegisterGameManager);
|
||||
}
|
||||
|
||||
private void DelayedRegisterGameManager()
|
||||
{
|
||||
if (GameManager.Instance is null)
|
||||
{
|
||||
GD.Print("No GameManager found for keyboard inputprovider");
|
||||
return;
|
||||
}
|
||||
GameManager.Instance.GameStateChange += InstanceOnGameStateChange;
|
||||
_enabled = true;
|
||||
}
|
||||
|
|
@ -107,9 +113,11 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
//if (camera == null) return Vector2.Zero; // Ensure there's a valid camera
|
||||
|
||||
//Vector2 mouseScreenPos = GetViewport().get_local_mouse_position();
|
||||
Vector2 mouseWorldPos = this.GetGlobalMousePosition();
|
||||
if (GameManager.Instance is null) return Vector2.Zero;
|
||||
|
||||
Vector2 mouseWorldPos = DisplayServer.MouseGetPosition();// GameManager.Instance.GetGlobalMousePosition();
|
||||
|
||||
return mouseWorldPos - this.GlobalPosition; // Get direction vector
|
||||
return mouseWorldPos - GameManager.Instance.PlayerPosition.Value; // Get direction vector
|
||||
}
|
||||
|
||||
public override bool GetActionJustPressed(string action)
|
||||
|
|
|
|||
|
|
@ -81,52 +81,7 @@ public partial class Active : BaseState<PlayerState, CharacterBody3D>
|
|||
{
|
||||
base.ProcessState(delta);
|
||||
|
||||
_movementDirection = _inputProvider.GetMovementInput().Normalized();
|
||||
_isStrafing = _inputProvider.GetStrafePressed();
|
||||
|
||||
// Toggle visibility of the hitbox sprite based on strafing
|
||||
_hitboxSpriteProvider.SetVisibility(_isStrafing);
|
||||
|
||||
var rightStickInput = _inputProvider.GetAimInput().Normalized();
|
||||
|
||||
// Update Facing Direction
|
||||
// if (!_isStrafing)
|
||||
// {
|
||||
if (rightStickInput.Length() > 0.1f) // If the right stick is moved
|
||||
{
|
||||
FacingDirection = rightStickInput;
|
||||
}
|
||||
else if (_movementDirection != Vector2.Zero) // Fall back to movement direction
|
||||
{
|
||||
FacingDirection = _movementDirection;
|
||||
}
|
||||
// }
|
||||
|
||||
_animationProvider.SetAnimationSpeed(MainObject.Velocity);
|
||||
_animationProvider.SetAnimation(FacingDirection);
|
||||
|
||||
HandleWeaponSwitch();
|
||||
_weaponProvider.Update(delta);
|
||||
|
||||
//_crosshairProvider.UpdatePosition(FacingDirection);
|
||||
|
||||
HandleShoot();
|
||||
|
||||
HandleInteraction();
|
||||
// FindInteractable();
|
||||
|
||||
// _crosshair.Position = CalculateCrosshairPosition();
|
||||
|
||||
if (_inputProvider.GetInventoryJustPressed())
|
||||
{
|
||||
GameManager.Instance.ChangeState(GameState.Inventory);
|
||||
}
|
||||
|
||||
if (_inputProvider.GetPauseJustPressed())
|
||||
{
|
||||
//CallDeferred(MethodName.PauseDeferred);
|
||||
PauseDeferred();
|
||||
}
|
||||
}
|
||||
|
||||
private void PauseDeferred()
|
||||
|
|
@ -134,32 +89,5 @@ public partial class Active : BaseState<PlayerState, CharacterBody3D>
|
|||
GameManager.Instance.Pause();
|
||||
}
|
||||
|
||||
// private void HandleShoot()
|
||||
// {
|
||||
// if (_inputProvider.GetReloadJustPressed())
|
||||
// {
|
||||
// _weaponProvider.Reload();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (!_inputProvider.GetShootPressed()) return;
|
||||
// _weaponProvider.Shoot(this.FacingDirection);
|
||||
// }
|
||||
//
|
||||
// private void HandleInteraction()
|
||||
// {
|
||||
// _activationProvider.HandleInteraction();
|
||||
// }
|
||||
//
|
||||
// private void HandleWeaponSwitch()
|
||||
// {
|
||||
// if (_inputProvider.GetWeaponNextJustPressed())
|
||||
// {
|
||||
// _weaponProvider.NextWeapon();
|
||||
// }
|
||||
// else if (_inputProvider.GetWeaponPreviousJustPressed())
|
||||
// {
|
||||
// _weaponProvider.PreviousWeapon();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -32,6 +32,6 @@ public partial class Init : BaseState<PlayerState, CharacterBody3D>
|
|||
private async Task AutoSwitchToStart()
|
||||
{
|
||||
await Task.Delay(500);
|
||||
//StateMachine.SetState(PlayerState.Active);
|
||||
StateMachine.SetState(PlayerState.Active);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
|
|||
[Export] public int StrafeSpeed { get; set; } = 35;
|
||||
[Export] public float Acceleration = 8f;
|
||||
[Export] public float Deceleration = 8f;
|
||||
[Export] public float Gravity = -9.8f;
|
||||
[Export] public float FallSpeed = 20f;
|
||||
|
||||
private bool _isStrafing;
|
||||
private float _accelerationPerSecond;
|
||||
|
|
@ -41,16 +43,38 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
|
|||
|
||||
public override void Process(double delta)
|
||||
{
|
||||
var movementInput = _inputProvider.GetMovementInput();
|
||||
|
||||
_isStrafing = _inputProvider.GetStrafePressed();
|
||||
var rightStickInput = _inputProvider.GetAimInput().Normalized();
|
||||
|
||||
// Update Facing Direction
|
||||
// if (!_isStrafing)
|
||||
// {
|
||||
if (rightStickInput.Length() > 0.1f) // If the right stick is moved
|
||||
{
|
||||
PlayerStorage.FacingDirection = rightStickInput;
|
||||
}
|
||||
else if (movementInput != Vector2.Zero) // Fall back to movement direction
|
||||
{
|
||||
PlayerStorage.FacingDirection = movementInput;
|
||||
}
|
||||
// }
|
||||
|
||||
var rotatedMovementDirection = movementInput.Rotated(Mathf.DegToRad(-45f));
|
||||
|
||||
PlayerStorage.MovementDirection = new Vector3(rotatedMovementDirection.X, 0, rotatedMovementDirection.Y);
|
||||
}
|
||||
|
||||
public override void PhysicsProcess(double delta)
|
||||
{
|
||||
|
||||
var frameVelocity = MainObject.Velocity;
|
||||
|
||||
if (_isStrafing)
|
||||
{
|
||||
// Instant movement at strafe speed
|
||||
MainObject.Velocity = PlayerStorage.MovementDirection * StrafeSpeed;
|
||||
frameVelocity = PlayerStorage.MovementDirection * StrafeSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -58,16 +82,22 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
|
|||
|
||||
if (PlayerStorage.MovementDirection != Vector3.Zero)
|
||||
{
|
||||
MainObject.Velocity = MainObject.Velocity.MoveToward(targetVelocity, Acceleration * (float)delta);
|
||||
frameVelocity = frameVelocity.MoveToward(targetVelocity, Acceleration * (float)delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainObject.Velocity = MainObject.Velocity.MoveToward(Vector3.Zero, Deceleration * (float)delta);
|
||||
frameVelocity = frameVelocity.MoveToward(Vector3.Zero, Deceleration * (float)delta);
|
||||
}
|
||||
}
|
||||
|
||||
//MainObject.Velocity += _movementDirection * MovementSpeed;
|
||||
|
||||
var velocityY = Mathf.Clamp(frameVelocity.Y + Gravity * (float)delta, -FallSpeed, FallSpeed);
|
||||
|
||||
frameVelocity.Y = velocityY;
|
||||
|
||||
MainObject.Velocity = frameVelocity;
|
||||
|
||||
MainObject.MoveAndSlide();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using Godot.Collections;
|
|||
|
||||
namespace Cirno.Scripts.Components.FSM;
|
||||
|
||||
public abstract partial class BaseState<TKey, TType> : Node2D, IState<TKey, TType>
|
||||
public abstract partial class BaseState<TKey, TType> : Node, IState<TKey, TType>
|
||||
where TKey : notnull
|
||||
where TType : Node
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public abstract partial class ElevatorMovementState : BaseState<ElevatorState, E
|
|||
private async Task MovePlayerToCenter()
|
||||
{
|
||||
var tween = GTweenSequenceBuilder.New()
|
||||
.Append(PlayerBody.TweenPosition(this.Position, 0.2f))
|
||||
.Append(PlayerBody.TweenPosition(MainObject.Position, 0.2f))
|
||||
.Build();
|
||||
|
||||
await tween.PlayAsync(CancellationToken.None);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public partial class Alert : EnemyStateBase
|
|||
}
|
||||
|
||||
// if player is outside disengage range, change to idle (later on, search)
|
||||
if (this.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) >=
|
||||
if (MainObject.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) >=
|
||||
StorageModule.Root.EnemyResource.PlayerDisengageRange)
|
||||
{
|
||||
StateMachine.SetState(EnemyState.Idle);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public partial class TurretAlert : EnemyStateBase
|
|||
}
|
||||
|
||||
// if player is outside disengage range, change to idle (later on, search)
|
||||
if (this.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) >=
|
||||
if (MainObject.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) >=
|
||||
StorageModule.Root.EnemyResource.PlayerDisengageRange)
|
||||
{
|
||||
|
||||
|
|
|
|||
121
Scripts/Misc/CameraController3D.cs
Normal file
121
Scripts/Misc/CameraController3D.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Misc;
|
||||
|
||||
public partial class CameraController3D : Camera3D
|
||||
{
|
||||
[Export] public bool EnableSmoothing = true;
|
||||
[Export] public bool FollowTargeting = true;
|
||||
|
||||
[Export] public float SmoothTime = 0.2f;
|
||||
[Export] public float MaxAimOffsetDistance = 2.0f;
|
||||
[Export] public float AimLerpSpeed = 8.0f;
|
||||
[Export] public float AimDeadzone = 0.2f;
|
||||
|
||||
[Export] public Vector3 CameraOffset = new Vector3(0, 12, -12); // Relative to target
|
||||
|
||||
[Export] public StringName AimUpName = "aim_up";
|
||||
[Export] public StringName AimDownName = "aim_down";
|
||||
[Export] public StringName AimLeftName = "aim_left";
|
||||
[Export] public StringName AimRightName = "aim_right";
|
||||
|
||||
[Export] public NodePath TargetPath;
|
||||
|
||||
private Node3D _target;
|
||||
private Vector3 _currentPosition = Vector3.Zero;
|
||||
private Vector3 _currentAimOffset = Vector3.Zero;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_target = GetNode<Node3D>(TargetPath);
|
||||
if (_target == null)
|
||||
{
|
||||
GD.PushError("Camera target not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
_currentPosition = GlobalPosition;
|
||||
|
||||
// Set fixed isometric angle once: -45° X tilt, 45° Y pan
|
||||
RotationDegrees = new Vector3(-45f, 45f, 0f);
|
||||
Projection = ProjectionType.Orthogonal;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (_target == null) return;
|
||||
|
||||
float dt = (float)delta;
|
||||
Vector3 targetPos = _target.GlobalTransform.Origin;
|
||||
|
||||
// Aim offset
|
||||
if (FollowTargeting)
|
||||
{
|
||||
Vector3 desiredOffset = GetAimOffsetWorldSpace();
|
||||
_currentAimOffset = _currentAimOffset.Lerp(desiredOffset, AimLerpSpeed * dt);
|
||||
|
||||
if (_currentAimOffset.Length() > MaxAimOffsetDistance)
|
||||
_currentAimOffset = _currentAimOffset.Normalized() * MaxAimOffsetDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentAimOffset = Vector3.Zero;
|
||||
}
|
||||
|
||||
// Final target position
|
||||
Vector3 targetWithOffset = targetPos + _currentAimOffset;
|
||||
Vector3 desiredCameraPos = targetWithOffset + CameraOffset;
|
||||
|
||||
if (EnableSmoothing)
|
||||
{
|
||||
float smoothingFactor = 1f - Mathf.Exp(-dt / SmoothTime);
|
||||
_currentPosition = _currentPosition.Lerp(desiredCameraPos, smoothingFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentPosition = desiredCameraPos;
|
||||
}
|
||||
|
||||
GlobalPosition = _currentPosition;
|
||||
// No LookAt or dynamic rotation — angle is fixed
|
||||
}
|
||||
|
||||
private Vector3 GetAimOffsetWorldSpace()
|
||||
{
|
||||
Vector2 stickDir = new Vector2(
|
||||
Input.GetActionStrength(AimRightName) - Input.GetActionStrength(AimLeftName),
|
||||
Input.GetActionStrength(AimDownName) - Input.GetActionStrength(AimUpName)
|
||||
);
|
||||
|
||||
float stickLen = stickDir.Length();
|
||||
if (stickLen > AimDeadzone)
|
||||
{
|
||||
float scaled = (stickLen - AimDeadzone) / (1f - AimDeadzone);
|
||||
Vector2 aimDir2D = stickDir.Normalized() * Mathf.Clamp(scaled, 0f, 1f);
|
||||
return new Vector3(aimDir2D.X, 0, aimDir2D.Y);
|
||||
}
|
||||
|
||||
// Mouse fallback
|
||||
Vector2 mousePos = GetViewport().GetMousePosition();
|
||||
Vector3 rayOrigin = ProjectRayOrigin(mousePos);
|
||||
Vector3 rayDir = ProjectRayNormal(mousePos) * 1000f;
|
||||
|
||||
var plane = new Plane(Vector3.Up, 0);
|
||||
var hit = plane.IntersectsRay(rayOrigin, rayDir);
|
||||
|
||||
if (hit is Vector3 hitPoint)
|
||||
{
|
||||
Vector3 offset = hitPoint - _target.GlobalTransform.Origin;
|
||||
offset.Y = 0;
|
||||
|
||||
float dist = offset.Length();
|
||||
if (dist > 0.01f)
|
||||
{
|
||||
float scaled = Mathf.Clamp((dist - AimDeadzone) / (10f - AimDeadzone), 0f, 1f);
|
||||
return offset.Normalized() * scaled;
|
||||
}
|
||||
}
|
||||
|
||||
return Vector3.Zero;
|
||||
}
|
||||
}
|
||||
1
Scripts/Misc/CameraController3D.cs.uid
Normal file
1
Scripts/Misc/CameraController3D.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ba0tf7ihw4hpp
|
||||
|
|
@ -36,10 +36,15 @@ public partial class FSMMovementPattern : AttackPattern
|
|||
tween = Parent.CreateTween();
|
||||
isComplete = false;
|
||||
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? Parent.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
if (parent is not Node2D parent2d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? parent2d.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
|
||||
boss.ChangeSpriteDirection(-(Parent.GlobalPosition - targetPosition));
|
||||
tween.TweenProperty(Parent, "global_position", targetPosition, pattern.moveDuration)
|
||||
boss.ChangeSpriteDirection(-(parent2d.GlobalPosition - targetPosition));
|
||||
tween.TweenProperty(parent2d, "global_position", targetPosition, pattern.moveDuration)
|
||||
.SetTrans(pattern.transitionType)
|
||||
.SetEase(pattern.easeType)
|
||||
.Finished += () =>
|
||||
|
|
|
|||
|
|
@ -35,11 +35,16 @@ public partial class SimpleMovementPattern : AttackPattern
|
|||
Boss = boss;
|
||||
tween = Parent.CreateTween();
|
||||
isComplete = false;
|
||||
|
||||
if (parent is not Node2D parent2d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? Parent.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
Vector2 targetPosition = (Boss?.HomePosition ?? parent2d.GlobalPosition) + pattern.relativeTargetPosition;
|
||||
|
||||
boss.ChangeSpriteDirection(-(Parent.GlobalPosition - targetPosition));
|
||||
tween.TweenProperty(Parent, "global_position", targetPosition, pattern.moveDuration)
|
||||
boss.ChangeSpriteDirection(-(parent2d.GlobalPosition - targetPosition));
|
||||
tween.TweenProperty(parent2d, "global_position", targetPosition, pattern.moveDuration)
|
||||
.SetTrans(pattern.transitionType)
|
||||
.SetEase(pattern.easeType)
|
||||
.Finished += () =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue