2024-06-14 09:11:35 +00:00
|
|
|
using System.Collections;
|
|
|
|
using BlueWater.Audios;
|
|
|
|
using BlueWater.Interfaces;
|
|
|
|
using BlueWater.Maps;
|
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
using UnityEngine;
|
2024-06-14 09:34:58 +00:00
|
|
|
using UnityEngine.Rendering.Universal;
|
2024-06-14 09:11:35 +00:00
|
|
|
|
|
|
|
namespace BlueWater
|
|
|
|
{
|
|
|
|
public class Rockfall : DamageableProps
|
|
|
|
{
|
|
|
|
[Title("컴포넌트")]
|
|
|
|
[SerializeField, Required]
|
|
|
|
private SphereCollider _sphereCollider;
|
2024-06-25 06:19:16 +00:00
|
|
|
|
|
|
|
[SerializeField, Required]
|
|
|
|
private GameObject _visualLook;
|
2024-06-14 09:11:35 +00:00
|
|
|
|
2024-06-14 09:34:58 +00:00
|
|
|
[SerializeField]
|
|
|
|
private DecalProjector _indicator;
|
|
|
|
|
|
|
|
[Title("표시기 설정")]
|
|
|
|
[SerializeField]
|
|
|
|
private bool _isUsingIndicator = true;
|
|
|
|
|
2024-06-14 09:11:35 +00:00
|
|
|
[Title("충돌 설정")]
|
|
|
|
[SerializeField]
|
|
|
|
private LayerMask _targetLayer;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private LayerMask _groundLayer;
|
|
|
|
|
2024-06-25 06:19:16 +00:00
|
|
|
[SerializeField, Range(0f, 5f), ShowIf("@_isUsingIndicator")]
|
|
|
|
private float _indicatorTime = 0.5f;
|
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
[SerializeField, Range(0f, 5f)]
|
2024-06-25 06:19:16 +00:00
|
|
|
private float _fallTime = 0.5f;
|
2024-06-14 09:11:35 +00:00
|
|
|
|
|
|
|
[SerializeField, Range(0, 5)]
|
|
|
|
private int _attackDamage = 1;
|
2024-06-25 06:19:16 +00:00
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private bool _isAcceleratedFall = true;
|
2024-06-14 09:11:35 +00:00
|
|
|
|
|
|
|
[Title("Ground Crash 설정")]
|
|
|
|
[SerializeField]
|
|
|
|
private string _groundCrashSfxName;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private ParticleSystem _groundCrashParticle;
|
2024-06-16 07:55:58 +00:00
|
|
|
|
|
|
|
private Collider[] _hitColliders;
|
2024-06-15 02:26:48 +00:00
|
|
|
private RaycastHit _raycastHit;
|
2024-06-16 07:55:58 +00:00
|
|
|
private Vector3 _startPosition;
|
|
|
|
private Vector3 _endPosition;
|
2024-06-14 09:11:35 +00:00
|
|
|
private bool _isAttacked;
|
2024-06-14 09:34:58 +00:00
|
|
|
|
|
|
|
// Hashes
|
|
|
|
private static readonly int _fillHash = Shader.PropertyToID("_Fill");
|
2024-06-14 09:11:35 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
private IEnumerator Start()
|
2024-06-14 09:11:35 +00:00
|
|
|
{
|
2024-06-25 06:19:16 +00:00
|
|
|
_visualLook.SetActive(false);
|
2024-06-14 09:11:35 +00:00
|
|
|
_sphereCollider.enabled = false;
|
2024-06-16 07:55:58 +00:00
|
|
|
_startPosition = transform.position;
|
2024-06-21 22:11:53 +00:00
|
|
|
SpawnLocation = MapManager.Instance.SandMoleMapController.ParticleInstanceLocation;
|
2024-06-16 07:55:58 +00:00
|
|
|
_hitColliders = new Collider[4];
|
|
|
|
BasicSetting();
|
2024-06-15 02:26:48 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
if (!Physics.Raycast(transform.position, Vector3.down, out _raycastHit, 50f, _groundLayer))
|
2024-06-15 02:26:48 +00:00
|
|
|
{
|
|
|
|
Debug.LogError("땅을 감지하지 못하는 버그");
|
2024-06-16 07:55:58 +00:00
|
|
|
yield break;
|
2024-06-15 02:26:48 +00:00
|
|
|
}
|
2024-06-16 07:55:58 +00:00
|
|
|
_endPosition = _raycastHit.point;
|
2024-06-15 02:26:48 +00:00
|
|
|
|
2024-06-14 09:34:58 +00:00
|
|
|
ShowIndicator();
|
2024-06-16 07:55:58 +00:00
|
|
|
var elapsedTime = 0f;
|
2024-06-25 06:19:16 +00:00
|
|
|
while (elapsedTime <= _indicatorTime)
|
2024-06-15 02:26:48 +00:00
|
|
|
{
|
2024-06-25 06:19:16 +00:00
|
|
|
var time = elapsedTime / _indicatorTime;
|
2024-06-14 09:34:58 +00:00
|
|
|
if (_isUsingIndicator && _indicator)
|
|
|
|
{
|
2024-06-16 07:55:58 +00:00
|
|
|
var fillValue = Mathf.Lerp(0f, 1f, time);
|
2024-06-14 09:34:58 +00:00
|
|
|
_indicator.material.SetFloat(_fillHash, fillValue);
|
|
|
|
}
|
2024-06-25 06:19:16 +00:00
|
|
|
//transform.position = Vector3.Lerp(_startPosition, _endPosition, time);
|
2024-06-16 07:55:58 +00:00
|
|
|
elapsedTime += Time.deltaTime;
|
2024-06-15 02:26:48 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
yield return null;
|
|
|
|
}
|
2024-06-14 09:11:35 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
_indicator.material.SetFloat(_fillHash, 1f);
|
|
|
|
HideIndicator();
|
2024-06-25 06:19:16 +00:00
|
|
|
_visualLook.SetActive(true);
|
|
|
|
|
|
|
|
if (_isAcceleratedFall)
|
|
|
|
{
|
|
|
|
var distance = Vector3.Distance(_startPosition, _endPosition);
|
|
|
|
var acceleration = 2 * distance / (_fallTime * _fallTime); // a = 2d / t^2
|
|
|
|
elapsedTime = 0f;
|
|
|
|
|
|
|
|
while (elapsedTime <= _fallTime)
|
|
|
|
{
|
|
|
|
var time = elapsedTime;
|
|
|
|
var displacement = 0.5f * acceleration * time * time;
|
|
|
|
var progress = displacement / distance;
|
|
|
|
transform.position = Vector3.Lerp(_startPosition, _endPosition, progress);
|
|
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elapsedTime = 0f;
|
|
|
|
while (elapsedTime <= _fallTime)
|
|
|
|
{
|
|
|
|
var time = elapsedTime / _fallTime;
|
|
|
|
transform.position = Vector3.Lerp(_startPosition, _endPosition, time);
|
|
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
}
|
2024-06-16 07:55:58 +00:00
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(_groundCrashSfxName))
|
|
|
|
{
|
|
|
|
AudioManager.Instance.PlaySfx(_groundCrashSfxName);
|
|
|
|
}
|
2024-06-14 09:11:35 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
if (_groundCrashParticle)
|
|
|
|
{
|
|
|
|
if (!SpawnLocation)
|
2024-06-15 02:26:48 +00:00
|
|
|
{
|
2024-06-16 07:55:58 +00:00
|
|
|
Debug.LogError("파티클 위치 생성 오류");
|
|
|
|
yield break;
|
2024-06-15 02:26:48 +00:00
|
|
|
}
|
2024-06-16 07:55:58 +00:00
|
|
|
Instantiate(_groundCrashParticle, transform.position, Quaternion.identity, SpawnLocation);
|
|
|
|
}
|
|
|
|
|
|
|
|
var hitCount = Physics.OverlapSphereNonAlloc(_sphereCollider.bounds.center, _sphereCollider.radius,
|
|
|
|
_hitColliders, _targetLayer, QueryTriggerInteraction.Collide);
|
|
|
|
for (var i = 0; i < hitCount; i++)
|
|
|
|
{
|
|
|
|
var hitCollider = _hitColliders[i];
|
|
|
|
var iDamageable = hitCollider.GetComponentInParent<IDamageable>();
|
|
|
|
if (iDamageable == null || !iDamageable.CanDamage()) continue;
|
2024-06-14 09:11:35 +00:00
|
|
|
|
2024-06-16 07:55:58 +00:00
|
|
|
iDamageable.TakeDamage(_attackDamage);
|
2024-06-15 02:26:48 +00:00
|
|
|
_isAttacked = true;
|
2024-06-14 09:11:35 +00:00
|
|
|
}
|
2024-06-16 07:55:58 +00:00
|
|
|
|
|
|
|
if (_isAttacked)
|
|
|
|
{
|
|
|
|
Die();
|
|
|
|
yield break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_sphereCollider.enabled = true;
|
2024-06-14 09:11:35 +00:00
|
|
|
}
|
2024-06-14 09:34:58 +00:00
|
|
|
|
|
|
|
private void BasicSetting()
|
|
|
|
{
|
|
|
|
if (!_isUsingIndicator || !_indicator) return;
|
|
|
|
|
|
|
|
_indicator.scaleMode = DecalScaleMode.InheritFromHierarchy;
|
|
|
|
_indicator.material = new Material(_indicator.material);
|
|
|
|
_indicator.material.SetFloat(_fillHash, 0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void HideIndicator()
|
|
|
|
{
|
|
|
|
if (!_isUsingIndicator || !_indicator) return;
|
|
|
|
|
|
|
|
_indicator.enabled = false;
|
|
|
|
_indicator.material.SetFloat(_fillHash, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ShowIndicator()
|
|
|
|
{
|
|
|
|
if (!_isUsingIndicator || !_indicator) return;
|
|
|
|
|
|
|
|
_indicator.material.SetFloat(_fillHash, 0);
|
|
|
|
_indicator.enabled = true;
|
|
|
|
}
|
2024-06-14 09:11:35 +00:00
|
|
|
}
|
|
|
|
}
|