버그 수정
This commit is contained in:
@@ -6,11 +6,13 @@ using UnityEngine.UI;
|
||||
namespace SHI.modal
|
||||
{
|
||||
/// <summary>
|
||||
/// 두 개의 RectTransform 가로 분할을 드래그 버튼으로 조절하는 간단한 스플리터.
|
||||
/// 레이아웃 그룹(수평) + LayoutElement.flexibleWidth 기반으로 동작합니다.
|
||||
/// 수평 레이아웃에서 두 패널의 가중치(LayoutElement.flexibleWidth)를 드래그 핸들로 조절하는 간단한 분할기입니다.
|
||||
/// </summary>
|
||||
public class HorizontalSplitDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
[SerializeField, Range(0.0f, 0.5f)] private float minLeftWeight = 0.1f;
|
||||
[SerializeField, Range(0.5f, 1.0f)] private float maxLeftWeight = 0.9f;
|
||||
|
||||
private RectTransform _left;
|
||||
private RectTransform _right;
|
||||
private LayoutElement _leftLayout;
|
||||
@@ -24,6 +26,9 @@ namespace SHI.modal
|
||||
private bool _lastLeftPanelActive;
|
||||
private float _lastParentWidth;
|
||||
|
||||
/// <summary>
|
||||
/// 좌/우 패널을 지정하고(필요 시 좌측 고정 패널 포함) 분할기를 초기화합니다.
|
||||
/// </summary>
|
||||
public void Initialize(RectTransform left, RectTransform right, RectTransform? leftFixedPanel = null)
|
||||
{
|
||||
_left = left;
|
||||
@@ -32,25 +37,27 @@ namespace SHI.modal
|
||||
_parent = left != null ? left.parent as RectTransform : null;
|
||||
_handleRect = transform as RectTransform;
|
||||
|
||||
_leftLayout = _left.GetComponent<LayoutElement>();
|
||||
if (_leftLayout == null) _leftLayout = _left.gameObject.AddComponent<LayoutElement>();
|
||||
_rightLayout = _right.GetComponent<LayoutElement>();
|
||||
if (_rightLayout == null) _rightLayout = _right.gameObject.AddComponent<LayoutElement>();
|
||||
_leftLayout = _left != null ? _left.GetComponent<LayoutElement>() : null;
|
||||
if (_left != null && _leftLayout == null) _leftLayout = _left.gameObject.AddComponent<LayoutElement>();
|
||||
_rightLayout = _right != null ? _right.GetComponent<LayoutElement>() : null;
|
||||
if (_right != null && _rightLayout == null) _rightLayout = _right.gameObject.AddComponent<LayoutElement>();
|
||||
|
||||
_lastLeftPanelActive = _leftFixedPanel != null && _leftFixedPanel.gameObject.activeInHierarchy;
|
||||
_lastParentWidth = _parent != null ? _parent.rect.width : 0f;
|
||||
RefreshPosition();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
if (_parent != null) _parentWidth = _parent.rect.width;
|
||||
if (_handleRect != null) _handleY = _handleRect.anchoredPosition.y;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (_parent == null) return;
|
||||
if (_parent == null || _leftLayout == null || _rightLayout == null) return;
|
||||
Vector2 local;
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(_parent, eventData.position, eventData.pressEventCamera, out local))
|
||||
return;
|
||||
@@ -58,34 +65,37 @@ namespace SHI.modal
|
||||
float width = _parent.rect.width;
|
||||
if (width <= 0f) return;
|
||||
|
||||
// 계산 범위: 좌측 고정 패널(보이는 경우)의 폭만큼 좌측 경계를 오른쪽으로 이동
|
||||
// 좌측 고정 패널(보이는 경우)의 폭만큼 좌측 경계를 오른쪽으로 이동
|
||||
float leftOffset = 0f;
|
||||
if (_leftFixedPanel != null && _leftFixedPanel.gameObject.activeSelf)
|
||||
{
|
||||
leftOffset = _leftFixedPanel.rect.width;
|
||||
}
|
||||
|
||||
float minX = -width * 0.5f + leftOffset; // 사용 가능한 작업 영역의 좌측 경계
|
||||
float maxX = width * 0.5f; // 우측 경계
|
||||
float minX = -width * 0.5f + leftOffset; // 작업 영역 좌측 경계
|
||||
float maxX = width * 0.5f; // 작업 영역 우측 경계
|
||||
// 현재 포인터 위치를 작업 영역 비율[0..1]로 변환 후 범위 제한
|
||||
float t = Mathf.InverseLerp(minX, maxX, local.x);
|
||||
t = Mathf.Clamp01(t);
|
||||
|
||||
// LayoutElement 비율 (양 끝 과도값 방지하여10%~90% 사이 유지)
|
||||
float leftWeight = Mathf.Clamp(t, 0.1f, 0.9f);
|
||||
float rightWeight = 1f - leftWeight;
|
||||
// LayoutElement 비율 (가변 범위)
|
||||
float leftWeight = Mathf.Lerp(minLeftWeight, maxLeftWeight, t);
|
||||
float rightWeight = Mathf.Max(0.0001f, 1f - leftWeight);
|
||||
_leftLayout.flexibleWidth = leftWeight;
|
||||
_rightLayout.flexibleWidth = rightWeight;
|
||||
|
||||
// 스플리터 핸들도 같은 좌표계에서 이동
|
||||
if (_handleRect != null)
|
||||
{
|
||||
float clampedX = Mathf.Lerp(minX, maxX, leftWeight);
|
||||
float clampedX = Mathf.Lerp(minX, maxX, Mathf.InverseLerp(minLeftWeight, maxLeftWeight, leftWeight));
|
||||
_handleRect.anchoredPosition = new Vector2(clampedX, _handleY);
|
||||
}
|
||||
}
|
||||
|
||||
// 외부에서 강제로 현재 레이아웃 기준으로 핸들 위치를 동기화합니다.
|
||||
/// <summary>
|
||||
/// 현재 레이아웃 상태에 맞게 드래그 핸들의 위치를 동기화합니다.
|
||||
/// (레이아웃/가시성 변경 이후 호출 권장)
|
||||
/// </summary>
|
||||
public void RefreshPosition()
|
||||
{
|
||||
if (_parent == null || _handleRect == null || _leftLayout == null || _rightLayout == null)
|
||||
@@ -103,11 +113,11 @@ namespace SHI.modal
|
||||
|
||||
float totalFlex = Mathf.Max(0.0001f, _leftLayout.flexibleWidth + _rightLayout.flexibleWidth);
|
||||
float leftWeight = Mathf.Clamp01(_leftLayout.flexibleWidth / totalFlex);
|
||||
leftWeight = Mathf.Clamp(leftWeight, 0.1f, 0.9f);
|
||||
leftWeight = Mathf.Clamp(leftWeight, minLeftWeight, maxLeftWeight);
|
||||
|
||||
if (_handleRect != null)
|
||||
{
|
||||
_handleRect.anchoredPosition = new Vector2(Mathf.Lerp(minX, maxX, leftWeight), _handleY);
|
||||
_handleRect.anchoredPosition = new Vector2(Mathf.Lerp(minX, maxX, Mathf.InverseLerp(minLeftWeight, maxLeftWeight, leftWeight)), _handleY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +133,7 @@ namespace SHI.modal
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnEndDrag(PointerEventData eventData) { }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user