대화시스템 수정

This commit is contained in:
2026-07-15 14:07:25 +09:00
parent 376423a2cb
commit e98b6f610d
5 changed files with 41 additions and 8 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -38,6 +38,10 @@ public int MainProgress
}
}
// UnityEvent 연결용 (버튼·이벤트존·노드 이벤트 등에서 진행도 조작)
public void AddMainProgress(int amount) => MainProgress += amount;
public void SetMainProgress(int value) => MainProgress = value;
// ── 호감도 ──────────────────────────────────────────────────
public int GetAffection(CharacterData character)
=> character != null && _state.Affection.TryGetValue(IdOf(character), out var v) ? v : 0;

View File

@@ -48,6 +48,9 @@ public struct PlacementCandidate
[Tooltip("충돌 검사에 쓰는 대사창 절반 크기 — 실제 캔버스 크기에 맞출 것")]
[SerializeField] private Vector3 _panelHalfExtents = new(0.5f, 0.3f, 0.05f);
[Tooltip("가림 허용 비율 — 패널 표본점(5×4=20점, 1점=5%) 중 이 비율까지는 가려져도 통과")]
[Range(0f, 1f)] [SerializeField] private float _maxOccludedFraction = 0.05f;
private Transform _speakerTransform;
private float _activeChestHeight;
private float _activeForwardOffset;
@@ -149,8 +152,8 @@ private void ApplyBestCandidate(List<PlacementCandidate> candidates)
// 벽/지형에 겹치는가
if (Physics.CheckBox(pos, _panelHalfExtents, rot, _obstacleMask, QueryTriggerInteraction.Ignore))
continue;
// 플레이어 눈에서 벽에 가려지는가
if (Physics.Linecast(camPos, pos, _obstacleMask, QueryTriggerInteraction.Ignore))
// 플레이어 눈에서 벽에 가려지는가 — 패널 전체를 표본점으로 검사해 허용 비율까지만 통과
if (OccludedFraction(camPos, pos, rot) > _maxOccludedFraction)
continue;
ApplyCandidate(cand);
@@ -159,6 +162,32 @@ private void ApplyBestCandidate(List<PlacementCandidate> candidates)
// 전부 실패 — 미리 적용해 둔 첫 후보(기본) 그대로 사용
}
// 카메라 눈에서 패널 표면 표본점들로 레이를 쏴서 벽에 가려진 비율(0~1)을 구한다.
// 표본은 패널 사각형을 모서리·가장자리까지 덮는 5×4 격자 — 중심 한 점만 검사하면
// 가장자리가 벽 뒤로 반쯤 걸쳐도 통과해 버리는 문제를 잡기 위한 것.
private const int _occlusionCols = 5;
private const int _occlusionRows = 4;
private float OccludedFraction(Vector3 camPos, Vector3 center, Quaternion rot)
{
Vector3 right = rot * Vector3.right * _panelHalfExtents.x;
Vector3 up = rot * Vector3.up * _panelHalfExtents.y;
int blocked = 0;
for (int r = 0; r < _occlusionRows; r++)
{
float v = (float)r / (_occlusionRows - 1) * 2f - 1f; // -1(아래) ~ +1(위)
for (int c = 0; c < _occlusionCols; c++)
{
float u = (float)c / (_occlusionCols - 1) * 2f - 1f; // -1(좌) ~ +1(우)
Vector3 p = center + right * u + up * v;
if (Physics.Linecast(camPos, p, _obstacleMask, QueryTriggerInteraction.Ignore))
blocked++;
}
}
return (float)blocked / (_occlusionRows * _occlusionCols);
}
private void LateUpdate()
{
if (_speakerTransform == null) return;