feat: 전투 공간 개편 및 카메라·캐릭터 품질 개선

[전투 공간]
- 단순 Plane 바닥 → Arena 계층 구조로 교체 (Floor, 벽 4개, Objects)
- PolygonDarkFortress 외부 에셋 임포트 (전투 공간 디자인 적용)
- 바닥 아래 검은 평면(FloorBase) 추가로 카메라 저각도 시 허공 노출 방지
- NavMesh 리베이크

[카메라]
- PlayerCamera에 SphereCast 기반 지형 충돌 감지 추가
- 카메라가 바닥 아래를 비출 때 최소 높이 보장

[캐릭터]
- 플레이어 CharacterController skinWidth 정상화 (0.0001 → 0.03)
- 보스 NavMeshAgent baseOffset 조정으로 발 파묻힘 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 19:59:04 +09:00
parent ec40b397b5
commit d39e13f032
5538 changed files with 2426799 additions and 125 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 04c79e28ae9b7994cb533011cd553d3c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BlackBase
m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats: []
m_Colors:
- _Color: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

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

View File

@@ -1949,7 +1949,7 @@ Transform:
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 2, y: 2, z: 2}
m_LocalScale: {x: 3, y: 3, z: 3}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 8242298026093095983}
@@ -2000,7 +2000,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
GlobalObjectIdHash: 1928582172
GlobalObjectIdHash: 860882280
InScenePlacedSourceGlobalObjectIdHash: 223369646
DeferredDespawnTick: 0
Ownership: 1

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9056ed50420273a4db85e789ee425c27
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,317 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &5940746375942102803
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1170778968920440458}
- component: {fileID: 3821143641133970193}
- component: {fileID: 2222132470815002763}
m_Layer: 0
m_Name: Point Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1170778968920440458
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5940746375942102803}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 9198191638700597494}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!108 &3821143641133970193
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5940746375942102803}
m_Enabled: 1
serializedVersion: 12
m_Type: 2
m_Color: {r: 1, g: 0.4980392, b: 0.3137255, a: 1}
m_Intensity: 100
m_Range: 20
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize2D: {x: 0.5, y: 0.5}
m_Shadows:
m_Type: 0
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 0
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ForceVisible: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!114 &2222132470815002763
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5940746375942102803}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!1001 &7222635089473302044
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 9198191638700597494}
m_Modifications:
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalScale.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalScale.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalScale.z
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalPosition.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3023045017317756691, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
propertyPath: m_Name
value: FX_Fire_01
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
--- !u!4 &8082019560467087820 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 1446479704125452240, guid: a4a1daf7a6de48e5a54b302437a74d1d, type: 3}
m_PrefabInstance: {fileID: 7222635089473302044}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &8659353301458536221
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalScale.x
value: 5
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalScale.y
value: 5
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalScale.z
value: 5
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -7511558181221131132, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: 'm_Materials.Array.data[0]'
value:
objectReference: {fileID: 2100000, guid: 3c5daeadc1128f649923562e4f21fa05, type: 2}
- target: {fileID: 919132149155446097, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
propertyPath: m_Name
value: SM_Prop_Torch_07
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects:
- targetCorrespondingSourceObject: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
insertIndex: -1
addedObject: {fileID: 8082019560467087820}
- targetCorrespondingSourceObject: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
insertIndex: -1
addedObject: {fileID: 1170778968920440458}
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
insertIndex: -1
addedObject: {fileID: 3488818035724147037}
m_SourcePrefab: {fileID: 100100000, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
--- !u!1 &8425489584955587148 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
m_PrefabInstance: {fileID: 8659353301458536221}
m_PrefabAsset: {fileID: 0}
--- !u!64 &3488818035724147037
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8425489584955587148}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 5
m_Convex: 1
m_CookingOptions: 30
m_Mesh: {fileID: 1287522369331218236, guid: 9b8f6adf78e68db4794d03c7de10d711, type: 2}
--- !u!4 &9198191638700597494 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: eef63ee37ee099543a05ac9e7cf0580d, type: 3}
m_PrefabInstance: {fileID: 8659353301458536221}
m_PrefabAsset: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 168b06aeec718644085963f36fdee117
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -69,7 +69,7 @@ CharacterController:
m_Radius: 0.3
m_SlopeLimit: 45
m_StepOffset: 0.3
m_SkinWidth: 0.0001
m_SkinWidth: 0.03
m_MinMoveDistance: 0.001
m_Center: {x: 0, y: 1, z: 0}
--- !u!136 &7641562851946724729

View File

@@ -16,6 +16,11 @@ namespace Colosseum.Player
[SerializeField] private float minPitch = -30f;
[SerializeField] private float maxPitch = 60f;
[Header("Collision")]
[SerializeField] private float collisionRadius = 0.2f;
[SerializeField] private LayerMask collisionMask = ~0; // 기본: 모든 레이어
[SerializeField] private float minHeightAboveGround = 0.3f; // 바닥 위 최소 카메라 높이
private Transform target;
private float yaw;
private float pitch;
@@ -104,12 +109,7 @@ namespace Colosseum.Player
{
if (target == null || cameraInstance == null) return;
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0f);
Vector3 offset = rotation * new Vector3(0f, 0f, -distance);
offset.y += height;
cameraInstance.transform.position = target.position + offset;
cameraInstance.transform.LookAt(target.position + Vector3.up * height * 0.5f);
UpdateCameraPosition();
}
/// <summary>
@@ -156,8 +156,28 @@ namespace Colosseum.Player
Vector3 offset = rotation * new Vector3(0f, 0f, -distance);
offset.y += height;
cameraInstance.transform.position = target.position + offset;
cameraInstance.transform.LookAt(target.position + Vector3.up * height * 0.5f);
Vector3 pivot = target.position + Vector3.up * height * 0.5f;
Vector3 desiredPos = target.position + offset;
// pivot → desiredPos 방향으로 SphereCast해서 지형 충돌 감지
Vector3 dir = desiredPos - pivot;
float maxDist = dir.magnitude;
if (Physics.SphereCast(pivot, collisionRadius, dir.normalized, out RaycastHit hit, maxDist, collisionMask, QueryTriggerInteraction.Ignore))
{
// 충돌 지점에서 collisionRadius만큼 pivot 쪽으로 당김
desiredPos = hit.point + dir.normalized * collisionRadius;
}
// 카메라 아래에 지면이 너무 가까우면 위로 밀어올려 바닥 아래면이 보이지 않게 함
if (Physics.Raycast(desiredPos, Vector3.down, out RaycastHit groundHit, minHeightAboveGround + 1f, collisionMask, QueryTriggerInteraction.Ignore))
{
float groundY = groundHit.point.y + minHeightAboveGround;
if (desiredPos.y < groundY)
desiredPos.y = groundY;
}
cameraInstance.transform.position = desiredPos;
cameraInstance.transform.LookAt(pivot);
}
}
}