몬스터용 데이터파이프라인 개선

애니메이션 컨트롤러 및 모델 설정 기능 추가
몬스터용 애니메이션 컨트롤러 생성
This commit is contained in:
2026-02-01 01:42:45 +09:00
parent 2593b6dd37
commit 5d0ed26578
29 changed files with 8634 additions and 8286 deletions

1
.gitignore vendored
View File

@@ -12,3 +12,4 @@
.vscode .vscode
Assets/_Recovery Assets/_Recovery
Assets/_Recovery.meta Assets/_Recovery.meta
GameData/Backups

View File

@@ -87,6 +87,7 @@
<Compile Include="Assets\Scripts\PlayerSpawnPoint.cs" /> <Compile Include="Assets\Scripts\PlayerSpawnPoint.cs" />
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\AutoLoadPipelineAsset.cs" /> <Compile Include="Assets\FlatKit\Demos\Common\Scripts\AutoLoadPipelineAsset.cs" />
<Compile Include="Assets\Scripts\AutoHost.cs" /> <Compile Include="Assets\Scripts\AutoHost.cs" />
<Compile Include="Assets\Scripts\MonsterAnimationController.cs" />
<Compile Include="Assets\Scripts\IVisionProvider.cs" /> <Compile Include="Assets\Scripts\IVisionProvider.cs" />
<Compile Include="Assets\Scripts\BuildingManager.cs" /> <Compile Include="Assets\Scripts\BuildingManager.cs" />
<Compile Include="Assets\Scripts\GhostMaterialTest.cs" /> <Compile Include="Assets\Scripts\GhostMaterialTest.cs" />

View File

@@ -0,0 +1,199 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!206 &-8765139288254573871
BlendTree:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Blend Tree
m_Childs:
- serializedVersion: 2
m_Motion: {fileID: 345275505875579249, guid: 2632f2cc035d62d41bca411a318fbe36, type: 3}
m_Threshold: 0
m_Position: {x: 0, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: MoveSpeed
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: -1640158340307531623, guid: e9bbf9eb253a2004aabc86fe90014c06, type: 3}
m_Threshold: 1
m_Position: {x: 0, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: MoveSpeed
m_Mirror: 0
m_BlendParameter: Speed
m_BlendParameterY: MoveSpeed
m_MinThreshold: 0
m_MaxThreshold: 1
m_UseAutomaticThresholds: 1
m_NormalizedBlendValues: 0
m_BlendType: 0
--- !u!1101 &-4801692629233737027
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 2543178704363584614}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: MonsterAnimationController
serializedVersion: 5
m_AnimatorParameters:
- m_Name: IsMoving
m_Type: 4
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
- m_Name: Attack
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
- m_Name: Speed
m_Type: 1
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: 7310025410107308077}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!1102 &812012611541870031
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Attack
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: -4801692629233737027}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 5005478036900451222, guid: bbfa9cc7ae2f16448b3adb4300f439e9, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &1407797717177975804
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: Attack
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 812012611541870031}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 0
--- !u!1102 &2543178704363584614
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Locomotion
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -8765139288254573871}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1107 &7310025410107308077
AnimatorStateMachine:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: 812012611541870031}
m_Position: {x: 390, y: -20, z: 0}
- serializedVersion: 1
m_State: {fileID: 2543178704363584614}
m_Position: {x: 390, y: 120, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions:
- {fileID: 1407797717177975804}
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 60, y: -10, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 710, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 2543178704363584614}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0a6254dd97e2e8a47ab5cd5c1a629717
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -19,6 +19,7 @@ MonoBehaviour:
atkRange: 1 atkRange: 1
atkDamage: 3 atkDamage: 3
atkIntervalSec: 1.2 atkIntervalSec: 1.2
meshPath: Assets/Meshes/Skeleton_Minion.fbx
cost: 1 cost: 1
weight: 1 weight: 1
modelPath: Assets/Models/Skeleton_Minion.fbx
animationControllerPath: Assets/Animations/PlayerAnimationController.controller

View File

@@ -19,6 +19,7 @@ MonoBehaviour:
atkRange: 1 atkRange: 1
atkDamage: 2 atkDamage: 2
atkIntervalSec: 1 atkIntervalSec: 1
meshPath: Assets/Meshes/Skeleton_Minion.fbx
cost: 2 cost: 2
weight: 0.5 weight: 0.5
modelPath: Assets/Models/Skeleton_Minion.fbx
animationControllerPath: Assets/Animations/PlayerAnimationController.controller

View File

@@ -19,6 +19,7 @@ MonoBehaviour:
atkRange: 1 atkRange: 1
atkDamage: 4 atkDamage: 4
atkIntervalSec: 1.5 atkIntervalSec: 1.5
meshPath: Assets/Meshes/Skeleton_Minion.fbx
cost: 5 cost: 5
weight: 0.2 weight: 0.2
modelPath: Assets/Models/Skeleton_Minion.fbx
animationControllerPath: Assets/Animations/PlayerAnimationController.controller

View File

@@ -19,6 +19,7 @@ MonoBehaviour:
atkRange: 5 atkRange: 5
atkDamage: 2 atkDamage: 2
atkIntervalSec: 1.4 atkIntervalSec: 1.4
meshPath: Assets/Meshes/Skeleton_Minion.fbx
cost: 3 cost: 3
weight: 0.333 weight: 0.333
modelPath: Assets/Models/Skeleton_Minion.fbx
animationControllerPath: Assets/Animations/PlayerAnimationController.controller

View File

@@ -19,6 +19,7 @@ MonoBehaviour:
atkRange: 1 atkRange: 1
atkDamage: 7 atkDamage: 7
atkIntervalSec: 1.3 atkIntervalSec: 1.3
meshPath: Assets/Meshes/Skeleton_Minion.fbx
cost: 10 cost: 10
weight: 0.1 weight: 0.1
modelPath: Assets/Models/Skeleton_Minion.fbx
animationControllerPath: Assets/Animations/PlayerAnimationController.controller

View File

@@ -24,14 +24,14 @@ namespace Northbound.Data
public int atkDamage; public int atkDamage;
/// <summary>공격 주기</summary> /// <summary>공격 주기</summary>
public float atkIntervalSec; public float atkIntervalSec;
/// <summary>메시 경로</summary>
public string meshPath;
/// <summary>애니메이터 컨트롤러 경로</summary>
public string animatorControllerPath;
/// <summary>몬스터 난이도 점수</summary> /// <summary>몬스터 난이도 점수</summary>
public int cost; public int cost;
/// <summary>등장 가중치</summary> /// <summary>등장 가중치</summary>
public float weight; public float weight;
/// <summary>사용할 모델의 경로</summary>
public string modelPath;
/// <summary>사용할 애니메이션 컨트롤러의 경로</summary>
public string animationControllerPath;
} }
} }

View File

@@ -15,8 +15,8 @@ GameObject:
- component: {fileID: 4485945348237935463} - component: {fileID: 4485945348237935463}
- component: {fileID: 3318886927439461238} - component: {fileID: 3318886927439461238}
- component: {fileID: 3710510283885710978} - component: {fileID: 3710510283885710978}
- component: {fileID: 8707976825772989039} - component: {fileID: 6023907831447366429}
- component: {fileID: 305627289932973437} - component: {fileID: 8728041163683826261}
m_Layer: 11 m_Layer: 11
m_Name: MonsterTemplate m_Name: MonsterTemplate
m_TagString: Untagged m_TagString: Untagged
@@ -61,7 +61,7 @@ CapsuleCollider:
m_Radius: 0.5 m_Radius: 0.5
m_Height: 2 m_Height: 2
m_Direction: 1 m_Direction: 1
m_Center: {x: 0, y: 0, z: 0} m_Center: {x: 0, y: 1, z: 0}
--- !u!114 &876002834352819743 --- !u!114 &876002834352819743
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -74,7 +74,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
GlobalObjectIdHash: 949228241 GlobalObjectIdHash: 209349728
InScenePlacedSourceGlobalObjectIdHash: 0 InScenePlacedSourceGlobalObjectIdHash: 0
DeferredDespawnTick: 0 DeferredDespawnTick: 0
Ownership: 1 Ownership: 1
@@ -170,60 +170,43 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.MonsterDataComponent m_EditorClassIdentifier: Assembly-CSharp::Northbound.MonsterDataComponent
monsterData: {fileID: 0} monsterData: {fileID: 0}
autoApplyOnAwake: 1 autoApplyOnAwake: 1
--- !u!33 &8707976825772989039 --- !u!95 &6023907831447366429
MeshFilter: Animator:
m_ObjectHideFlags: 0 serializedVersion: 7
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3810918154428190126}
m_Mesh: {fileID: 0}
--- !u!23 &305627289932973437
MeshRenderer:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3810918154428190126} m_GameObject: {fileID: 3810918154428190126}
m_Enabled: 1 m_Enabled: 1
m_CastShadows: 1 m_Avatar: {fileID: 0}
m_ReceiveShadows: 1 m_Controller: {fileID: 9100000, guid: 0a6254dd97e2e8a47ab5cd5c1a629717, type: 2}
m_DynamicOccludee: 1 m_CullingMode: 0
m_StaticShadowCaster: 0 m_UpdateMode: 0
m_MotionVectors: 1 m_ApplyRootMotion: 0
m_LightProbeUsage: 1 m_LinearVelocityBlending: 0
m_ReflectionProbeUsage: 1 m_StabilizeFeet: 0
m_RayTracingMode: 2 m_AnimatePhysics: 0
m_RayTraceProcedural: 0 m_WarningMessage:
m_RayTracingAccelStructBuildFlagsOverride: 0 m_HasTransformHierarchy: 1
m_RayTracingAccelStructBuildFlags: 1 m_AllowConstantClipSamplingOptimization: 1
m_SmallMeshCulling: 1 m_KeepAnimatorStateOnDisable: 0
m_ForceMeshLod: -1 m_WriteDefaultValuesOnDisable: 0
m_MeshLodSelectionBias: 0 --- !u!114 &8728041163683826261
m_RenderingLayerMask: 1 MonoBehaviour:
m_RendererPriority: 0 m_ObjectHideFlags: 0
m_Materials: m_CorrespondingSourceObject: {fileID: 0}
- {fileID: 0} m_PrefabInstance: {fileID: 0}
m_StaticBatchInfo: m_PrefabAsset: {fileID: 0}
firstSubMesh: 0 m_GameObject: {fileID: 3810918154428190126}
subMeshCount: 0 m_Enabled: 1
m_StaticBatchRoot: {fileID: 0} m_EditorHideFlags: 0
m_ProbeAnchor: {fileID: 0} m_Script: {fileID: 11500000, guid: 2b2a547d86f65d64a93a7a3c415d1ce2, type: 3}
m_LightProbeVolumeOverride: {fileID: 0} m_Name:
m_ScaleInLightmap: 1 m_EditorClassIdentifier: Assembly-CSharp::Northbound.MonsterAnimationController
m_ReceiveGI: 1 ShowTopMostFoldoutHeaderGroup: 1
m_PreserveUVs: 0 speedParam: Speed
m_IgnoreNormalsForChartDetection: 0 attackTriggerParam: Attack
m_ImportantGI: 0 isMovingParam: IsMoving
m_StitchLightmapSeams: 1 autoLoadFromMonsterData: 1
m_SelectedEditorRenderState: 3 debugLogging: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}

View File

@@ -75,27 +75,27 @@ MonoBehaviour:
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0 - Override: 0
Prefab: {fileID: 5764052602947399654, guid: eccdace7a7b21a446891da5739b1549f, type: 3} Prefab: {fileID: 7146441246397375875, guid: eccdace7a7b21a446891da5739b1549f, type: 3}
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0 - Override: 0
Prefab: {fileID: 8497750939283614707, guid: 4ee9b364dfe9d0949a23374e660d3e13, type: 3} Prefab: {fileID: 9065146123892903723, guid: 4ee9b364dfe9d0949a23374e660d3e13, type: 3}
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0 - Override: 0
Prefab: {fileID: 7862005309935152867, guid: 9cac250ebe8d420469bd4da3ab8cfd86, type: 3} Prefab: {fileID: 2347008446492047424, guid: 9cac250ebe8d420469bd4da3ab8cfd86, type: 3}
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0 - Override: 0
Prefab: {fileID: 4357115039351603180, guid: ff2924ffa397a8e44925625790831d25, type: 3} Prefab: {fileID: 4973514444862586119, guid: ff2924ffa397a8e44925625790831d25, type: 3}
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0 - Override: 0
Prefab: {fileID: 4147164034265547914, guid: e8d09b814275ad745a427433c28dd53f, type: 3} Prefab: {fileID: 5710477988932221578, guid: e8d09b814275ad745a427433c28dd53f, type: 3}
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -291,6 +291,75 @@ Transform:
m_CorrespondingSourceObject: {fileID: 5749230937810543840, guid: 88f7f1e8a019b674498ab5fd494c1d34, type: 3} m_CorrespondingSourceObject: {fileID: 5749230937810543840, guid: 88f7f1e8a019b674498ab5fd494c1d34, type: 3}
m_PrefabInstance: {fileID: 97216554} m_PrefabInstance: {fileID: 97216554}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!1001 &262141280
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalPosition.x
value: -13.821813
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalPosition.y
value: 1.0000176
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalPosition.z
value: -79.981514
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 330216587035606633, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1862252567762920688, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_Controller
value:
objectReference: {fileID: 9100000, guid: 0a6254dd97e2e8a47ab5cd5c1a629717, type: 2}
- target: {fileID: 4973514444862586119, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: m_Name
value: Monster104
objectReference: {fileID: 0}
- target: {fileID: 6792128439220764867, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: GlobalObjectIdHash
value: 25366073
objectReference: {fileID: 0}
- target: {fileID: 6792128439220764867, guid: ff2924ffa397a8e44925625790831d25, type: 3}
propertyPath: InScenePlacedSourceGlobalObjectIdHash
value: 2094204011
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ff2924ffa397a8e44925625790831d25, type: 3}
--- !u!1 &306979656 --- !u!1 &306979656
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -3841,3 +3910,4 @@ SceneRoots:
- {fileID: 6883440760007776145} - {fileID: 6883440760007776145}
- {fileID: 816886532} - {fileID: 816886532}
- {fileID: 5107842} - {fileID: 5107842}
- {fileID: 262141280}

View File

@@ -26,13 +26,20 @@ namespace Northbound.Editor
monsterDataComponent.ApplyMonsterData(); monsterDataComponent.ApplyMonsterData();
} }
if (!string.IsNullOrEmpty(monsterData.meshPath)) var animationController = prefab.GetComponent<MonsterAnimationController>();
if (animationController == null)
{
animationController = prefab.AddComponent<MonsterAnimationController>();
Debug.Log($"[MonsterPrefabSetup] Added MonsterAnimationController component");
}
if (!string.IsNullOrEmpty(monsterData.modelPath))
{ {
RemoveOldModel(prefab); RemoveOldModel(prefab);
if (monsterData.meshPath.ToLower().EndsWith(".fbx")) if (monsterData.modelPath.ToLower().EndsWith(".fbx"))
{ {
GameObject fbxModel = AssetDatabase.LoadAssetAtPath<GameObject>(monsterData.meshPath); GameObject fbxModel = AssetDatabase.LoadAssetAtPath<GameObject>(monsterData.modelPath);
if (fbxModel != null) if (fbxModel != null)
{ {
GameObject fbxInstance = GameObject.Instantiate(fbxModel); GameObject fbxInstance = GameObject.Instantiate(fbxModel);
@@ -42,11 +49,23 @@ namespace Northbound.Editor
fbxInstance.transform.localRotation = Quaternion.identity; fbxInstance.transform.localRotation = Quaternion.identity;
fbxInstance.transform.localScale = Vector3.one; fbxInstance.transform.localScale = Vector3.one;
Debug.Log($"[MonsterPrefabSetup] Applied FBX model: {monsterData.meshPath}"); Debug.Log($"[MonsterPrefabSetup] Applied FBX model: {monsterData.modelPath}");
Avatar modelAvatar = fbxModel.GetComponent<Animator>()?.avatar;
if (modelAvatar != null)
{
Animator prefabAnimator = prefab.GetComponent<Animator>();
if (prefabAnimator != null)
{
prefabAnimator.avatar = modelAvatar;
Debug.Log($"[MonsterPrefabSetup] Applied Avatar: {modelAvatar.name}");
}
}
} }
else else
{ {
Debug.LogWarning($"[MonsterPrefabSetup] Could not load FBX model: {monsterData.meshPath}"); Debug.LogWarning($"[MonsterPrefabSetup] Could not load FBX model: {monsterData.modelPath}");
} }
} }
else else
@@ -54,34 +73,34 @@ namespace Northbound.Editor
var meshFilter = prefab.GetComponent<MeshFilter>(); var meshFilter = prefab.GetComponent<MeshFilter>();
if (meshFilter != null) if (meshFilter != null)
{ {
Mesh mesh = AssetDatabase.LoadAssetAtPath<Mesh>(monsterData.meshPath); Mesh mesh = AssetDatabase.LoadAssetAtPath<Mesh>(monsterData.modelPath);
if (mesh != null) if (mesh != null)
{ {
meshFilter.sharedMesh = mesh; meshFilter.sharedMesh = mesh;
Debug.Log($"[MonsterPrefabSetup] Applied mesh: {monsterData.meshPath}"); Debug.Log($"[MonsterPrefabSetup] Applied mesh: {monsterData.modelPath}");
} }
else else
{ {
Debug.LogWarning($"[MonsterPrefabSetup] Could not load mesh: {monsterData.meshPath}"); Debug.LogWarning($"[MonsterPrefabSetup] Could not load mesh: {monsterData.modelPath}");
} }
} }
} }
} }
if (!string.IsNullOrEmpty(monsterData.animatorControllerPath)) if (!string.IsNullOrEmpty(monsterData.animationControllerPath))
{ {
Animator animator = prefab.GetComponent<Animator>(); Animator animator = prefab.GetComponent<Animator>();
if (animator != null) if (animator != null)
{ {
RuntimeAnimatorController controller = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(monsterData.animatorControllerPath); RuntimeAnimatorController controller = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(monsterData.animationControllerPath);
if (controller != null) if (controller != null)
{ {
animator.runtimeAnimatorController = controller; animator.runtimeAnimatorController = controller;
Debug.Log($"[MonsterPrefabSetup] Applied Animator Controller: {monsterData.animatorControllerPath}"); Debug.Log($"[MonsterPrefabSetup] Applied Animator Controller: {monsterData.animationControllerPath}");
} }
else else
{ {
Debug.LogWarning($"[MonsterPrefabSetup] Could not load Animator Controller: {monsterData.animatorControllerPath}"); Debug.LogWarning($"[MonsterPrefabSetup] Could not load Animator Controller: {monsterData.animationControllerPath}");
} }
} }
} }

View File

@@ -58,6 +58,9 @@ namespace Northbound
[Tooltip("디버그 정보 표시")] [Tooltip("디버그 정보 표시")]
public bool showDebugInfo = true; public bool showDebugInfo = true;
[Header("Events")]
public System.Action<GameObject> OnAttackPerformed;
private NavMeshAgent _agent; private NavMeshAgent _agent;
private EnemyUnit _enemyUnit; private EnemyUnit _enemyUnit;
private Transform _coreTransform; private Transform _coreTransform;
@@ -390,6 +393,8 @@ namespace Northbound
damageable.TakeDamage(attackDamage, NetworkObjectId); damageable.TakeDamage(attackDamage, NetworkObjectId);
_lastAttackTime = Time.time; _lastAttackTime = Time.time;
OnAttackPerformed?.Invoke(target);
if (showDebugInfo) if (showDebugInfo)
Debug.Log($"<color=red>[EnemyAI] {gameObject.name} -> {target.name} 타격 성공! (데미지: {attackDamage})</color>"); Debug.Log($"<color=red>[EnemyAI] {gameObject.name} -> {target.name} 타격 성공! (데미지: {attackDamage})</color>");
} }
@@ -502,6 +507,15 @@ namespace Northbound
#endregion #endregion
#region Public API
public EnemyAIState GetCurrentState()
{
return _currentState.Value;
}
#endregion
#region Gizmos ( ) #region Gizmos ( )
private void OnDrawGizmos() private void OnDrawGizmos()
{ {

View File

@@ -0,0 +1,148 @@
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
namespace Northbound
{
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(EnemyAIController))]
public class MonsterAnimationController : NetworkBehaviour
{
[Header("Animation Parameters")]
[Tooltip("Speed parameter name in Animator")]
public string speedParam = "Speed";
[Tooltip("Attack trigger parameter name in Animator")]
public string attackTriggerParam = "Attack";
[Tooltip("IsMoving bool parameter name in Animator")]
public string isMovingParam = "IsMoving";
[Header("Settings")]
[Tooltip("Auto-load animator controller from MonsterData")]
public bool autoLoadFromMonsterData = true;
[Tooltip("Debug logging")]
public bool debugLogging = false;
private Animator _animator;
private EnemyAIController _aiController;
private NavMeshAgent _agent;
private NetworkVariable<float> _networkSpeed = new NetworkVariable<float>(
0f,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server
);
private NetworkVariable<bool> _networkIsMoving = new NetworkVariable<bool>(
false,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server
);
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
_animator = GetComponent<Animator>();
_aiController = GetComponent<EnemyAIController>();
_agent = GetComponent<NavMeshAgent>();
_aiController.OnAttackPerformed += HandleAttackPerformed;
if (autoLoadFromMonsterData)
{
LoadAnimatorController();
}
}
public override void OnNetworkDespawn()
{
if (_aiController != null)
{
_aiController.OnAttackPerformed -= HandleAttackPerformed;
}
base.OnNetworkDespawn();
}
private void HandleAttackPerformed(GameObject target)
{
if (!IsServer) return;
TriggerAttackClientRpc();
if (debugLogging)
Debug.Log($"[MonsterAnimationController] Triggered attack animation for {target.name}", this);
}
private void LoadAnimatorController()
{
var monsterDataComponent = GetComponent<MonsterDataComponent>();
if (monsterDataComponent != null && monsterDataComponent.monsterData != null)
{
string animatorPath = monsterDataComponent.monsterData.animationControllerPath;
if (!string.IsNullOrEmpty(animatorPath))
{
RuntimeAnimatorController controller = Resources.Load<RuntimeAnimatorController>(animatorPath);
if (controller != null)
{
_animator.runtimeAnimatorController = controller;
if (debugLogging)
Debug.Log($"[MonsterAnimationController] Loaded animator from {animatorPath}", this);
}
else if (debugLogging)
{
Debug.LogWarning($"[MonsterAnimationController] Could not load animator from {animatorPath}", this);
}
}
}
}
private void Update()
{
if (!IsSpawned) return;
if (IsServer)
{
UpdateServerSide();
}
UpdateClientSide();
}
private void UpdateServerSide()
{
if (_agent == null) return;
float currentSpeed = _agent.velocity.magnitude;
bool isMoving = currentSpeed > 0.1f && _agent.isOnNavMesh && !_agent.isStopped;
_networkSpeed.Value = currentSpeed;
_networkIsMoving.Value = isMoving;
}
private void UpdateClientSide()
{
if (_animator == null) return;
_animator.SetFloat(speedParam, _networkSpeed.Value);
_animator.SetBool(isMovingParam, _networkIsMoving.Value);
}
[Rpc(SendTo.ClientsAndHost)]
private void TriggerAttackClientRpc()
{
if (_animator != null)
{
_animator.SetTrigger(attackTriggerParam);
}
}
public void ResetAttackTrigger()
{
if (_animator != null)
{
_animator.ResetTrigger(attackTriggerParam);
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2b2a547d86f65d64a93a7a3c415d1ce2

View File

@@ -41,12 +41,6 @@
"condition": null, "condition": null,
"description": "공격 주기" "description": "공격 주기"
}, },
{
"name": "prefab_path",
"type": "string",
"condition": null,
"description": "프리팹/리소스 경로"
},
{ {
"name": "cost", "name": "cost",
"type": "int", "type": "int",
@@ -58,5 +52,17 @@
"type": "float", "type": "float",
"condition": null, "condition": null,
"description": "등장 가중치" "description": "등장 가중치"
},
{
"name": "model_path",
"type": "string",
"condition": null,
"description": "사용할 모델의 경로"
},
{
"name": "animation_controller_path",
"type": "string",
"condition": null,
"description": "사용할 애니메이션 컨트롤러의 경로"
} }
] ]

View File

@@ -1,6 +1,6 @@
id,memo,move_speed,max_hp,atk_range,atk_damage,atk_interval_sec,prefab_path,cost,weight,mesh_path id,memo,move_speed,max_hp,atk_range,atk_damage,atk_interval_sec,cost,weight,model_path,animation_controller_path
101,Grunt(기본),2.6,30,1,3,1.2,Assets/Prefabs/EnemyTest,1,1.0,Assets/Meshes/Skeleton_Minion.fbx 101,Grunt(기본),2.6,30,1,3,1.2,1,1.0,Assets/Models/Skeleton_Minion.fbx,Assets/Animations/PlayerAnimationController.controller
102,Fast(빠름/약함),3.4,18,1,2,1.0,Assets/Prefabs/MonsterTest,2,0.5,Assets/Meshes/Skeleton_Minion.fbx 102,Fast(빠름/약함),3.4,18,1,2,1.0,2,0.5,Assets/Models/Skeleton_Minion.fbx,Assets/Animations/PlayerAnimationController.controller
103,Tank(느림/단단),2.0,70,1,4,1.5,Assets/Prefabs/Core,5,0.2,Assets/Meshes/Skeleton_Minion.fbx 103,Tank(느림/단단),2.0,70,1,4,1.5,5,0.2,Assets/Models/Skeleton_Minion.fbx,Assets/Animations/PlayerAnimationController.controller
104,Ranged(원거리/약함),2.4,22,5,2,1.4,Assets/Prefabs/Resource,3,0.333,Assets/Meshes/Skeleton_Minion.fbx 104,Ranged(원거리/약함),2.4,22,5,2,1.4,3,0.333,Assets/Models/Skeleton_Minion.fbx,Assets/Animations/PlayerAnimationController.controller
105,Elite(소수 정예),2.8,120,1,7,1.3,Assets/Prefabs/ResourcePickup,10,0.1,Assets/Meshes/Skeleton_Minion.fbx 105,Elite(소수 정예),2.8,120,1,7,1.3,10,0.1,Assets/Models/Skeleton_Minion.fbx,Assets/Animations/PlayerAnimationController.controller
1 id memo move_speed max_hp atk_range atk_damage atk_interval_sec prefab_path cost weight model_path mesh_path animation_controller_path
2 101 Grunt(기본) 2.6 30 1 3 1.2 Assets/Prefabs/EnemyTest 1 1.0 Assets/Models/Skeleton_Minion.fbx Assets/Meshes/Skeleton_Minion.fbx Assets/Animations/PlayerAnimationController.controller
3 102 Fast(빠름/약함) 3.4 18 1 2 1.0 Assets/Prefabs/MonsterTest 2 0.5 Assets/Models/Skeleton_Minion.fbx Assets/Meshes/Skeleton_Minion.fbx Assets/Animations/PlayerAnimationController.controller
4 103 Tank(느림/단단) 2.0 70 1 4 1.5 Assets/Prefabs/Core 5 0.2 Assets/Models/Skeleton_Minion.fbx Assets/Meshes/Skeleton_Minion.fbx Assets/Animations/PlayerAnimationController.controller
5 104 Ranged(원거리/약함) 2.4 22 5 2 1.4 Assets/Prefabs/Resource 3 0.333 Assets/Models/Skeleton_Minion.fbx Assets/Meshes/Skeleton_Minion.fbx Assets/Animations/PlayerAnimationController.controller
6 105 Elite(소수 정예) 2.8 120 1 7 1.3 Assets/Prefabs/ResourcePickup 10 0.1 Assets/Models/Skeleton_Minion.fbx Assets/Meshes/Skeleton_Minion.fbx Assets/Animations/PlayerAnimationController.controller