CapersProject/Assets/02.Scripts/Prop/Rockfall.cs

157 lines
5.0 KiB
C#
Raw Normal View History

using System;
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;
namespace BlueWater
{
public class Rockfall : DamageableProps
{
[Title("컴포넌트")]
[SerializeField]
private Rigidbody _rigidbody;
[SerializeField, Required]
private SphereCollider _sphereCollider;
2024-06-14 09:34:58 +00:00
[SerializeField]
private DecalProjector _indicator;
[Title("표시기 설정")]
[SerializeField]
private bool _isUsingIndicator = true;
[Title("충돌 설정")]
[SerializeField]
private LayerMask _targetLayer;
[SerializeField]
private LayerMask _groundLayer;
[SerializeField, Range(0f, 1f)]
private float _checkDistance = 0.1f;
[SerializeField, Range(0, 5)]
private int _attackDamage = 1;
[Title("Ground Crash 설정")]
[SerializeField]
private string _groundCrashSfxName;
[SerializeField]
private ParticleSystem _groundCrashParticle;
private Collider[] _hitColliders = new Collider[4];
private RaycastHit _raycastHit;
private float _startDistance = float.PositiveInfinity;
private bool _isGrounded;
private bool _isAttacked;
2024-06-14 09:34:58 +00:00
// Hashes
private static readonly int _fillHash = Shader.PropertyToID("_Fill");
private void OnDrawGizmos()
{
Debug.DrawRay(transform.position, Vector3.down * _checkDistance, _isGrounded ? Color.blue : Color.red);
}
private void Start()
{
_sphereCollider.enabled = false;
SpawnLocation = MapManager.Instance.SandMoleMapController.ParticleInstantiateLocation;
if (!Physics.Raycast(transform.position, Vector3.down, out _raycastHit, 10f, _groundLayer))
{
Debug.LogError("땅을 감지하지 못하는 버그");
return;
}
2024-06-14 09:34:58 +00:00
BasicSetting();
ShowIndicator();
_startDistance = _raycastHit.distance;
}
2024-06-14 09:34:58 +00:00
2024-06-15 02:35:32 +00:00
private void FixedUpdate()
{
if (!Physics.Raycast(transform.position, Vector3.down, out _raycastHit, 10f, _groundLayer))
{
Debug.LogError("땅을 감지하지 못하는 버그");
return;
}
_isGrounded = _raycastHit.distance <= _checkDistance;
2024-06-14 09:34:58 +00:00
if (!_isGrounded)
{
2024-06-14 09:34:58 +00:00
if (_isUsingIndicator && _indicator)
{
var fillValue = Mathf.Lerp(1f, 0f, _raycastHit.distance / _startDistance);
2024-06-14 09:34:58 +00:00
_indicator.material.SetFloat(_fillHash, fillValue);
}
}
else if (_isGrounded && !_isAttacked)
{
_indicator.material.SetFloat(_fillHash, 1f);
HideIndicator();
if (_rigidbody)
{
_rigidbody.isKinematic = true;
}
_sphereCollider.enabled = true;
if (!string.IsNullOrEmpty(_groundCrashSfxName))
{
AudioManager.Instance.PlaySfx(_groundCrashSfxName);
}
if (_groundCrashParticle && SpawnLocation)
{
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;
iDamageable.TakeDamage(_attackDamage);
Die();
}
_isAttacked = true;
}
}
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;
}
}
}