mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
Mapping and models
This commit is contained in:
parent
bd7f04d6fe
commit
595444885d
21 changed files with 4674 additions and 843 deletions
89
Scripts/Components/Actors/ShadowProvider.cs
Normal file
89
Scripts/Components/Actors/ShadowProvider.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class ShadowProvider : Node3D
|
||||
{
|
||||
|
||||
[Export] public bool AutoEnable { get; private set; } = true;
|
||||
|
||||
public bool Enabled { get; private set; }
|
||||
|
||||
[Export] public float MaxShadowScale = 1.2f;
|
||||
[Export] public float MinShadowScale = 0.5f;
|
||||
[Export] public float MaxShadowHeight = 5f;
|
||||
|
||||
[Export(PropertyHint.Layers3DPhysics)] public uint CollisionMask { get; set; }
|
||||
|
||||
private Node3D _mainObject;
|
||||
|
||||
private Array<Rid> Exclusions = [];
|
||||
|
||||
public void Init(Node3D mainObject)
|
||||
{
|
||||
_mainObject = mainObject;
|
||||
if (_mainObject is CharacterBody3D body)
|
||||
{
|
||||
Exclusions.Add(body.GetRid());
|
||||
}
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (!AutoEnable) return;
|
||||
|
||||
Init(GetParentNode3D());
|
||||
Enable();
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (!Enabled || _mainObject is 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,
|
||||
CollideWithAreas = false,
|
||||
CollisionMask = CollisionMask,
|
||||
Exclude = Exclusions
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
this.GlobalPosition = new Vector3(origin.X, groundPos.Y + 0.01f, origin.Z);
|
||||
this.Scale = new Vector3(scale, scale, scale);
|
||||
this.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/Actors/ShadowProvider.cs.uid
Normal file
1
Scripts/Components/Actors/ShadowProvider.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dvln1783wvvuw
|
||||
|
|
@ -1,34 +1,31 @@
|
|||
using Godot;
|
||||
using Cirno.Scripts.Components.Actors;
|
||||
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;
|
||||
[Export] public ShadowProvider ShadowProvider { get; private set; }
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
ShadowProvider.Enable();
|
||||
}
|
||||
|
||||
public override void ExitState(PlayerState state)
|
||||
{
|
||||
|
||||
ShadowProvider.Disable();
|
||||
}
|
||||
|
||||
public override void Init(IStateMachine<PlayerState, CharacterBody3D> machine)
|
||||
{
|
||||
_machine = machine;
|
||||
|
||||
ShadowProvider.Init(MainObject);
|
||||
}
|
||||
|
||||
public override void Process(double delta)
|
||||
|
|
@ -38,39 +35,6 @@ public partial class ShadowModule : ModuleBase<PlayerState, CharacterBody3D>
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue