57 lines
2.4 KiB
C#
57 lines
2.4 KiB
C#
using Godot;
|
|
|
|
public partial class PhysicsSpike : Node3D
|
|
{
|
|
private RigidBody3D _ball;
|
|
private RigidBody3D _chaser;
|
|
private Node3D _chaseTarget;
|
|
private float _elapsed;
|
|
private bool _ballTouched;
|
|
|
|
public override void _Ready()
|
|
{
|
|
StaticBody3D floor = new() { Position = new Vector3(0, -0.5f, 0) };
|
|
floor.AddChild(new CollisionShape3D { Shape = new BoxShape3D { Size = new Vector3(20, 1, 20) } });
|
|
AddChild(floor);
|
|
|
|
_ball = new RigidBody3D { Position = new Vector3(0, 2, 0), ContactMonitor = true, MaxContactsReported = 4 };
|
|
_ball.AddChild(new CollisionShape3D { Shape = new SphereShape3D { Radius = 0.25f } });
|
|
_ball.BodyEntered += _ => _ballTouched = true;
|
|
AddChild(_ball);
|
|
|
|
StaticBody3D wall = new() { Position = new Vector3(5, 2, 0) };
|
|
wall.AddChild(new CollisionShape3D { Shape = new BoxShape3D { Size = new Vector3(0.5f, 4, 4) } });
|
|
AddChild(wall);
|
|
|
|
_chaser = new RigidBody3D { Position = new Vector3(0, 1, 0), GravityScale = 0f };
|
|
_chaser.AddChild(new CollisionShape3D { Shape = new SphereShape3D { Radius = 0.25f } });
|
|
AddChild(_chaser);
|
|
|
|
_chaseTarget = new Node3D();
|
|
AddChild(_chaseTarget);
|
|
GD.Print("SPIKE: physics spike scene ready");
|
|
}
|
|
|
|
public override void _PhysicsProcess(double delta)
|
|
{
|
|
_elapsed += (float)delta;
|
|
|
|
_chaseTarget.GlobalPosition = new Vector3(Mathf.Min(8f, _elapsed * 2f), 1, 0);
|
|
Vector3 to = _chaseTarget.GlobalPosition - _chaser.GlobalPosition;
|
|
Vector3 desired = to / (float)delta;
|
|
if (desired.Length() > 3f)
|
|
desired = desired.Normalized() * 3f;
|
|
_chaser.LinearVelocity = desired;
|
|
|
|
if (_elapsed < 2.5f)
|
|
return;
|
|
|
|
bool dropOk = _ballTouched && _ball.GlobalPosition.Y > 0.2f && _ball.GlobalPosition.Y < 0.35f;
|
|
bool chaseOk = _chaser.GlobalPosition.X > 4.4f && _chaser.GlobalPosition.X < 5.05f;
|
|
GD.Print($"SPIKE: drop test — ball y={_ball.GlobalPosition.Y:F3} (expected ~0.25), contact={_ballTouched} → {(dropOk ? "PASS" : "FAIL")}");
|
|
GD.Print($"SPIKE: chase test — chaser x={_chaser.GlobalPosition.X:F3} (wall face 4.75, body radius 0.25), vel={_chaser.LinearVelocity.Length():F2} → {(chaseOk ? "PASS" : "FAIL")}");
|
|
GD.Print($"SPIKE: overall {(dropOk && chaseOk ? "PASS — Box3D functional from C#" : "CHECK — behavior differs, inspect above")}");
|
|
GetTree().Quit();
|
|
}
|
|
}
|