Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Submodules/RaycastSubmodule.cs
2025-12-24 16:58:51 -05:00

84 lines
3.6 KiB
C#

using System;
using Cielonos.MainGame.Characters;
using Unity.VisualScripting;
using UnityEngine;
namespace Cielonos.MainGame
{
public class RaycastSubmodule : AttackAreaSubmoduleBase
{
public bool isDynamicDirection;
public bool isDynamicRayLength;
public Vector3 direction;
public float rayLength;
public float rayRadius;
public bool isCapsuleRay => rayRadius > 0;
public Action<Collider, Vector3> onHit;
public RaycastSubmodule(AttackAreaBase owner, Vector3 direction, float rayRadius, float rayLength) : base(owner)
{
this.isDynamicDirection = direction == default;
this.isDynamicRayLength = rayLength < 0;
this.direction = direction;
this.rayLength = rayLength;
this.rayRadius = rayRadius;
this.onHit = (collider, point) =>
{
owner.HitCharacter(collider, point);
owner.HitEnvironment(collider, point);
};
}
public void Update()
{
if (owner.moveSm != null && isDynamicRayLength)
{
rayLength = owner.moveSm.scaledVelocity.magnitude * Time.deltaTime;
}
Vector3 rayDirection = isDynamicDirection ? owner.topParent.forward : direction;
Ray ray = new Ray(owner.transform.position, rayDirection);
if (isCapsuleRay)
{
float capsuleRadius = Mathf.Max(rayRadius, 0.1f);
float capsuleHeight = Mathf.Max(rayLength, 0.1f);
Vector3 point0 = owner.transform.position + rayDirection.normalized * capsuleHeight;
Vector3 point1 = owner.transform.position - rayDirection.normalized * capsuleHeight;
Collider[] hitColliders = new Collider[8];
int size = Physics.OverlapCapsuleNonAlloc(point0, point1, capsuleRadius, hitColliders,
LayerMask.GetMask("HurtBox", "Default", "FadableEnvironment", "UnfadableEnvironment", "Wall", "Ground"));
if (size >= 1)
{
Debug.Log("RaycastSubmodule detected colliders: " + size);
for (int i = 0; i < size; i++)
{
CharacterBase character = hitColliders[i].GetComponentInParent<CharacterBase>();
if (character != null)
{
Debug.Log("RaycastSubmodule hit character: " + character.name);
onHit?.Invoke(hitColliders[i], hitColliders[i].ClosestPoint(owner.transform.position));
return;
}
}
onHit?.Invoke(hitColliders[0], hitColliders[0].ClosestPoint(owner.transform.position));
return;
}
/*if (Physics.CapsuleCast(point0, point1, capsuleRadius, rayDirection, out RaycastHit hit, rayLength,
LayerMask.GetMask("Player", "Enemy", "Default", "FadableEnvironment", "UnfadableEnvironment", "Wall", "Ground")))
{
onHit?.Invoke(hit.collider, hit.point);
}*/
}
else
{
if (Physics.Raycast(ray, out RaycastHit hit, rayLength,
LayerMask.GetMask("HurtBox", "Default", "FadableEnvironment", "UnfadableEnvironment", "Wall", "Ground")))
{
onHit?.Invoke(hit.collider, hit.point);
}
}
}
}
}