2023-12-15 07:19:02 +00:00
|
|
|
using Sirenix.OdinInspector;
|
2024-01-14 17:24:48 +00:00
|
|
|
using Unity.Mathematics;
|
2023-12-15 07:19:02 +00:00
|
|
|
using UnityEngine;
|
2024-01-14 17:24:48 +00:00
|
|
|
using Random = UnityEngine.Random;
|
2023-12-15 07:19:02 +00:00
|
|
|
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
|
|
namespace BlueWaterProject
|
|
|
|
{
|
|
|
|
public class Cannon : MonoBehaviour
|
|
|
|
{
|
2023-12-17 19:50:44 +00:00
|
|
|
[Title("초기화 방식")]
|
|
|
|
[SerializeField] private bool autoInit = true;
|
|
|
|
|
|
|
|
[Title("캐논 변수")]
|
2023-12-15 07:19:02 +00:00
|
|
|
[SerializeField] private GameObject projectileObj;
|
|
|
|
[SerializeField] private Transform firePos;
|
2024-01-14 17:24:48 +00:00
|
|
|
[Range(0f, 0.5f)]
|
|
|
|
[SerializeField] private float fireAngle = 0.2f;
|
|
|
|
[SerializeField] private float speed = 75f;
|
|
|
|
[SerializeField] private float height = 20f;
|
2024-01-02 21:39:53 +00:00
|
|
|
[SerializeField] private Vector2 randomCatch = new(1, 4);
|
2023-12-15 07:19:02 +00:00
|
|
|
|
2023-12-17 19:50:44 +00:00
|
|
|
[Title("캐논 발사 카메라 효과")]
|
2024-01-14 17:24:48 +00:00
|
|
|
[SerializeField] private float cameraShakePower = 2f;
|
|
|
|
[SerializeField] private float cameraShakeDuration = 0.3f;
|
2023-12-17 19:50:44 +00:00
|
|
|
|
2024-01-02 21:39:53 +00:00
|
|
|
private float cannonRadius;
|
|
|
|
private LayerMask boidsLayer;
|
2024-01-18 07:21:07 +00:00
|
|
|
private Collider[] hitColliders = new Collider[3];
|
2024-01-02 21:39:53 +00:00
|
|
|
|
2023-12-17 19:50:44 +00:00
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
if (autoInit)
|
|
|
|
{
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
}
|
2023-12-15 07:19:02 +00:00
|
|
|
|
|
|
|
[Button("셋팅 초기화")]
|
|
|
|
private void Init()
|
|
|
|
{
|
|
|
|
projectileObj = Utils.LoadFromFolder<GameObject>("Assets/05.Prefabs/Particles/GrenadeFire", "GrenadeFireOBJ", ".prefab");
|
|
|
|
firePos = transform.Find("FirePos");
|
2024-01-02 21:39:53 +00:00
|
|
|
cannonRadius = projectileObj.GetComponent<SphereCollider>()?.radius ??
|
|
|
|
projectileObj.GetComponent<ParticleWeapon>().colliderRadius;
|
|
|
|
boidsLayer = LayerMask.GetMask("Boids");
|
2023-12-15 07:19:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Fire(float chargingGauge)
|
|
|
|
{
|
2023-12-17 19:50:44 +00:00
|
|
|
VisualFeedbackManager.Inst.CameraShake(CameraManager.Inst.OceanCamera.BaseShipCam, cameraShakePower, cameraShakeDuration);
|
2024-01-14 17:24:48 +00:00
|
|
|
var addAngle = chargingGauge * fireAngle;
|
|
|
|
var firePosRotation = firePos.rotation.eulerAngles;
|
|
|
|
firePosRotation.x -= addAngle;
|
|
|
|
var projectile = Instantiate(projectileObj, firePos.position, Quaternion.Euler(firePosRotation));
|
2024-01-02 21:39:53 +00:00
|
|
|
var particleWeapon = projectile.GetComponent<ParticleWeapon>();
|
|
|
|
particleWeapon.onHitAction.AddListener(HandleCannonHit);
|
2024-01-14 17:24:48 +00:00
|
|
|
projectile.GetComponent<Rigidbody>().velocity = projectile.transform.forward * speed;
|
2023-12-15 07:19:02 +00:00
|
|
|
}
|
2024-01-02 21:39:53 +00:00
|
|
|
|
|
|
|
private void HandleCannonHit(RaycastHit hit, float power)
|
|
|
|
{
|
|
|
|
if (hit.collider.gameObject.layer == LayerMask.NameToLayer("Water"))
|
|
|
|
{
|
2024-01-18 07:21:07 +00:00
|
|
|
var maxSize = Physics.OverlapSphereNonAlloc(hit.point, cannonRadius, hitColliders, boidsLayer,
|
|
|
|
QueryTriggerInteraction.Collide);
|
2024-01-02 21:39:53 +00:00
|
|
|
|
2024-01-18 07:21:07 +00:00
|
|
|
for (var i = 0; i < maxSize; i++)
|
2024-01-02 21:39:53 +00:00
|
|
|
{
|
2024-01-18 07:21:07 +00:00
|
|
|
var hitBoids = hitColliders[i].GetComponentInParent<Boids>();
|
|
|
|
var catchSize = Random.Range((int)randomCatch.x, (int)randomCatch.y);
|
2024-01-21 17:42:31 +00:00
|
|
|
hitBoids.CatchBoid(hitColliders[i], catchSize);
|
2024-01-02 21:39:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hit.transform.GetComponent<IDamageable>()?.TakeDamage(power);
|
|
|
|
}
|
|
|
|
}
|
2023-12-15 07:19:02 +00:00
|
|
|
}
|
|
|
|
}
|