BITKit/Src/Unity/Scripts/WorldNode/WorldNodeService.cs

101 lines
2.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Quadtree;
using Quadtree.Items;
using UnityEngine;
namespace BITKit.WorldNodes
{
public interface IWorldNodeService
{
IWorldNode[] WorldNodes { get; }
IWorldNode[] GetNodes(Vector3 position, float radius);
IWorldNode[] GetConnectedNodes(IWorldNode node);
}
public abstract class WorldNodeServiceImplementation : IWorldNodeService
{
protected virtual IWorldNodeService Service { get; }
public IWorldNode[] WorldNodes => Service.WorldNodes;
public IWorldNode[] GetNodes(Vector3 position, float radius)
{
return Service.GetNodes(position, radius);
}
public IWorldNode[] GetConnectedNodes(IWorldNode node)
{
return Service.GetConnectedNodes(node);
}
}
[ExecuteInEditMode]
public class WorldNodeService : MonoBehaviour,IWorldNodeService
{
private class WorldNodeProxy : IItem<WorldNodeProxy, Node<WorldNodeProxy>>
{
public Bounds Bounds;
public Bounds GetBounds()=>Bounds;
public Node<WorldNodeProxy> ParentNode { get; set; }
public void QuadTree_Root_Initialized(IQuadtreeRoot<WorldNodeProxy, Node<WorldNodeProxy>> root)
{
}
}
public static event Action OnDrawGizmo;
public static readonly CacheList<IWorldNode> WorldNodeList = new();
public static IWorldNode[] WorldNodes => WorldNodeList.ValueArray;
private static QuadtreeRoot<WorldNodeProxy, Node<WorldNodeProxy>> _QuadtreeRoot;
public static IWorldNode[] GetNodes(Vector3 position, float radius)
{
return WorldNodes.Where(node => InRange(position, node, radius))
.Where(node => InSight(position, node))
.ToArray();
}
public static IWorldNode[] GetConnectedNodes(IWorldNode node)
{
throw new System.NotImplementedException();
}
private static bool InRange(Vector3 position, IWorldNode node, float radius)
{
return Vector3.Distance(position, node.Position) <= radius;
}
private static bool InSight(Vector3 position, IWorldNode node)
{
if (Physics.Linecast(position, node.Position, out var hit))
{
return hit.transform == node.As<MonoBehaviour>().transform;
}
return true;
}
IWorldNode[] IWorldNodeService.WorldNodes => WorldNodes;
IWorldNode[] IWorldNodeService.GetNodes(Vector3 position, float radius)
{
return GetNodes(position, radius);
}
IWorldNode[] IWorldNodeService.GetConnectedNodes(IWorldNode node)
{
return GetConnectedNodes(node);
}
private void OnDrawGizmos()
{
OnDrawGizmo?.Invoke();
}
private void Reset()
{
WorldNodeList.Clear();
}
[SerializeField] private Vector3 size;
private void Start()
{
_QuadtreeRoot = new QuadtreeRoot<WorldNodeProxy, Node<WorldNodeProxy>>(transform.position,size);
}
}
}