Project_WL/Assets/WL/Scripts/Player/PlayerTouchSettings.cs

78 lines
4.8 KiB
C#

using UnityEngine;
namespace WL.Player
{
/// <summary>
/// 모바일 터치 조작(가상 패드 + 자동 이동) 수치의 단일 출처(SOT).
/// 코드 상수 금지(C45) — 영역 비율·데드존·반경·달리기 임계값은 전부 이 에셋에서 읽는다.
/// 에셋 경로: Assets/WL/Settings/PlayerTouchSettings.asset
/// </summary>
[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;
/// <summary>패드 영역을 픽셀 Rect 로 환산</summary>
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;
}
}
}