using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; using UnityEngine.EventSystems; public class ImageSlider : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public List images; // 所有图片的 RectTransform GraphicRaycaster raycaster; public int currentIndex = 0; // 当前居中图片索引 float largeSpacing = 1000f; // 图片之间的水平间距 float smallSpacing = 800f; // 图片之间的水平间距 float sideScale = 1.0f; // 侧边图片的缩放比例 float sideRotation = 60f; // 侧边图片的倾斜角度 private Vector2 dragStartPos; private bool isDragging = false; private Dictionary originalSprites = new Dictionary(); void Start() { raycaster = GetComponentInParent().GetComponent(); foreach (var img in images) { var imageComp = img.GetComponent(); if (imageComp != null) { originalSprites[img] = imageComp.sprite; // 缓存原始图像 } } UpdateLayout(true); } public void OnBeginDrag(PointerEventData eventData) { // Debug.Log("开始拖动"); dragStartPos = eventData.position; isDragging = true; } public void OnEndDrag(PointerEventData eventData) { // Debug.Log("结束拖动"); isDragging = false; float dragDelta = eventData.position.x - dragStartPos.x; if (Mathf.Abs(dragDelta) > 100f) // 你可以根据需要调整阈值 { if (dragDelta > 0) SlideLeft(); else SlideRight(); } } public void SlideLeft() { currentIndex = (currentIndex - 1 + images.Count) % images.Count; // 循环索引 UpdateLayout(); } public void SlideRight() { currentIndex = (currentIndex + 1) % images.Count; // 循环索引 UpdateLayout(); } // 用于处理循环偏移 int GetWrappedOffset(int index, int center, int count) { int offset = index - center; if (offset > count / 2) offset -= count; else if (offset < -count / 2) offset += count; return offset; } void ReplaceCenterImage(RectTransform img) { Image imageComp = img.GetComponent(); if (imageComp == null) return; string name = img.name; // 加载新的图像(可以放在 Resources 文件夹中) Sprite newSprite = Resources.Load("CenterImages/" + name); if (newSprite != null) { imageComp.sprite = newSprite; } else { Debug.LogWarning("找不到对应的中心图像: " + name); } } void RestoreOriginalImage(RectTransform img) { Image imageComp = img.GetComponent(); if (imageComp == null) return; if (originalSprites.ContainsKey(img)) { imageComp.sprite = originalSprites[img]; } } void UpdateLayout(bool instant = false) { for (int i = 0; i < images.Count; i++) { var img = images[i]; // int offset = i - currentIndex; int offset = GetWrappedOffset(i, currentIndex, images.Count); if (Mathf.Abs(offset) > 2) { img.gameObject.SetActive(false); continue; } else { img.gameObject.SetActive(true); } // 判断是否是中心图 if (offset == 0) { ReplaceCenterImage(img); } else { RestoreOriginalImage(img); } float spacing = (Mathf.Abs(offset) == 1) ? largeSpacing : smallSpacing; float posX = offset * spacing; float posZ = Mathf.Abs(offset) * 500f; Vector3 targetPos = new Vector3(posX, 0, posZ); float alpha = 1.0f; // Vector3 targetPos = new Vector3(offset * spacing, 0, 0); // Vector3 targetPos = new Vector3(offset * spacing, 0, Mathf.Abs(offset) * 200f); // 加入Z轴位移 Vector3 targetScale = new Vector3(1f, 1f, 1f) * sideScale; Vector3 targetRotation = Vector3.zero; if (offset < 0) { // targetScale = Vector3.one * sideScale; targetRotation = new Vector3(0, -sideRotation, 0); } else if (offset > 0) { // targetScale = Vector3.one * sideScale; targetRotation = new Vector3(0, sideRotation, 0); } if (Mathf.Abs(offset) > 1) { img.GetComponent().DOFade(alpha, 0.5f); } if (instant) { img.anchoredPosition3D = targetPos; img.localScale = targetScale; img.localRotation = Quaternion.Euler(targetRotation); img.GetComponent().color = new Color(1, 1, 1, alpha); } else { img.DOAnchorPos3D(targetPos, 0.5f).SetEase(Ease.OutExpo); img.DOScale(targetScale, 0.8f).SetEase(Ease.OutExpo); img.DOLocalRotate(targetRotation, 0.5f).SetEase(Ease.OutExpo); } // img.SetSiblingIndex(images.Count - Mathf.Abs(offset)); // 让中间图最高层,左右两边根据距离决定层级 int sortingOrder = 100 - Mathf.Abs(offset) * 10; img.SetSiblingIndex(sortingOrder); List<(RectTransform img, int offsetx)> sorted = new(); for (int j = 0; j < images.Count; j++) { int offsetx = GetWrappedOffset(j, currentIndex, images.Count); sorted.Add((images[j], offsetx)); } // 按 offset 的绝对值升序排序,中心的图在最上 sorted.Sort((a, b) => Mathf.Abs(b.offsetx).CompareTo(Mathf.Abs(a.offsetx))); for (int k = 0; k < sorted.Count; k++) { sorted[k].img.SetSiblingIndex(k); } } } public void OnDrag(PointerEventData eventData) { } void Update() { if (Input.GetMouseButtonDown(0)) { dragStartPos = Input.mousePosition; isDragging = false; } if (Input.GetMouseButtonUp(0)) { float dragDistance = (Input.mousePosition - (Vector3)dragStartPos).magnitude; if (dragDistance > 50f) { isDragging = true; // 视为拖动 } else { isDragging = false; // 视为点击 } if (!isDragging) { // 执行点击检测(只允许点击中心图) DetectClick(); } } } void DetectClick() { PointerEventData pointerData = new PointerEventData(EventSystem.current); pointerData.position = Input.mousePosition; List results = new List(); raycaster.Raycast(pointerData, results); if (results.Count > 0) { GameObject clicked = results[0].gameObject; Debug.Log("🖱️ 点击了: " + clicked.name); // 判断是否是当前居中的图像 if (clicked == images[currentIndex].gameObject) { // 判断是否是指定区域 string name = clicked.name; if (name == "杭州市淳安县" || name == "湖州市安吉县" || name == "湖州市长兴县" || name == "金华浦江县金狮湖" || name == "金华浦江县三江口湿地" || name == "金华义乌市水系统" || name == "宁波市三江口" || name == "宁波象山县" || name == "宁波月湖整治" || name == "绍兴诸暨市浦阳江" || name == "温州市龙湾区") { // InPanel inpanel = UIManager.Instance.ShowPanel(); // inpanel.setImage(clicked.name); // UIManager.Instance.HidePanel(); } } else { Debug.Log("点击了非中心图,不响应点击"); } } } }