dezhou_client/wb_unity_pro/Assets/Scripts/LuaHelper/CustomScrollView.cs

218 lines
6.8 KiB
C#
Raw Normal View History

2025-12-22 20:49:57 +08:00
using UnityEngine;
public class CustomScrollView : MonoBehaviour
{
public RectTransform rectStopUp;
public RectTransform rectStopDown;
public RectTransform rectTitle;
public RectTransform rectCenter;
public RectTransform rectCenterLimitUp;
public RectTransform rectCenterLimitDown;
public RectTransform rectCenterSubUp;
public RectTransform rectCenterSubDown;
// <20><><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private float damping = 0.9f; // <20><><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>ֵԽС<D4BD><D0A1><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>
private float minVelocity = 0.1f; // <20><>С<EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD>ֵ
private Vector3 vecStart;
private Vector3 vecStartCenter;
private Vector3 vecStartTitle;
private Vector3 velocity = Vector3.zero; // <20><>ǰ<EFBFBD>ٶ<EFBFBD>
private bool isDragging = false;
private float lastMouseY;
private bool shouldStopScrollUp = false; // <20>Ƿ<EFBFBD>Ӧ<EFBFBD><D3A6>ֹͣ<CDA3><D6B9><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>
private bool shouldStopScrollDown = false; // <20>Ƿ<EFBFBD>Ӧ<EFBFBD><D3A6>ֹͣ<CDA3><D6B9><EFBFBD>»<EFBFBD><C2BB><EFBFBD>
void Update()
{
if (Input.GetMouseButtonDown(0))
{
StartDragging();
}
if (Input.GetMouseButtonUp(0))
{
StopDragging();
}
if (Input.GetMouseButton(0))
{
HandleDragging();
}
// Ӧ<>û<EFBFBD><C3BB><EFBFBD>Ч<EFBFBD><D0A7>
ApplyInertia();
}
private void StartDragging()
{
vecStart = Input.mousePosition;
vecStartCenter = rectCenter.position;
vecStartTitle = rectTitle.position;
lastMouseY = Input.mousePosition.y;
velocity = Vector3.zero;
isDragging = true;
shouldStopScrollUp = false;
shouldStopScrollDown = false;
}
private void StopDragging()
{
isDragging = false;
}
private void HandleDragging()
{
if (!isDragging) return;
Vector3 currentMousePos = Input.mousePosition;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><59>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
float deltaY = currentMousePos.y - vecStart.y;
Vector3 newPosition = vecStartCenter + new Vector3(0, deltaY, 0);
// <20><><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>
CheckScrollLimits(deltaY);
// <20><><EFBFBD>ݱ߽<DDB1><DFBD><EFBFBD><EFBFBD>ƾ<EFBFBD><C6BE><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>rectCenterλ<72><CEBB>
if (!(deltaY > 0 && shouldStopScrollDown) && !(deltaY < 0 && shouldStopScrollUp))
{
// ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rectCenter<65><72>λ<EFBFBD><CEBB>
rectCenter.position = newPosition;
// <20><><EFBFBD><EFBFBD>rectTitleӦ<65><D3A6><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
Vector3 newTitlePosition = vecStartTitle + new Vector3(0, deltaY, 0);
// <20><><EFBFBD><EFBFBD>rectTitle<6C><65>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±߽<C2B1>
float minY = rectStopDown.position.y;
float maxY = rectStopUp.position.y;
newTitlePosition.y = Mathf.Clamp(newTitlePosition.y, minY, maxY);
// <20><><EFBFBD><EFBFBD>rectTitle<6C><65>λ<EFBFBD><CEBB>
rectTitle.position = newTitlePosition;
}
// <20><><EFBFBD>㵱ǰ<E3B5B1>ٶȣ<D9B6><C8A3><EFBFBD><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
float currentDeltaY = currentMousePos.y - lastMouseY;
velocity = new Vector3(0, currentDeltaY / Time.deltaTime, 0);
lastMouseY = currentMousePos.y;
}
private void ApplyInertia()
{
if (!isDragging && velocity.magnitude > minVelocity)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>
CheckScrollLimits(velocity.y * Time.deltaTime);
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ӧ<EFBFBD><D3A6>ֹͣ<CDA3><D6B9><EFBFBD>Ի<EFBFBD><D4BB><EFBFBD>
bool shouldStopInertia = (velocity.y > 0 && shouldStopScrollDown) || (velocity.y < 0 && shouldStopScrollUp);
if (!shouldStopInertia)
{
// ʹ<><CAB9>ָ<EFBFBD><D6B8>˥<EFBFBD><CBA5><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
float deceleration = Mathf.Pow(damping, Time.deltaTime * 60f);
velocity *= deceleration;
// rectCenter<65><72><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>
rectCenter.position += velocity * Time.deltaTime;
// rectTitle<6C><65><EFBFBD><EFBFBD>rectCenter<65>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܱ߽<DCB1><DFBD><EFBFBD><EFBFBD><EFBFBD>
Vector3 newTitlePosition = rectTitle.position + velocity * Time.deltaTime;
float minY = rectStopDown.position.y;
float maxY = rectStopUp.position.y;
newTitlePosition.y = Mathf.Clamp(newTitlePosition.y, minY, maxY);
rectTitle.position = newTitlePosition;
}
else
{
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ټ<EFBFBD><D9BC><EFBFBD>
velocity *= 0.5f;
}
if (velocity.magnitude <= minVelocity)
{
velocity = Vector3.zero;
}
}
else if (!isDragging && velocity.magnitude <= minVelocity)
{
// <20><><EFBFBD>ٶȺ<D9B6>Сʱ<D0A1><CAB1>ȷ<EFBFBD><C8B7>rectTitle<6C><65><EFBFBD>ڱ߽<DAB1><DFBD><EFBFBD>
Vector3 currentTitlePos = rectTitle.position;
float minY = rectStopDown.position.y;
float maxY = rectStopUp.position.y;
currentTitlePos.y = Mathf.Clamp(currentTitlePos.y, minY, maxY);
rectTitle.position = currentTitlePos;
}
}
// <20><><EFBFBD><EFBFBD><E9BBAC><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>
private void CheckScrollLimits(float deltaY)
{
// <20><><EFBFBD>ñ<EFBFBD>־
shouldStopScrollUp = false;
shouldStopScrollDown = false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD><C2BB><EFBFBD>ʱrectCenterSubUp<55><70><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD>rectCenterLimitUp
if (deltaY < 0) // <20><><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD><EFBFBD><EFBFBD>rectCenter<65><72><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>
{
if (rectCenterSubUp != null && rectCenterLimitUp != null)
{
// <20><><EFBFBD><EFBFBD>rectCenterSubUp<55>ĵײ<C4B5><D7B2>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>rectCenterLimitUp<55>Ķ<EFBFBD><C4B6><EFBFBD>
float subUpBottom = rectCenterSubUp.position.y - rectCenterSubUp.rect.height / 2;
float limitUpTop = rectCenterLimitUp.position.y + rectCenterLimitUp.rect.height / 2;
if (subUpBottom < limitUpTop)
{
shouldStopScrollUp = true;
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>ʱrectCenterSubDown<77><6E><EFBFBD>ܸ<EFBFBD><DCB8><EFBFBD>rectCenterLimitDown
if (deltaY > 0) // <20><><EFBFBD>»<EFBFBD><C2BB><EFBFBD><EFBFBD><EFBFBD>rectCenter<65><72><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>
{
if (rectCenterSubDown != null && rectCenterLimitDown != null)
{
// <20><><EFBFBD><EFBFBD>rectCenterSubDown<77>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>rectCenterLimitDown<77>ĵײ<C4B5>
float subDownTop = rectCenterSubDown.position.y + rectCenterSubDown.rect.height / 2;
float limitDownBottom = rectCenterLimitDown.position.y - rectCenterLimitDown.rect.height / 2;
if (subDownTop > limitDownBottom)
{
shouldStopScrollDown = true;
}
}
}
}
// <20>ⲿ<EFBFBD><E2B2BF><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶȣ<D9B6><C8A3><EFBFBD><EFBFBD><EFBFBD><E7B7B4>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
public void AddVelocity(Vector3 additionalVelocity)
{
velocity += additionalVelocity;
}
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public void SetDamping(float newDamping)
{
damping = Mathf.Clamp(newDamping, 0.1f, 0.99f);
}
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ٶ<EFBFBD>
public Vector3 GetCurrentVelocity()
{
return velocity;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>Ƹ<EFBFBD><C6B8><EFBFBD>rectTitleλ<65>õ<EFBFBD><C3B5>߽<EFBFBD><DFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD>Ҫʱ<D2AA><CAB1><EFBFBD>ã<EFBFBD>
public void ClampTitlePosition()
{
Vector3 currentTitlePos = rectTitle.position;
float minY = rectStopDown.position.y;
float maxY = rectStopUp.position.y;
currentTitlePos.y = Mathf.Clamp(currentTitlePos.y, minY, maxY);
rectTitle.position = currentTitlePos;
}
}