3D Bullet pattern fix

This commit is contained in:
Marco 2025-06-21 10:42:11 +02:00
commit a6c8544de8
5 changed files with 525 additions and 438 deletions

File diff suppressed because one or more lines are too long

View file

@ -23,7 +23,7 @@ class_properties = {}
class_property_descriptions = {}
auto_apply_to_matching_node_properties = false
meta_properties = {
"size": AABB(-32, -8, -16, 32, 16, 16),
"size": AABB(-32, -16, -16, 32, 16, 16),
"studio": "\"3D/MapModels/actor_tank_large.glb\""
}
node_class = ""

View file

@ -9,7 +9,7 @@
script = ExtResource("3_2rxa2")
BulletResource = ExtResource("1_bjips")
EmitterOffset = Vector3(0, 0, 0)
bulletCount = 2
bulletCount = 8
rotationSpeed = 60.0
_rotationOffset = 0.0
duration = 10.0

View file

@ -7,47 +7,62 @@ namespace Cirno.Scripts.Actors;
public partial class BulletSpawner3D : Node3D
{
[Export] public PackedScene BulletScene;
public void SpawnBullet(BulletInfo bulletInfo, Vector3 position)
{
var bulletScene = bulletInfo.BulletScene ?? BulletScene;
Bullet3D bullet;
int count = bulletInfo.BulletCount;
float spreadRadians = Mathf.DegToRad(bulletInfo.Spread);
float step = count > 1 ? spreadRadians / (count - 1) : 0;
// Choose base direction (defaults to +X)
Vector2 baseDirection = bulletInfo.Direction == Vector2.Zero
? Vector2.Right
: bulletInfo.Direction.Normalized();
float baseAngle = Mathf.Atan2(baseDirection.Y, baseDirection.X); // angle in radians
float offsetRadians = Mathf.DegToRad(bulletInfo.RotationOffset);
// Calculate per-bullet spread angle step
float spreadRadians = Mathf.DegToRad(bulletInfo.Spread);
// 👇 Configure this depending on desired pattern
bool isFullCircle = Mathf.Abs(bulletInfo.Spread - 360f) < 0.01f;
float angleStep = isFullCircle
? spreadRadians / count // Full circle: divide evenly across bullets
: count > 1
? spreadRadians / (count - 1) // Fan spread: divide across gaps
: 0f;
// Determine starting angle for bullet pattern
float startAngle = isFullCircle
? baseAngle + offsetRadians // Full circle starts at baseAngle + offset
: baseAngle + offsetRadians - (spreadRadians / 2.0f); // Fan starts centered
// Spawn bullets
for (int i = 0; i < count; i++)
{
bullet = PoolingManager.Instance.SpawnBullet<Bullet3D>(bulletInfo.OriginalBulletResource);
Bullet3D bullet = PoolingManager.Instance.SpawnBullet<Bullet3D>(bulletInfo.OriginalBulletResource);
bullet.GlobalPosition = position;
// Optionally apply modifiers (null-safe)
if (bulletInfo.Modifier is not null)
{
bulletInfo = bulletInfo.Modifier.ModifyBullet(bulletInfo, i, count);
}
bullet.Initialize(bulletInfo);
Vector2 baseDirection = bulletInfo.Direction == Vector2.Zero ? Vector2.Right : bulletInfo.Direction.Normalized();
float baseAngle = Mathf.Atan2(baseDirection.Y, baseDirection.X);
// Compute final angle for this bullet
float angle = startAngle + angleStep * i;
// Spread centered: offset from center
float offsetFromCenter = (i - (count - 1) / 2.0f) * step;
float angle = baseAngle + Mathf.DegToRad(bulletInfo.RotationOffset) + offsetFromCenter;
// Optional: Tiny jitter to avoid precision collapse
// angle += i * 0.0001f;
Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)).Normalized();
bullet.SetDirection(bulletDirection);
// float offsetRadians = Mathf.DegToRad(bulletInfo.RotationOffset);
// float spreadStep = Mathf.DegToRad(bulletInfo.Spread) / Mathf.Max(1, bulletInfo.BulletCount - 1); // Ensure proper spread spacing, also add 1 if 0
// float angle = baseAngle + offsetRadians + (spreadStep * i);
//
//
// Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
//
// bullet.SetDirection(bulletDirection);
// Optional: Debug offset to visualize all bullets
// bullet.GlobalPosition += new Vector3(i * 0.1f, 0, 0);
GD.Print($"Bullet {i}: Angle={Mathf.RadToDeg(angle)}, Direction={bulletDirection}");
}
}