Files
factory-game/source/Scripts/Components/CollisionComponent.cs
2026-03-01 08:32:24 +03:00

76 lines
1.9 KiB
C#

using FactoryGame.Entities;
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class CollisionComponent : Area3D, IComponent {
public enum CollisionComponentMode {
Body,
BodyShape,
Area,
AreaShape
}
[Export]
public CollisionComponentMode Mode { get; set; } = CollisionComponentMode.Body;
[ExportGroup("White List")]
[Export]
public bool UseWhiteList { get; set; }
[Export]
public Node3D[]? WhiteList { get; set; }
[ExportGroup("Black List")]
[Export]
public bool UseBlackList { get; set; }
[Export]
public Node3D[]? BlackList { get; set; }
public IReadOnlyList<Node3D> Collisions => _collisions;
private List<Node3D> _collisions = new();
public override void _Ready() {
switch (Mode) {
case CollisionComponentMode.Body: {
BodyEntered += (body) => Enter(body);
BodyExited += (body) => Exit(body);
}
; break;
case CollisionComponentMode.BodyShape: {
BodyShapeEntered += (_, body, _, _) => Enter(body);
BodyShapeExited += (_, body, _, _) => Exit(body);
}
; break;
case CollisionComponentMode.Area: {
AreaEntered += Enter;
AreaEntered += Exit;
}
; break;
case CollisionComponentMode.AreaShape: {
AreaShapeEntered += (_, body, _, _) => Enter(body);
AreaShapeEntered += (_, body, _, _) => Exit(body);
}
; break;
}
base._Ready();
}
private void Enter(Node3D body) {
if (CheckBody(body))
_collisions.Add(body);
}
private void Exit(Node3D body) {
if (_collisions.Contains(body))
_collisions.Remove(body);
}
private bool CheckBody(Node3D body) {
if (UseBlackList && BlackList != null && BlackList.Contains(body))
return false;
if (UseWhiteList && WhiteList != null && !WhiteList.Contains(body))
return false;
return true;
}
public bool IsCollide() => _collisions.Count > 0;
public bool IsCollide(Node3D body) => _collisions.Contains(body);
}