using UnityEngine; namespace WL.Player { /// /// 모바일 터치 조작(가상 패드 + 자동 이동) 수치의 단일 출처(SOT). /// 코드 상수 금지(C45) — 영역 비율·데드존·반경·달리기 임계값은 전부 이 에셋에서 읽는다. /// 에셋 경로: Assets/WL/Settings/PlayerTouchSettings.asset /// [CreateAssetMenu(fileName = "PlayerTouchSettings", menuName = "WL/Player Touch Settings")] public class PlayerTouchSettings : ScriptableObject { [Header("플로팅 조이스틱 (PD #706 ②)")] [Tooltip("켜면 화면 어디를 터치해도 그 지점에 패드가 나타나고, 떼면 사라진다(HUD 버튼 위에서 시작한 터치는 제외). " + "끄면 구 방식 — 아래 패드 영역 안에서만 패드가 뜨고 영역 밖 터치는 자동 이동(PointAt)")] public bool floatingPadEverywhere = true; [Header("가상 패드 영역 (뷰포트 비율 0~1 · 좌하단 원점) — floatingPadEverywhere 가 꺼졌을 때만 사용")] [Tooltip("【floatingPadEverywhere = true 면 미사용】 패드 영역 좌하단 (기본 0,0)")] public Vector2 padAreaMin = new Vector2(0f, 0f); [Tooltip("【floatingPadEverywhere = true 면 미사용】 패드 영역 우상단 (기본 0.5,0.5 = 화면 좌측 하단 1/4)")] public Vector2 padAreaMax = new Vector2(0.5f, 0.5f); [Header("가상 조이스틱")] [Tooltip("최대 입력이 되는 드래그 반경. 화면 짧은 변 대비 비율")] [Range(0.02f, 0.5f)] public float padRadiusRatio = 0.12f; [Tooltip("이 비율 이하 드래그는 입력 없음으로 본다(반경 대비)")] [Range(0f, 0.9f)] public float padDeadZoneRatio = 0.15f; [Header("자동 이동 (패드 영역 밖 터치) — floatingPadEverywhere 가 꺼졌을 때만 사용")] [Tooltip("【floatingPadEverywhere = true 면 미사용】 플레이어 화면 좌표에서 이 거리(화면 짧은 변 대비 비율) 안쪽을 터치하면 정지")] [Range(0f, 0.5f)] public float autoMoveDeadZoneRatio = 0.03f; [Tooltip("자동 이동은 항상 최대 속도로 (끄면 터치 거리에 비례)")] public bool autoMoveFullSpeed = true; [Header("걷기 / 달리기 전환 (가상 패드)")] [Tooltip("PD 조정값 · 드래그 정규화 크기(데드존~반경 = 0~1)가 이 값 미만이면 걷기, 이상이면 달리기 · 임시 0.5")] [Range(0f, 1f)] public float sprintInputThreshold = 0.5f; [Tooltip("걷기 구간에서도 드래그 크기에 비례해 속도를 낮춘다(미세 위치 조작)")] public bool scaleWalkByDrag = true; [Tooltip("걷기 구간 최소 속도 비율(걷기 속도 대비). 제자리 걷기 방지")] [Range(0.1f, 1f)] public float walkMinSpeedRatio = 0.35f; [Tooltip("패드 밖 터치(자동 이동)는 항상 달리기")] public bool autoMoveAlwaysRun = true; [Header("입력 안전 장치 (무입력인데 자동 이동하는 현상 차단)")] [Tooltip("앱(에디터 게임 뷰)이 포커스를 잃은 동안에는 포인터 입력을 받지 않는다. 백그라운드 클릭이 이동으로 새는 것을 막는다")] public bool ignoreInputWhenUnfocused = true; [Tooltip("【PD #707 ① 이후 코드에서 항상 적용】 이미 눌린 채로 넘어온 포인터는 뗄 때까지 무시한다. release 를 놓친 잔류 입력 차단")] public bool requireFreshPress = true; [Tooltip("씬 시작 후 이 시간(초) 동안 포인터 입력을 아예 무시한다. Play 진입 순간의 잔류 클릭·터치가 " + "가상패드를 만들어 캐릭터가 저절로 움직이던 문제 차단 (PD #707 ①) · 임시 0.5")] [Range(0f, 3f)] public float inputIgnoreSecondsAfterStart = 0.5f; [Header("디버그")] [Tooltip("게임 뷰에 패드 영역/조이스틱을 그린다")] public bool drawDebugOverlay = true; /// 패드 영역을 픽셀 Rect 로 환산 public Rect GetPadRectPixels(float screenWidth, float screenHeight) { float x = padAreaMin.x * screenWidth; float y = padAreaMin.y * screenHeight; return new Rect(x, y, (padAreaMax.x - padAreaMin.x) * screenWidth, (padAreaMax.y - padAreaMin.y) * screenHeight); } public float GetPadRadiusPixels(float screenWidth, float screenHeight) { return Mathf.Min(screenWidth, screenHeight) * padRadiusRatio; } public float GetAutoMoveDeadZonePixels(float screenWidth, float screenHeight) { return Mathf.Min(screenWidth, screenHeight) * autoMoveDeadZoneRatio; } } }