Single Image Map Pan/Zoom & Coordinates
Hello to whomever may be reading this,
I'm currently working on a mobile game that has a map integration and the map i've got consists of a single image (Converted to Sprite in Unity on import). I have this, currently, set as an image component of a Panel which is toggled on and off with a button.
This all being well and good, I can't find the best way to provide zoom and pan functionality around the map.
I'd like the player to be able to use one finger to slide and pan across the map, and pinch two fingers together to zoom in or out. This is something i've seen done, and there's of course ways i've found to apply this to a 3D environment, however i'm unsure as to whether that's the best practise within the 'map mode' as i've aptly named it.
Then comes my second obstacle, which is the placing of waypoints and key points of interest. This, however, I have deemed may be best to do by utilising some form of data type such as an array, list e.t.c. or even a json file with multiple parameters for each waypoint, being; Image, Coordinates, Name and so on. However, again, is this the best way to go about this? And if so, what's the best way to calculate the coordinates of the image? Should I use pixel coordinates?
Thank you so much,
Kye Jones :)
Answer by KwinkyWolf · May 25, 2020 at 05:47 PM
Alright, so after a bit of fiddling around I've solved half of this question with this lot of code...
using UnityEngine;
using UnityEngine.UI;
public class MapMove : MonoBehaviour
{
public GameObject panel; // The panel
public float zoomSpeed; // The rate of change of the canvas scale factor
public float min;
public float max;
public Vector2 screenSize;
void Start()
{
screenSize = new Vector2(Screen.width, Screen.height);
}
void Update()
{
// Zooming
if (Input.touchCount == 2)
{
// Store both touches.
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
// Find the position in the previous frame of each touch.
Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
// Find the magnitude of the vector (the distance) between the touches in each frame.
float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;
// Find the difference in the distances between each frame.
float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;
// Create new Vector3 for the change
Vector3 difference = new Vector3();
difference.x = deltaMagnitudeDiff * zoomSpeed;
difference.y = deltaMagnitudeDiff * zoomSpeed;
difference.z = deltaMagnitudeDiff * zoomSpeed;
// ... change the canvas size based on the change in distance between the touches.
panel.transform.localScale -= difference;
// Clamp the scale
panel.transform.localScale = new Vector3(
Mathf.Clamp(panel.transform.localScale.x, min, max),
Mathf.Clamp(panel.transform.localScale.y, min, max),
1
);
}
// Panning
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
panel.transform.position -= touchDeltaPosition;
Vector2 imageSize = panel.GetComponent<RectTransform>().sizeDelta;
imageSize = panel.transform.localScale * imageSize;
// Clamp the location
float minX = -Mathf.Abs((imageSize.x / 2) / 2);
float maxX = Mathf.Abs((imageSize.x / 2) / 2);
float minY = -Mathf.Abs((imageSize.y / 2) / 2);
float maxY = Mathf.Abs((imageSize.y / 2) / 2);
Vector3 newSlide = panel.GetComponent<RectTransform>().anchoredPosition;
if (newSlide.x >= maxX) {
newSlide.x = maxX;
panel.GetComponent<RectTransform>().anchoredPosition = newSlide;
}
else if (newSlide.x <= minX)
{
newSlide.x = minX;
panel.GetComponent<RectTransform>().anchoredPosition = newSlide;
};
if (newSlide.y >= maxY) {
newSlide.y = maxY;
panel.GetComponent<RectTransform>().anchoredPosition = newSlide;
}
else if (newSlide.y <= minY)
{
newSlide.y = minY;
panel.GetComponent<RectTransform>().anchoredPosition = newSlide;
};
}
}
}
Your answer
Follow this Question
Related Questions
How to make a gameobject clickable in a certain radius 1 Answer
Script doesn't let me disable a second panel and I cant find a way around this. 0 Answers
How Can i Get This bool to work? Just need someone willing to explain. 2 Answers
AddListener fuction throwing a NullReferenceException error 1 Answer