Mapping and shadows

This commit is contained in:
Marco 2025-06-11 17:30:53 +02:00
commit 8ab7735d17
21 changed files with 2003 additions and 210 deletions

View file

@ -0,0 +1,76 @@
using Godot;
namespace Cirno.Scripts.Components.FSM._3DPlayer;
public partial class ShadowModule : ModuleBase<PlayerState, CharacterBody3D>
{
[Export] public NodePath ShadowPath;
[Export] public float MaxShadowScale = 1.2f;
[Export] public float MinShadowScale = 0.5f;
[Export] public float MaxShadowHeight = 5f;
private IStateMachine<PlayerState, CharacterBody3D> _machine;
private CharacterBody3D MainObject => _machine.MainObject;
[Export] public Node3D Shadow { get; private set; }
[Export(PropertyHint.Layers3DPhysics)] public uint CollisionMask { get; set; }
public override void EnterState(PlayerState state)
{
}
public override void ExitState(PlayerState state)
{
}
public override void Init(IStateMachine<PlayerState, CharacterBody3D> machine)
{
_machine = machine;
}
public override void Process(double delta)
{
}
public override void PhysicsProcess(double delta)
{
if (Shadow == null) return;
// Raycast down to get ground height
Vector3 origin = MainObject.GlobalTransform.Origin;
Vector3 from = origin + Vector3.Up * 0.5f;
Vector3 to = origin + Vector3.Down * 20f;
var spaceState = MainObject.GetWorld3D().DirectSpaceState;
var result = spaceState.IntersectRay(new PhysicsRayQueryParameters3D
{
From = from,
To = to,
CollideWithBodies = true,
CollisionMask = CollisionMask,
Exclude = [MainObject.GetRid()]
});
if (result.Count > 0)
{
Vector3 groundPos = (Vector3)result["position"];
float height = origin.Y - groundPos.Y;
// Clamp and scale
float t = Mathf.Clamp(height / MaxShadowHeight, 0f, 1f);
float scale = Mathf.Lerp(MaxShadowScale, MinShadowScale, t);
Shadow.GlobalPosition = new Vector3(origin.X, groundPos.Y + 0.01f, origin.Z);
Shadow.Scale = new Vector3(scale, 1f, scale);
}
else
{
Shadow.Visible = false;
}
}
}

View file

@ -0,0 +1 @@
uid://c8ar11sg0su2h