using System; using System.Collections; using System.Diagnostics; using BehaviorDesigner.Runtime; using UnityEditor; using UnityEngine; using UnityEngine.AI; using UnityEngine.Assertions; using Debug = UnityEngine.Debug; using Object = UnityEngine.Object; using Random = UnityEngine.Random; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class Utils { public enum DebugType { NONE, LOG, WARNING, ERROR, DEBUG_ASSERT, ASSERT // } /// /// 각도를 통해 방향값을 반환하는 함수 /// public static Vector3 AngleToDir(float angle) { var radian = angle * Mathf.Deg2Rad; return new Vector3(Mathf.Sin(radian), 0f, Mathf.Cos(radian)).normalized; } // public static T FindTaskAndAssert(BehaviorTree behaviorTree) where T : Task // { // var newBehaviorTask = behaviorTree.FindTask(); // Assert.IsNotNull(newBehaviorTask, typeof(T) + "타입의 Task가 존재하지 않습니다."); // // return newBehaviorTask; // } public static T GetComponentAndAssert(Transform componentLocation, DebugType debugType = DebugType.DEBUG_ASSERT) where T : class { var newComponent = componentLocation.GetComponent(); switch (debugType) { case DebugType.NONE: Debug.Log("DebugType is None."); break; case DebugType.LOG: Debug.Log(typeof(T) + "타입의 Component가 존재하지 않습니다."); break; case DebugType.WARNING: Debug.LogWarning(typeof(T) + "타입의 Component가 존재하지 않습니다."); break; case DebugType.ERROR: Debug.LogError(typeof(T) + "타입의 Component가 존재하지 않습니다."); break; case DebugType.DEBUG_ASSERT: Debug.Assert(newComponent != null, typeof(T) + "타입의 Component가 존재하지 않습니다."); break; case DebugType.ASSERT: Assert.IsNotNull(newComponent, typeof(T) + "타입의 Component가 존재하지 않습니다."); break; default: throw new ArgumentOutOfRangeException(nameof(debugType), debugType, null); } return newComponent; } public static bool ArrivedAgentDestination(NavMeshAgent agent) => !agent.pathPending && agent.remainingDistance <= agent.stoppingDistance; /// /// 메서드를 누가 호출하는지 알려주는 메서드입니다 /// 메서드 마지막에 이 함수를 호출하면 됩니다 /// public static void WhereCallThisFunction() { var stackTrace = new StackTrace(); var stackFrame = stackTrace.GetFrame(1); var method = stackFrame.GetMethod(); var className = method.DeclaringType?.Name; var methodName = method.Name; UnityEngine.Debug.Log($"Call {className}.{methodName}"); } public static float CalcDamage(float attackerPower, float attackerShieldPenetrationRate, EnemyStat defender) { var finalDamage = 0f; if (defender.UsingShield) { var penetrationChance = attackerShieldPenetrationRate - (attackerShieldPenetrationRate * defender.PenetrationResistivity * 0.01f); // 방패를 관통했다면, if (Random.Range(0, 100) < penetrationChance) { finalDamage = attackerPower - defender.Def; finalDamage = Mathf.Max(finalDamage, 0); return finalDamage; } // 방패를 관통하지 못 함 return 0; } finalDamage = attackerPower - defender.Def; finalDamage = Mathf.Max(finalDamage, 0); return finalDamage; } public static IEnumerator CoolDown(float waitTime, Action onCooldownComplete = null) { var time = 0f; while (time <= waitTime) { time += Time.deltaTime; yield return null; } onCooldownComplete?.Invoke(); } public static bool SetCloseDestination(NavMeshAgent agent, Vector3 destination, float stopDistance, float maxDistance) { var walkableMask = 1 << NavMesh.GetAreaFromName("Walkable"); if (NavMesh.SamplePosition(destination, out var hit, maxDistance, walkableMask)) { agent.stoppingDistance = stopDistance; agent.SetDestination(hit.position); return true; // var path = new NavMeshPath(); // if (agent.CalculatePath(hit.position, path) && path.status == NavMeshPathStatus.PathComplete) // { // agent.stoppingDistance = stopDistance; // agent.SetDestination(hit.position); // return true; // } // // Debug.Log("길이 연결되어 있지 않습니다."); // return false; } Debug.Log("근처에 갈 수 있는 위치가 없습니다."); return false; } public static void SetBehaviorVariable(Behavior behaviorTreeComponent, string behaviorVariableName, T value) { var sharedVariable = behaviorTreeComponent.GetVariable(behaviorVariableName); sharedVariable?.SetValue(value); } #if UNITY_EDITOR public static T LoadFromFolder(string folderPath, string name, string extension) where T : Object { var fullPath = System.IO.Path.Combine(folderPath, name + extension); var t = AssetDatabase.LoadAssetAtPath(fullPath); return t; } #endif } }