Project_WL/Assets/Script/Map/MapData.cs

198 lines
9.8 KiB
C#
Raw Permalink Normal View History

using CodeStage.AntiCheat.ObscuredTypes;
2024-12-15 01:39:39 +00:00
using System;
using System.Collections.Generic;
using UnityEngine;
2025-01-25 21:04:01 +00:00
using Random = UnityEngine.Random;
2024-12-15 01:39:39 +00:00
public class MapData : MonoBehaviourSingletonTemplate<MapData>
2024-12-15 01:39:39 +00:00
{
public Material material_skybox;
public GameObject[] gos_map; // 미궁에서 사용 (여러 맵 중 하나 오픈)
2025-03-10 07:15:28 +00:00
public ChapterPortal m_ChapterPortal;
2024-12-15 01:39:39 +00:00
[SerializeField] public List<MapZoneData> m_MapZoneData;
WL 리뉴얼 세션 2026-09-06~07 (#760~#800) — 전투·배경·UI·타격감 (조직 PD 로그 #746~#800 · 대화로그 §14~§24) - 전투: Knight@Attack1~3_S 3콤보(4 컨트롤러·클래스별 서브클립) · 타겟팅 4규칙(정면 우선·재타겟·즉시 공격·어그로 금지 · WLTargetingSettings) · 대쉬 후 공격(Stander@Chase_Start · DashDriver · 5 m · 사정거리+0.8 · 근거리 적 우선) · 공격 이동 FrameTable(발 접지 실측 표 · AttackRootMotion) · 충돌 반경/투사체 0.3 배(WLCollisionTuning) · 무적(임시)·펫 금지(WLGameplaySettings) - 검기: NamuFX Slash_B 배리언트 Effect_WLSwingArc 원 피팅 정합 배치 + 캘리브레이션(SlashArcMeasure · SlashTrailSettings) · 찌르기 Effect_WLStab 대기 · 램프 리본(BladeTrail · WL_BladeRibbon.shader · T_WL_BladeRibbonRamp) 보존(drawRibbon 0) - 타격감: Assets/WL/Feel(WLHitFeel · 히트스톱 0.03 · 셰이크 0.10 m · 몹 펀치 1.12 · Actor.Get_Damage 훅 1줄 · 원본 RealCamera 셰이크 결함 대체) - 배경/맵: LMHPOLY Demo_01~10 → WL_Nature01~10(프리팹·씬·NavMesh·스포너·BattleMapConfig) · 물(ToonWaterU) · 포스트 블룸 0.9/0.3 · 잔디(BruteForce·드레싱) 제거 · 마젠타 머티리얼 URP 변환 - UI: 세로 HUD(WL_HUD · 하단 5메뉴 폭 전체 · 채팅/전투 패드 숨김 · WLIngameUiOverride) · Title/TitleInfo 1080×1920 Expand + 배경 높이 fit(WLBackgroundFit) · 로딩 SortOrder_5(WLRawImageAspectSync · 초점표 8장) · Loading1~8 ASTC 6×6 - 도구: AgentScripts/*(LightProbe · WL_MapSwitch · WL760~WL800 프로브/집행/검증 · 상단 사용법 주석) · 에디터 락 프로토콜 파일(staging) - 제외(별도 커밋 예정): Assets/LMHPOLY(703 MB) · Assets/Feel(422 MB) · Assets/Shinabro(300 MB) — 에셋 스토어/구 WL 팩 원본 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:24:25 +00:00
// 2026-09-05 #746 (배경 어두움 수정) 실측: Ingame 씬은 베이크 데이터가 없고 앰비언트 모드가 Skybox 라 런타임 앰비언트 프로브가 ≈0.04(검정)이었다.
// - 로비는 material_skybox 가 null, 필드맵은 skybox 만 바꾸고 프로브를 재생성하지 않아 #744 의 ambientIntensity 조정은 무효였다.
// - 값은 코드 상수가 아니라 맵 프리팹 필드로 둔다(C45 · 맵마다 인스펙터에서 조정). 색은 선형 값(스크립트 대입은 색공간 변환 없음).
[Header("조명 · 런타임 앰비언트 (#746 · 맵 프리팹에서 조정)")]
[Tooltip("Trilight/Flat 은 skybox 와 무관하게 즉시 적용. Skybox 모드는 material_skybox 가 있고 updateEnvironmentFromSkybox 가 켜진 경우에만 프로브가 생성된다.")]
public UnityEngine.Rendering.AmbientMode ambientMode = UnityEngine.Rendering.AmbientMode.Trilight;
// 기본값 = PD "더 밝게"(2026-09-05) 반영: 로비 실측 평균 휘도 .60/.42/.18 → 0.282, 백색 1.0/.71/.31 → 0.325. 백색 계열을 기본으로.
public Color ambientSky = new Color(1.00f, 1.00f, 1.00f, 1f);
public Color ambientEquator = new Color(0.71f, 0.58f, 0.48f, 1f);
public Color ambientGround = new Color(0.31f, 0.31f, 0.45f, 1f);
[Range(0f, 2f)] public float ambientIntensity = 1f; // Skybox 모드 전용 (Trilight/Flat 은 무시)
[Range(0f, 1f)] public float reflectionIntensity = 0.3f;
[Tooltip("Skybox 모드에서 DynamicGI.UpdateEnvironment() 를 호출해 skybox 기준 프로브를 만든다(맵 로딩 시 1회 비용).")]
public bool updateEnvironmentFromSkybox = false;
// 2026-09-06 #756: 힘민지 로비 모드는 PCActor.Set_Obj 가 무기 장착을 건너뛴다(휴식 공간 설계). 시작 맵(WL_Start)처럼
// 로비 타입이어도 무기를 보여야 하는 맵은 이 플래그를 켠다 → StartWakeSequence 가 플레이어 인식 직후 Change_Weapon() 호출.
[Header("플레이어 표시 (#756)")]
[Tooltip("로비 모드 맵에서도 플레이어 무기를 장착·표시한다 (WL_Start 등)")]
public bool showWeaponInLobby = false;
// 2026-09-06 #764 (PD: "몬스터도 플레이어가 갈 수 없는 지형을 뚫고 이동하거나 이동 불가 지형에 생성되지 않도록")
// 실측(WL_Start · 4m 격자 1806점): NavMesh 위 1144점 중 플레이어 시작 지점에서 도달 가능한 곳은 427점(37%)뿐이다.
// 기존 DSUtil.Get_RandomPos_onNavMesh 는 ① 스냅 반경으로 MobGenRange 를 그대로 써서 최대 2×range 까지 튀고
// ② NavMesh.CalculatePath 의 반환값만 보고 status(PathComplete)를 보지 않아 **부분 경로(벽 너머·다른 섬)를 통과**시킨다.
// → 스포너 19개 × 30점 표집 실측에서 51%(295/570)가 플레이어 시작 지점에서 도달 불가였다.
// 아래 값은 전부 **기본값 = 기존 동작**이라 이 값을 세팅하지 않은 기존 맵은 아무것도 바뀌지 않는다(C8).
[Header("몬스터 스폰 · 이동 (#764 · 맵 프리팹에서 조정)")]
[Tooltip("스포너가 몬스터 생성 위치를 뽑을 때 완전 경로(PathComplete)가 나오는 지점만 쓴다. " +
"WL_Start 처럼 NavMesh 가 섬으로 끊긴 맵에서 켠다. 끄면 기존 표집 방식 그대로.")]
public bool spawnRequireReachableFromPlayer = false;
[Tooltip("스폰 후보의 무작위 점을 NavMesh 로 끌어당길 최대 거리(m). 크면 벽 너머 다른 섬으로 스냅된다. " +
"0 이하면 기존 동작(MobGenRange 를 스냅 반경으로 사용). 실측 권장 = 2")]
public float spawnSnapRadius = 0f;
[Tooltip("스폰 후보 표집 재시도 횟수. 0 이하면 기존 기본값(50)을 쓴다.")]
public int spawnSampleTries = 0;
[Tooltip("몬스터가 넉백·끌어당김·점프로 NavMesh 밖으로 밀렸을 때 되돌릴 최대 거리(m). " +
"0 이하면 스냅하지 않는다(기존 동작). 몬스터에만 적용되고 플레이어·펫·NPC 는 영향이 없다.")]
public float mobNavSnapRadius = 0f;
// 2026-09-06 #771 (WL_Nature 시작 맵): 힘민지 맵은 Start() 에서 RenderSettings.fog=false 로 안개를 껐다.
// Demo_01(LMHPOLY) 처럼 원경이 살아 있는 야외 맵은 안개가 룩의 핵심이라 **맵 프리팹 필드**로 되살린다(#746 과 같은 방식).
// 기본값 = fogEnabled false → 이 값을 켜지 않은 기존 맵은 동작이 전혀 바뀌지 않는다(C8).
[Header("안개 (#771 · 맵 프리팹에서 조정)")]
[Tooltip("끄면 기존 동작 그대로 RenderSettings.fog = false.")]
public bool fogEnabled = false;
public FogMode fogMode = FogMode.Linear;
public Color fogColor = new Color(0.492f, 0.611f, 0.821f, 1f);
[Tooltip("Linear 전용 — 이 거리부터 안개가 시작된다. 게임 카메라는 플레이어에서 3 m 뒤라 12 m 는 캐릭터 바로 뒤다.")]
public float fogStart = 30f;
[Tooltip("Linear 전용 — 이 거리에서 안개가 100%.")]
public float fogEnd = 250f;
[Tooltip("Exponential 계열 전용.")]
public float fogDensity = 0.0017f;
2024-12-15 01:39:39 +00:00
void Start()
{
RenderSettings.skybox = material_skybox;
WL 리뉴얼 세션 2026-09-06~07 (#760~#800) — 전투·배경·UI·타격감 (조직 PD 로그 #746~#800 · 대화로그 §14~§24) - 전투: Knight@Attack1~3_S 3콤보(4 컨트롤러·클래스별 서브클립) · 타겟팅 4규칙(정면 우선·재타겟·즉시 공격·어그로 금지 · WLTargetingSettings) · 대쉬 후 공격(Stander@Chase_Start · DashDriver · 5 m · 사정거리+0.8 · 근거리 적 우선) · 공격 이동 FrameTable(발 접지 실측 표 · AttackRootMotion) · 충돌 반경/투사체 0.3 배(WLCollisionTuning) · 무적(임시)·펫 금지(WLGameplaySettings) - 검기: NamuFX Slash_B 배리언트 Effect_WLSwingArc 원 피팅 정합 배치 + 캘리브레이션(SlashArcMeasure · SlashTrailSettings) · 찌르기 Effect_WLStab 대기 · 램프 리본(BladeTrail · WL_BladeRibbon.shader · T_WL_BladeRibbonRamp) 보존(drawRibbon 0) - 타격감: Assets/WL/Feel(WLHitFeel · 히트스톱 0.03 · 셰이크 0.10 m · 몹 펀치 1.12 · Actor.Get_Damage 훅 1줄 · 원본 RealCamera 셰이크 결함 대체) - 배경/맵: LMHPOLY Demo_01~10 → WL_Nature01~10(프리팹·씬·NavMesh·스포너·BattleMapConfig) · 물(ToonWaterU) · 포스트 블룸 0.9/0.3 · 잔디(BruteForce·드레싱) 제거 · 마젠타 머티리얼 URP 변환 - UI: 세로 HUD(WL_HUD · 하단 5메뉴 폭 전체 · 채팅/전투 패드 숨김 · WLIngameUiOverride) · Title/TitleInfo 1080×1920 Expand + 배경 높이 fit(WLBackgroundFit) · 로딩 SortOrder_5(WLRawImageAspectSync · 초점표 8장) · Loading1~8 ASTC 6×6 - 도구: AgentScripts/*(LightProbe · WL_MapSwitch · WL760~WL800 프로브/집행/검증 · 상단 사용법 주석) · 에디터 락 프로토콜 파일(staging) - 제외(별도 커밋 예정): Assets/LMHPOLY(703 MB) · Assets/Feel(422 MB) · Assets/Shinabro(300 MB) — 에셋 스토어/구 WL 팩 원본 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:24:25 +00:00
Apply_Lighting();
Apply_Fog();
2025-03-10 07:15:28 +00:00
if (m_ChapterPortal)
{
var mapData = MyValue.MyChoiceMapData;
var isclear = ServerInfo.Ins.m_ServerData.MapData_isClearChaper(mapData.n_MapID, mapData.n_Difficult);
m_ChapterPortal.Set_NextChapter(isclear);
}
2024-12-15 01:39:39 +00:00
}
WL 리뉴얼 세션 2026-09-06~07 (#760~#800) — 전투·배경·UI·타격감 (조직 PD 로그 #746~#800 · 대화로그 §14~§24) - 전투: Knight@Attack1~3_S 3콤보(4 컨트롤러·클래스별 서브클립) · 타겟팅 4규칙(정면 우선·재타겟·즉시 공격·어그로 금지 · WLTargetingSettings) · 대쉬 후 공격(Stander@Chase_Start · DashDriver · 5 m · 사정거리+0.8 · 근거리 적 우선) · 공격 이동 FrameTable(발 접지 실측 표 · AttackRootMotion) · 충돌 반경/투사체 0.3 배(WLCollisionTuning) · 무적(임시)·펫 금지(WLGameplaySettings) - 검기: NamuFX Slash_B 배리언트 Effect_WLSwingArc 원 피팅 정합 배치 + 캘리브레이션(SlashArcMeasure · SlashTrailSettings) · 찌르기 Effect_WLStab 대기 · 램프 리본(BladeTrail · WL_BladeRibbon.shader · T_WL_BladeRibbonRamp) 보존(drawRibbon 0) - 타격감: Assets/WL/Feel(WLHitFeel · 히트스톱 0.03 · 셰이크 0.10 m · 몹 펀치 1.12 · Actor.Get_Damage 훅 1줄 · 원본 RealCamera 셰이크 결함 대체) - 배경/맵: LMHPOLY Demo_01~10 → WL_Nature01~10(프리팹·씬·NavMesh·스포너·BattleMapConfig) · 물(ToonWaterU) · 포스트 블룸 0.9/0.3 · 잔디(BruteForce·드레싱) 제거 · 마젠타 머티리얼 URP 변환 - UI: 세로 HUD(WL_HUD · 하단 5메뉴 폭 전체 · 채팅/전투 패드 숨김 · WLIngameUiOverride) · Title/TitleInfo 1080×1920 Expand + 배경 높이 fit(WLBackgroundFit) · 로딩 SortOrder_5(WLRawImageAspectSync · 초점표 8장) · Loading1~8 ASTC 6×6 - 도구: AgentScripts/*(LightProbe · WL_MapSwitch · WL760~WL800 프로브/집행/검증 · 상단 사용법 주석) · 에디터 락 프로토콜 파일(staging) - 제외(별도 커밋 예정): Assets/LMHPOLY(703 MB) · Assets/Feel(422 MB) · Assets/Shinabro(300 MB) — 에셋 스토어/구 WL 팩 원본 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:24:25 +00:00
// #746: 프리팹 필드의 앰비언트 설정을 RenderSettings 에 적용한다(Start 에서 1회 · 인스펙터 튜닝 후 재호출 가능).
public void Apply_Lighting()
{
RenderSettings.ambientMode = ambientMode;
switch (ambientMode)
{
case UnityEngine.Rendering.AmbientMode.Trilight:
RenderSettings.ambientSkyColor = ambientSky;
RenderSettings.ambientEquatorColor = ambientEquator;
RenderSettings.ambientGroundColor = ambientGround;
break;
case UnityEngine.Rendering.AmbientMode.Flat:
RenderSettings.ambientLight = ambientSky;
break;
default: // Skybox: 프로브는 material_skybox 로부터 명시적으로 재생성해야 값이 바뀐다
RenderSettings.ambientIntensity = ambientIntensity;
if (updateEnvironmentFromSkybox && material_skybox != null)
DynamicGI.UpdateEnvironment();
break;
}
RenderSettings.reflectionIntensity = reflectionIntensity;
}
// #771: 안개도 맵 프리팹 필드에서 적용한다. fogEnabled=false 면 기존 동작(끔) 그대로.
public void Apply_Fog()
{
RenderSettings.fog = fogEnabled;
if (!fogEnabled) return;
RenderSettings.fogMode = fogMode;
RenderSettings.fogColor = fogColor;
RenderSettings.fogStartDistance = fogStart;
RenderSettings.fogEndDistance = fogEnd;
RenderSettings.fogDensity = fogDensity;
}
2024-12-15 01:39:39 +00:00
public MapZoneData Get_MapZoneData(int index) { return m_MapZoneData[index]; }
public void Set_MazeMap(int index)
{
DSUtil.InActivateGameObjects(gos_map, index);
Set_MazeNextPortal(index, false);
}
2025-01-25 21:04:01 +00:00
public void Set_MazeNextPortal(int index, bool active)
{
var mzd = Get_MapZoneData(index);
if (!DSUtil.CheckNull(mzd.go_mazeNextPortal))
mzd.go_mazeNextPortal.SetActive(active);
}
2024-12-15 01:39:39 +00:00
}
[Serializable]
public class MapZoneData
{
public GameObject go_portal;
public float CamRot_Portal;
2024-12-15 01:39:39 +00:00
public GameObject go_reincarnation;
public float CamRot_Reincarnation;
2025-01-25 21:04:01 +00:00
public GameObject go_mazeNextPortal;
2024-12-15 01:39:39 +00:00
public Transform tf_Farmer;
public Transform[] tf_Obj;
}
public class ChoiceMapData
{
ObscuredInt _Difficult;
public int n_Difficult
{
get { return _Difficult; }
set { _Difficult = value; _Difficult.RandomizeCryptoKey(); }
}
ObscuredInt _MapID;
public int n_MapID
{
get { return _MapID; }
set { _MapID = value; _MapID.RandomizeCryptoKey(); }
}
ObscuredInt _PortalIndex;
public int n_PortalIndex
{
get { return _PortalIndex; }
set { _PortalIndex = value; _PortalIndex.RandomizeCryptoKey(); }
}
ObscuredInt _DungeonLv;
public int n_DungeonLv
{
get { return _DungeonLv; }
set { _DungeonLv = value; _DungeonLv.RandomizeCryptoKey(); }
}
2025-01-31 05:32:03 +00:00
protected ObscuredDouble _NightmareBeforeDmg;
public double d_NightmareBeforeDmg
{
get { return _NightmareBeforeDmg; }
set { _NightmareBeforeDmg = value; _NightmareBeforeDmg.RandomizeCryptoKey(); }
}
public BattleMapConfigTableData Get_MapData() { return table_battlemapconfig.Ins.Get_Data(n_MapID); }
public DungeonMapConfigTableData Get_DungeonMapData_orNull()
{
var mapData = Get_MapData();
2025-01-25 21:04:01 +00:00
return mapData.e_Dungeon == eDungeon.None ? null :
table_dungeonmapconfig.Ins.Get_Data_orNull(mapData.e_Dungeon, n_DungeonLv);
}
public int Get_DungeonIndex()
{
var dgData = Get_DungeonMapData_orNull();
return DSUtil.CheckNull(dgData) ? 0 : MyEnumToInt.Ins.Get_Int(dgData.e_DungeonType) - 1;
}
2025-01-25 21:04:01 +00:00
public void Set_MazeMapIndex()
{
n_PortalIndex = Random.Range(0, table_GlobalValue.Ins.Get_Int("MazeMapCount"));
}
2024-12-15 01:39:39 +00:00
}