Skip to content

Instantly share code, notes, and snippets.

@TSUMIKISEISAKU
Last active September 27, 2023 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TSUMIKISEISAKU/9e12490d42c1485f705c7af718201df8 to your computer and use it in GitHub Desktop.
Save TSUMIKISEISAKU/9e12490d42c1485f705c7af718201df8 to your computer and use it in GitHub Desktop.
using System.Collections;
using UnityEngine;
/// <summary>
/// スカルプトを利用したコンクリートのインタラクション管理
/// </summary>
public class ConcreteSculptManager : MonoBehaviour
{
[SerializeField, Tooltip("スカルプト制御")]
private SculptManager _sculptManager;
[SerializeField, Tooltip("干渉判定用LayerMask")]
private LayerMask _layerMask;
[SerializeField, Tooltip("破片のパーティクルの制御")]
private ConcreteParticlesHandler _particleHandler;
// スカルプトを実行する周期の制御
private IEnumerator _sculptingCycleSequence;
// パーティクル制御がBurst出ない場合に、スカルプト出来るタイミング
private bool _isSculptTiming;
/// <summary>
/// 初期化
/// </summary>
private void Start()
{
}
/// <summary>
/// 実際に道具による切削を行う
/// </summary>
/// <param name="position"></param>
/// <param name="direction"></param>
/// <param name="damage">このフレームで適用されるダメージ 0~1</param>
public void ApplyDamage(Vector3 position, Vector3 direction, float damage, float range, bool burstParticles)
{
// メッシュとの干渉判定を行う
// 切削エリア内に干渉判定用MeshColliderがあるかどうか調べる
Collider[] colliders = Physics.OverlapSphere(position, range, _layerMask);
bool isMeshColliderDetected = false;
for(int i = 0; i < colliders.Length; i++)
{
if (colliders[i] != _sculptManager.GetMeshCollider())
{
continue;
}
isMeshColliderDetected = true;
break;
}
// MeshColliderが無ければ離脱
if(!isMeshColliderDetected)
{
// 干渉が検出されなかったら破片のパーティクルを停止
_particleHandler.Stop();
// スカルプトの周期の計算を停止
if(_sculptingCycleSequence != null)
{
StopCoroutine(_sculptingCycleSequence);
_sculptingCycleSequence = null;
}
return;
}
if(_isSculptTiming || burstParticles)
{
// スカルプトを行う
_sculptManager.Sculpt(position, direction, damage, range);
}
// 干渉が検出されたら破片のパーティクルを再生
// damageはこのフレームで適用される値なので、
// 1秒当たりのダメージを代入するにはTime.deltaTimeで割る必要がある
_particleHandler.SetParams(position, -direction, damage / Time.deltaTime);
if (burstParticles)
{
_particleHandler.Burst();
}
else
{
_particleHandler.Play();
// スカルプトの周期の計算を開始
if(_sculptingCycleSequence == null)
{
_sculptingCycleSequence = SculptingCycleSequence();
StartCoroutine(_sculptingCycleSequence);
}
}
}
/// <summary>
/// スカルプトの周期の計算
/// </summary>
/// <returns></returns>
private IEnumerator SculptingCycleSequence()
{
WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
Vector2 intervalRange = new Vector2(0.1f, 0.3f);
while(true)
{
float interval = Random.Range(intervalRange.x, intervalRange.y);
yield return new WaitForSeconds(interval);
_isSculptTiming = true;
yield return waitForEndOfFrame;
yield return waitForEndOfFrame;
_isSculptTiming = false;
}
}
/// <summary>
/// 地絡発生時のスカルプト用メッシュの陥没
/// </summary>
public void ApplyDamageForAccident(Vector3 position, Vector3 direction)
{
float damage = 0.1f;
float range = 0.06f;
// スカルプトを行う
_sculptManager.Sculpt(position, direction, damage, range);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment