드래그 어긋나는거 수정
This commit is contained in:
@@ -12,6 +12,7 @@ namespace SHI.modal
|
||||
{
|
||||
[SerializeField, Range(0.0f, 0.5f)] private float minLeftWeight = 0.1f;
|
||||
[SerializeField, Range(0.5f, 1.0f)] private float maxLeftWeight = 0.9f;
|
||||
[SerializeField] private bool useActualWidthForHandle = true; // 실제 패널 폭 기준 위치 보정
|
||||
|
||||
private RectTransform _left;
|
||||
private RectTransform _right;
|
||||
@@ -47,6 +48,7 @@ namespace SHI.modal
|
||||
RefreshPosition();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
@@ -54,6 +56,23 @@ namespace SHI.modal
|
||||
if (_handleRect != null) _handleY = _handleRect.anchoredPosition.y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 부모 RectTransform pivot을 고려한 작업 영역 좌/우 경계 계산.
|
||||
/// </summary>
|
||||
private void GetWorkArea(out float minX, out float maxX, out float leftOffset)
|
||||
{
|
||||
minX = maxX = leftOffset = 0f;
|
||||
if (_parent == null) return;
|
||||
float width = _parent.rect.width;
|
||||
var pivot = _parent.pivot; // (0..1)
|
||||
float pivotOrigin = -width * pivot.x; // local 좌표계에서 좌측 경계
|
||||
leftOffset = 0f;
|
||||
if (_leftFixedPanel != null && _leftFixedPanel.gameObject.activeSelf)
|
||||
leftOffset = _leftFixedPanel.rect.width; // 고정 패널 폭만큼 이동
|
||||
minX = pivotOrigin + leftOffset;
|
||||
maxX = pivotOrigin + width; // 우측 경계 (handle 중심 좌표)
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
@@ -61,66 +80,80 @@ namespace SHI.modal
|
||||
Vector2 local;
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(_parent, eventData.position, eventData.pressEventCamera, out local))
|
||||
return;
|
||||
|
||||
float width = _parent.rect.width;
|
||||
if (width <= 0f) return;
|
||||
|
||||
// 좌측 고정 패널(보이는 경우)의 폭만큼 좌측 경계를 오른쪽으로 이동
|
||||
float leftOffset = 0f;
|
||||
if (_leftFixedPanel != null && _leftFixedPanel.gameObject.activeSelf)
|
||||
{
|
||||
leftOffset = _leftFixedPanel.rect.width;
|
||||
}
|
||||
float minX, maxX, leftOffset;
|
||||
GetWorkArea(out minX, out maxX, out leftOffset);
|
||||
|
||||
float minX = -width * 0.5f + leftOffset; // 작업 영역 좌측 경계
|
||||
float maxX = width * 0.5f; // 작업 영역 우측 경계
|
||||
// 현재 포인터 위치를 작업 영역 비율[0..1]로 변환 후 범위 제한
|
||||
// 드래그 포인터를 작업 영역으로 정규화하여 [0..1] 비율 t 산출
|
||||
float t = Mathf.InverseLerp(minX, maxX, local.x);
|
||||
t = Mathf.Clamp01(t);
|
||||
|
||||
// LayoutElement 비율 (가변 범위)
|
||||
// 가변 비율 계산 (minLeftWeight~maxLeftWeight 범위)
|
||||
float leftWeight = Mathf.Lerp(minLeftWeight, maxLeftWeight, t);
|
||||
float rightWeight = Mathf.Max(0.0001f, 1f - leftWeight);
|
||||
_leftLayout.flexibleWidth = leftWeight;
|
||||
_rightLayout.flexibleWidth = rightWeight;
|
||||
|
||||
// 스플리터 핸들도 같은 좌표계에서 이동
|
||||
if (_handleRect != null)
|
||||
// 레이아웃 즉시 반영 후 실제 폭 기준 위치 재계산
|
||||
Canvas.ForceUpdateCanvases();
|
||||
UpdateHandlePositionFromActualWidths(minX, maxX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 실제 패널 폭을 사용해 핸들 위치를 경계선(왼쪽 패널 오른쪽 끝)에 정렬.
|
||||
/// 레이아웃 그룹 padding/spacing, 고정 패널 폭을 모두 반영.
|
||||
/// </summary>
|
||||
private void UpdateHandlePositionFromActualWidths(float minX, float maxX)
|
||||
{
|
||||
if (_handleRect == null || _parent == null || _left == null) return;
|
||||
if (!useActualWidthForHandle)
|
||||
{
|
||||
float clampedX = Mathf.Lerp(minX, maxX, Mathf.InverseLerp(minLeftWeight, maxLeftWeight, leftWeight));
|
||||
_handleRect.anchoredPosition = new Vector2(clampedX, _handleY);
|
||||
// 기존 비율 방식 (보정 없이)
|
||||
float totalFlex = Mathf.Max(0.0001f, _leftLayout.flexibleWidth + _rightLayout.flexibleWidth);
|
||||
float leftWeight = Mathf.Clamp01(_leftLayout.flexibleWidth / totalFlex);
|
||||
float normalized = Mathf.InverseLerp(minLeftWeight, maxLeftWeight, Mathf.Clamp(leftWeight, minLeftWeight, maxLeftWeight));
|
||||
float xRatio = Mathf.Lerp(minX, maxX, normalized);
|
||||
_handleRect.anchoredPosition = new Vector2(xRatio, _handleY);
|
||||
return;
|
||||
}
|
||||
|
||||
// 고정 패널 폭 + 가변 왼쪽 패널 실제 폭 = 경계 픽셀
|
||||
float fixedWidth = (_leftFixedPanel != null && _leftFixedPanel.gameObject.activeSelf) ? _leftFixedPanel.rect.width : 0f;
|
||||
float variableLeftWidth = _left.rect.width; // 레이아웃 적용 후 실제 계산된 폭
|
||||
|
||||
// 부모 pivot 기반 local 좌표 좌측 경계
|
||||
float widthParent = _parent.rect.width;
|
||||
float origin = -widthParent * _parent.pivot.x;
|
||||
float boundaryX = origin + fixedWidth + variableLeftWidth;
|
||||
|
||||
// 핸들 자체 폭 중앙 정렬 (핸들 pivot이 중앙이라고 가정)
|
||||
// 경계 근처에서 과도한 이동 방지 (clamp)
|
||||
float halfHandle = _handleRect.rect.width * 0.5f;
|
||||
float minCenter = origin + fixedWidth + halfHandle; // 최소 중앙: 고정 패널 끝 + 반 핸들
|
||||
float maxCenter = origin + widthParent - halfHandle; // 최대 중앙: 부모 우측 - 반 핸들
|
||||
float centerX = Mathf.Clamp(boundaryX, minCenter, maxCenter);
|
||||
_handleRect.anchoredPosition = new Vector2(centerX, _handleY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 레이아웃 상태에 맞게 드래그 핸들의 위치를 동기화합니다.
|
||||
/// (레이아웃/가시성 변경 이후 호출 권장)
|
||||
/// </summary>
|
||||
public void RefreshPosition()
|
||||
{
|
||||
if (_parent == null || _handleRect == null || _leftLayout == null || _rightLayout == null)
|
||||
return;
|
||||
|
||||
if (_parent == null || _handleRect == null || _leftLayout == null || _rightLayout == null) return;
|
||||
float width = _parent.rect.width;
|
||||
if (width <= 0f) return;
|
||||
|
||||
float leftOffset = 0f;
|
||||
if (_leftFixedPanel != null && _leftFixedPanel.gameObject.activeSelf)
|
||||
leftOffset = _leftFixedPanel.rect.width;
|
||||
float minX, maxX, leftOffset;
|
||||
GetWorkArea(out minX, out maxX, out leftOffset);
|
||||
|
||||
float minX = -width * 0.5f + leftOffset;
|
||||
float maxX = width * 0.5f;
|
||||
|
||||
float totalFlex = Mathf.Max(0.0001f, _leftLayout.flexibleWidth + _rightLayout.flexibleWidth);
|
||||
float leftWeight = Mathf.Clamp01(_leftLayout.flexibleWidth / totalFlex);
|
||||
leftWeight = Mathf.Clamp(leftWeight, minLeftWeight, maxLeftWeight);
|
||||
|
||||
if (_handleRect != null)
|
||||
{
|
||||
_handleRect.anchoredPosition = new Vector2(Mathf.Lerp(minX, maxX, Mathf.InverseLerp(minLeftWeight, maxLeftWeight, leftWeight)), _handleY);
|
||||
}
|
||||
Canvas.ForceUpdateCanvases();
|
||||
UpdateHandlePositionFromActualWidths(minX, maxX);
|
||||
}
|
||||
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
bool nowActive = _leftFixedPanel != null && _leftFixedPanel.gameObject.activeInHierarchy;
|
||||
|
||||
Reference in New Issue
Block a user