private void DrawMapIcon(Vector3 worldPosition, MapIcon icon, bool keepOnMap) { if (!icon || !UI || !UI.gameObject) { return; } //把相机视野内的世界坐标归一化为一个裁剪正方体中的坐标,其边长为1,就是说所有视野内的坐标都变成了x、z、y分量都在(0,1)以内的裁剪坐标 Vector3 viewportPoint = MapCamera.WorldToViewportPoint(worldPosition); //这一步用于修正UI因设备分辨率不一样,在进行缩放后实际Rect信息变了而产生的问题 Rect screenSpaceRect = ZetanUtility.GetScreenSpaceRect(UI.mapRect); //获取四个顶点的位置,顶点序号 // 1 ┏━┓ 2 // 0 ┗━┛ 3 Vector3[] corners = new Vector3[4]; UI.mapRect.GetWorldCorners(corners); //根据归一化的裁剪坐标,转化为相对于地图的坐标 Vector3 screenPos = new Vector3(viewportPoint.x * screenSpaceRect.width + corners[0].x, viewportPoint.y * screenSpaceRect.height + corners[0].y, 0); Vector3 rangePos = screenPos; if (keepOnMap) { //以遮罩的Rect为范围基准而不是地图的 screenSpaceRect = ZetanUtility.GetScreenSpaceRect(MapMaskRect); float size = (screenSpaceRect.width < screenSpaceRect.height ? screenSpaceRect.width : screenSpaceRect.height) * 0.5f;//地图的一半尺寸 UI.mapWindowRect.GetWorldCorners(corners); if (circle && !isViewingWorldMap) { //以下不使用UI.mapMaskRect.position,是因为该position值会受轴心(UI.mapMaskRect.pivot)位置的影响而使得最后的结果出现偏移 Vector3 realCenter = ZetanUtility.CenterBetween(corners[0], corners[2]); Vector3 positionOffset = Vector3.ClampMagnitude(screenPos - realCenter, radius * size); screenPos = realCenter + positionOffset; } else { float edgeSize = (isViewingWorldMap ? worldEdgeSize : this.edgeSize) * size; screenPos.x = Mathf.Clamp(screenPos.x, corners[0].x + edgeSize, corners[2].x - edgeSize); screenPos.y = Mathf.Clamp(screenPos.y, corners[0].y + edgeSize, corners[1].y - edgeSize); } } icon.transform.position = screenPos; if (icon.iconRange) { icon.iconRange.transform.position = rangePos; } }