RoguelikeKit/Assets/Common/Scripts/Boss Fight/CircleFenceBehavior.cs

107 lines
3.0 KiB
C#

using UnityEngine;
namespace OctoberStudio
{
public class CircleFenceBehavior : BossFenceBehavior
{
[SerializeField] float radius = 5f;
public float Radius { get; private set; }
public override void Init()
{
Radius = radius;
float perimeter = 2 * Mathf.PI * radius;
FencePoolSize = Mathf.CeilToInt(perimeter / linkDistance);
base.Init();
}
public override void SpawnFence(Vector2 center)
{
base.SpawnFence(center);
float angleStep = 360f / FencePoolSize;
for(int i = 0; i < FencePoolSize; i++)
{
var position = Center + (Vector2)(Quaternion.Euler(0, 0, angleStep * i) * Vector2.up * Radius);
if (StageController.FieldManager.ValidatePosition(position, Vector2.zero, false))
{
var link = fenceLinkPool.GetEntity();
link.transform.position = position;
link.transform.rotation = Quaternion.identity;
fenceLinks.Add(link);
}
}
}
public override Vector2 GetRandomPointInside(float offset)
{
return Center + Random.insideUnitCircle * (Radius - offset);
}
public override bool ValidatePosition(Vector2 position, Vector2 offset)
{
var biggerOffset = Mathf.Max(offset.x, offset.y);
return Vector2.Distance(Center, position) < (Radius - biggerOffset);
}
public override Vector2 GetIntersectionPoint(Vector2 start, Vector2 end, float offset)
{
var path = end - start;
var distance = path.magnitude;
if(distance < Mathf.Epsilon) return start;
var startToCenter = start - Center;
var offsetRadius = Radius - offset;
var a = Vector2.Dot(path, path);
var b = 2 * Vector2.Dot(startToCenter, path);
var c = Vector2.Dot(startToCenter, startToCenter) - offsetRadius * offsetRadius;
var discriminant = b * b - 4 * a * c;
if (discriminant < 0) return start;
var sqrtDisc = Mathf.Sqrt(discriminant);
// Two roots
var t1 = (-b - sqrtDisc) / (2 * a);
var t2 = (-b + sqrtDisc) / (2 * a);
var t = Mathf.Max(t1, t2);
if (t < 0) return start;
return start + path * t;
}
public void SetRadiusOverride(float radiusOverride)
{
Radius = radiusOverride;
float perimeter = 2 * Mathf.PI * Radius;
FencePoolSize = Mathf.CeilToInt(perimeter / linkDistance);
}
public void ResetRadiusOverride()
{
Radius = radius;
float perimeter = 2 * Mathf.PI * Radius;
FencePoolSize = Mathf.CeilToInt(perimeter / linkDistance);
}
public override void RemoveFence()
{
base.RemoveFence();
ResetRadiusOverride();
}
}
}