2024-06-03 18:26:03 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
2024-06-18 18:16:19 +00:00
|
|
|
|
using System.Collections.Generic;
|
2024-11-07 12:20:24 +00:00
|
|
|
|
using Pathfinding;
|
2024-06-03 18:26:03 +00:00
|
|
|
|
using UnityEngine;
|
2024-11-11 02:02:24 +00:00
|
|
|
|
using UnityEngine.Localization.Settings;
|
|
|
|
|
using UnityEngine.Localization.Tables;
|
|
|
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
2024-11-07 12:20:24 +00:00
|
|
|
|
using Random = UnityEngine.Random;
|
2024-06-03 18:26:03 +00:00
|
|
|
|
|
2025-02-10 02:13:46 +00:00
|
|
|
|
namespace DDD.Utility
|
2024-06-03 18:26:03 +00:00
|
|
|
|
{
|
|
|
|
|
public static class Utils
|
|
|
|
|
{
|
|
|
|
|
public static IEnumerator CoolDownCoroutine(float waitTime, Action onCooldownComplete = null)
|
|
|
|
|
{
|
|
|
|
|
yield return new WaitForSeconds(waitTime);
|
|
|
|
|
onCooldownComplete?.Invoke();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void StartUniqueCoroutine(MonoBehaviour owner, ref Coroutine coroutineField, IEnumerator coroutineMethod)
|
|
|
|
|
{
|
|
|
|
|
if (coroutineField != null)
|
|
|
|
|
{
|
|
|
|
|
owner.StopCoroutine(coroutineField);
|
|
|
|
|
coroutineField = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coroutineField = owner.StartCoroutine(coroutineMethod);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void EndUniqueCoroutine(MonoBehaviour owner, ref Coroutine coroutineField)
|
|
|
|
|
{
|
|
|
|
|
if (coroutineField != null)
|
|
|
|
|
{
|
|
|
|
|
owner.StopCoroutine(coroutineField);
|
|
|
|
|
coroutineField = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-18 18:16:19 +00:00
|
|
|
|
|
|
|
|
|
public static void RegisterList<T>(List<T> list, T item)
|
|
|
|
|
{
|
|
|
|
|
if (list.Contains(item))
|
|
|
|
|
{
|
2024-11-07 09:13:54 +00:00
|
|
|
|
Debug.Log($"{item}은 이미 {list}안에 등록되어 있습니다.");
|
2024-06-18 18:16:19 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list.Add(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void UnregisterList<T>(List<T> list, T item)
|
|
|
|
|
{
|
|
|
|
|
if (!list.Contains(item))
|
|
|
|
|
{
|
2024-11-07 09:13:54 +00:00
|
|
|
|
Debug.Log($"{item}은 {list}안에 없습니다.");
|
2024-06-18 18:16:19 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list.Remove(item);
|
|
|
|
|
}
|
2024-11-07 12:20:24 +00:00
|
|
|
|
|
2024-12-20 05:11:56 +00:00
|
|
|
|
public static Vector3 RandomPositionOnGraph(int graphIndex = 0, float radius = 0.5f)
|
2024-11-07 12:20:24 +00:00
|
|
|
|
{
|
|
|
|
|
// 그래프 인덱스가 유효한지 검사
|
|
|
|
|
if (graphIndex < 0 || graphIndex >= AstarPath.active.data.graphs.Length)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("유효하지 않은 그래프 인덱스입니다.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 특정 그래프를 가져와 모든 walkable 노드를 수집
|
|
|
|
|
List<GraphNode> walkableNodes = new List<GraphNode>();
|
|
|
|
|
NavGraph graph = AstarPath.active.data.graphs[graphIndex];
|
|
|
|
|
|
|
|
|
|
graph.GetNodes(node =>
|
|
|
|
|
{
|
|
|
|
|
if (node.Walkable)
|
|
|
|
|
{
|
|
|
|
|
walkableNodes.Add(node);
|
|
|
|
|
}
|
|
|
|
|
return true; // 모든 노드를 반복하도록 true 반환
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// walkable한 노드가 없을 경우 Vector3.zero 반환
|
|
|
|
|
if (walkableNodes.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("이동 가능한 노드가 없습니다.");
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 05:11:56 +00:00
|
|
|
|
LayerMask propsLayerMask = LayerMask.GetMask("Props");
|
|
|
|
|
// 반복적으로 랜덤 위치를 가져와 조건을 만족하는지 확인
|
|
|
|
|
for (int attempt = 0; attempt < 100000; attempt++)
|
|
|
|
|
{
|
|
|
|
|
// walkable한 노드 중 하나를 무작위로 선택
|
|
|
|
|
GraphNode randomNode = walkableNodes[Random.Range(0, walkableNodes.Count)];
|
|
|
|
|
|
|
|
|
|
// 선택한 노드의 위치를 Vector3로 변환
|
|
|
|
|
Vector3 randomPosition = (Vector3)randomNode.position;
|
|
|
|
|
|
|
|
|
|
// 반경과 Props 레이어가 설정되어 있다면 검사
|
|
|
|
|
if (radius > 0)
|
|
|
|
|
{
|
|
|
|
|
// 반경 내 Props 레이어 오브젝트가 있는지 검사
|
|
|
|
|
Collider[] results = new Collider[1];
|
|
|
|
|
var size = Physics.OverlapSphereNonAlloc(randomPosition, radius, results, propsLayerMask, QueryTriggerInteraction.Collide);
|
|
|
|
|
|
|
|
|
|
// Props가 발견되면 다시 시도
|
|
|
|
|
if (size > 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 조건을 만족하면 위치 반환
|
|
|
|
|
return randomPosition;
|
|
|
|
|
}
|
2024-11-07 12:20:24 +00:00
|
|
|
|
|
2024-12-20 05:11:56 +00:00
|
|
|
|
// 반복 시도 후에도 유효한 위치를 찾지 못한 경우 예외 처리
|
|
|
|
|
throw new Exception("조건을 만족하는 유효한 위치를 찾지 못했습니다.");
|
2024-11-07 12:20:24 +00:00
|
|
|
|
}
|
2024-11-11 02:02:24 +00:00
|
|
|
|
|
|
|
|
|
public static string GetLocalizedString(string key)
|
|
|
|
|
{
|
|
|
|
|
return LocalizationSettings.StringDatabase.GetLocalizedString("StringDataTable", key, LocalizationSettings.SelectedLocale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static AsyncOperationHandle<StringTable> GetTableAsync()
|
|
|
|
|
{
|
|
|
|
|
return LocalizationSettings.StringDatabase.GetTableAsync("StringDataTable");
|
|
|
|
|
}
|
2024-06-03 18:26:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|