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