데이터 파이프라인 개선 및 포탈 로직 생성
csv import 시 자동으로 완전한 프리팹이 생성될 수 있도록 함.
This commit is contained in:
180
Assets/Scripts/Editor/TemplateCreator.cs
Normal file
180
Assets/Scripts/Editor/TemplateCreator.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using Unity.Netcode;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
public class TemplateCreator
|
||||
{
|
||||
private const string TEMPLATE_BASE_PATH = "Assets/Data/Templates";
|
||||
|
||||
[MenuItem("Tools/Data/Create Monster Template")]
|
||||
public static void CreateMonsterTemplate()
|
||||
{
|
||||
CreateTemplate("Monster", SetupMonsterComponents);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Data/Create Tower Template")]
|
||||
public static void CreateTowerTemplate()
|
||||
{
|
||||
CreateTemplate("Tower", SetupTowerComponents);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Data/Create Player Template")]
|
||||
public static void CreatePlayerTemplate()
|
||||
{
|
||||
CreateTemplate("Player", SetupPlayerComponents);
|
||||
}
|
||||
|
||||
private static void CreateTemplate(string typeName, System.Action<GameObject> setupComponents)
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder(TEMPLATE_BASE_PATH))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(Application.dataPath + "/Data/Templates");
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
string templateName = $"{typeName}Template";
|
||||
string templatePath = $"{TEMPLATE_BASE_PATH}/{templateName}.prefab";
|
||||
|
||||
GameObject templateGO = new GameObject(templateName);
|
||||
|
||||
setupComponents(templateGO);
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(templateGO, templatePath);
|
||||
GameObject.DestroyImmediate(templateGO);
|
||||
|
||||
Debug.Log($"[TemplateCreator] Created template: {templatePath}");
|
||||
AssetDatabase.Refresh();
|
||||
Selection.activeObject = AssetDatabase.LoadAssetAtPath<GameObject>(templatePath);
|
||||
}
|
||||
|
||||
private static void SetupMonsterComponents(GameObject go)
|
||||
{
|
||||
Transform t = go.transform;
|
||||
t.localPosition = Vector3.zero;
|
||||
t.localRotation = Quaternion.identity;
|
||||
t.localScale = Vector3.one;
|
||||
|
||||
if (go.GetComponent<CapsuleCollider>() == null)
|
||||
{
|
||||
CapsuleCollider collider = go.AddComponent<CapsuleCollider>();
|
||||
collider.isTrigger = false;
|
||||
collider.radius = 0.5f;
|
||||
collider.height = 2f;
|
||||
collider.direction = 1;
|
||||
collider.center = Vector3.zero;
|
||||
}
|
||||
|
||||
if (go.GetComponent<Animator>() == null)
|
||||
{
|
||||
Animator animator = go.AddComponent<Animator>();
|
||||
animator.runtimeAnimatorController = null;
|
||||
animator.avatar = null;
|
||||
animator.applyRootMotion = false;
|
||||
animator.updateMode = AnimatorUpdateMode.Normal;
|
||||
animator.cullingMode = AnimatorCullingMode.CullUpdateTransforms;
|
||||
}
|
||||
|
||||
if (go.GetComponent<NetworkObject>() == null)
|
||||
go.AddComponent<NetworkObject>();
|
||||
|
||||
if (go.GetComponent<EnemyUnit>() == null)
|
||||
go.AddComponent<EnemyUnit>();
|
||||
|
||||
if (go.GetComponent<MonsterDataComponent>() == null)
|
||||
go.AddComponent<MonsterDataComponent>();
|
||||
|
||||
if (go.GetComponent<NavMeshAgent>() == null)
|
||||
{
|
||||
NavMeshAgent agent = go.AddComponent<NavMeshAgent>();
|
||||
agent.speed = 2.6f;
|
||||
agent.angularSpeed = 120f;
|
||||
agent.acceleration = 8f;
|
||||
agent.stoppingDistance = 0f;
|
||||
agent.autoBraking = true;
|
||||
agent.radius = 0.5f;
|
||||
agent.height = 2f;
|
||||
}
|
||||
|
||||
if (go.GetComponent<EnemyAIController>() == null)
|
||||
{
|
||||
EnemyAIController ai = go.AddComponent<EnemyAIController>();
|
||||
ai.aiType = TeamType.Monster;
|
||||
ai.detectionRange = 6f;
|
||||
ai.detectionAngle = 360f;
|
||||
ai.maxChaseDistance = 30f;
|
||||
ai.attackRange = 1f;
|
||||
ai.attackInterval = 1.2f;
|
||||
ai.attackDamage = 3;
|
||||
ai.moveSpeed = 2.6f;
|
||||
ai.chaseSpeedMultiplier = 1.2f;
|
||||
}
|
||||
|
||||
MeshFilter meshFilter = go.GetComponent<MeshFilter>();
|
||||
if (meshFilter == null)
|
||||
meshFilter = go.AddComponent<MeshFilter>();
|
||||
|
||||
MeshRenderer meshRenderer = go.GetComponent<MeshRenderer>();
|
||||
if (meshRenderer == null)
|
||||
meshRenderer = go.AddComponent<MeshRenderer>();
|
||||
|
||||
int monsterLayer = LayerMask.NameToLayer("Monster");
|
||||
if (monsterLayer >= 0)
|
||||
{
|
||||
go.layer = monsterLayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
go.layer = 0;
|
||||
}
|
||||
|
||||
NetworkObject netObj = go.GetComponent<NetworkObject>();
|
||||
if (netObj != null)
|
||||
{
|
||||
netObj.SynchronizeTransform = true;
|
||||
netObj.SpawnWithObservers = true;
|
||||
netObj.AlwaysReplicateAsRoot = false;
|
||||
}
|
||||
|
||||
EnemyUnit enemyUnit = go.GetComponent<EnemyUnit>();
|
||||
if (enemyUnit != null)
|
||||
{
|
||||
enemyUnit.enemyTeam = TeamType.Monster;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupTowerComponents(GameObject go)
|
||||
{
|
||||
if (go.GetComponent<NetworkObject>() == null)
|
||||
go.AddComponent<NetworkObject>();
|
||||
|
||||
int defaultLayer = LayerMask.NameToLayer("Default");
|
||||
if (defaultLayer >= 0)
|
||||
{
|
||||
go.layer = defaultLayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
go.layer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupPlayerComponents(GameObject go)
|
||||
{
|
||||
if (go.GetComponent<NetworkObject>() == null)
|
||||
go.AddComponent<NetworkObject>();
|
||||
|
||||
int playerLayer = LayerMask.NameToLayer("Player");
|
||||
if (playerLayer >= 0)
|
||||
{
|
||||
go.layer = playerLayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
go.layer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user