using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using DevelopEngine; using UnityEngine.UI; using UnityEngine.Events; using System.Threading.Tasks; //必须保证Map大于Mask public class MyDragMap :MonoBehaviour,IPointerDownHandler,IDragHandler,IPointerUpHandler,IScrollHandler { private Vector2 offsetPos; //临时记录点击点与UI的相对位置 private RectTransform rectTransform; private Vector2 parentSize; private Vector2 thisSize= new Vector2(8192,8192); [SerializeField] float maxScale = 3; [SerializeField] float minScale = 1; RawImage thisImage; bool canDrag; float terrainSize = 10000f;//地形横边长 单位M float mapScale=10000f/8000f;//地图和地形之间的比例尺 public Texture Texture { get { return thisImage.texture; } } // Start is called before the first frame update void Awake() { thisImage = this.GetComponent(); } /// /// 设置需要异步加载图片的完整路径 /// public async Task SetTextureAsyncPath(string path) { Texture2D texture = await OutSpriteLoader.LoadTexture(path); if (texture != null) { SetTexture(texture); return true; } else { return false; } } /// /// 设置地图当前图片 /// /// public void SetTexture(Texture2D texture) { thisImage.texture = texture; thisImage.SetNativeSize(); InitSize(); } //图片加载完成后 或图片尺寸发生变化时需调用 否则可能导致地图拖拽功能异常 public void InitSize() { parentSize = this.transform.parent.GetComponent().rect.size; rectTransform = this.GetComponent(); thisSize = rectTransform.sizeDelta; minScale = parentSize.x/ thisSize.x; maxScale = thisSize.x / 3300; //if (thisSize.x > 5000) // maxScale = thisSize.x / 5000; //else // maxScale = 5000 / thisSize.x; mapScale = terrainSize / thisSize.x; rectTransform.localScale = new Vector3(minScale, minScale, 1); rectTransform.anchoredPosition = new Vector2(0,0); MapHelper.InitHelper(new Vector2(terrainSize, terrainSize), thisSize);//初始化地图转换信息 } //需保持子物体大于父物体 public void OnDrag(PointerEventData eventData) { if (!canDrag) return; transform.position = eventData.position - offsetPos; ClampPostion(); } private void ClampPostion() { Vector2 anchoredPosition = rectTransform.anchoredPosition; float xClamp = (thisSize.x * rectTransform.localScale.x - parentSize.x) / 2; float yClamp = (thisSize.y * rectTransform.localScale.y - parentSize.y) / 2; if (anchoredPosition.x > xClamp) anchoredPosition.x = xClamp; if (anchoredPosition.x < -xClamp) anchoredPosition.x = -xClamp; if (anchoredPosition.y > yClamp) anchoredPosition.y = yClamp; if (anchoredPosition.y < -yClamp) anchoredPosition.y = -yClamp; rectTransform.anchoredPosition = anchoredPosition; } public void OnPointerDown(PointerEventData eventData) { canDrag = true; offsetPos = eventData.position - (Vector2)transform.position; } public void OnPointerUp(PointerEventData eventData) { canDrag = false; } public void OnScroll(PointerEventData eventData) { float delX = Input.mousePosition.x - transform.position.x; float delY = Input.mousePosition.y - transform.position.y; float scaleX = delX / rectTransform.rect.width / transform.localScale.x; float scaleY = delY / rectTransform.rect.height / transform.localScale.y; float scroell = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroell) > 0.05f ) { float scale = rectTransform.localScale.x; float newScale = scale+ scroell; newScale = Mathf.Clamp(newScale, minScale, maxScale); if (scale == newScale)//未发生缩放时不调整位置 避免出现滚轮导致位置移动 return; Vector2 mouseAnchoredPostion = Vector2.zero; RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, null, out mouseAnchoredPostion); // Debug.Log(mouseAnchoredPostion); rectTransform.anchoredPosition -= mouseAnchoredPostion * (newScale-scale);//触发clamp时未完全按照scroll发生变化 因此需计算实际变量 rectTransform.localScale = new Vector3(newScale, newScale, 1); ClampPostion(); } } }