unity3D MiniMap等比例對映的實現(二) 通過RawImage UV資訊控制小地圖的移動
阿新 • • 發佈:2019-02-08
上一篇為大家介紹了Image簡單的實現Player的移動並對映到小地圖上:上篇連結點選開啟連結
本篇為大家分享的是通過RawImage來實現實現小地圖的縮放:最終實現效果Player的移動會控制RawImage的UV資訊的改變使得RawImage移動,呈現一下最終效果:
具體UI的調整適配這裡我就不多介紹了,介面的佈局調整可以看上一篇 這裡只是將Image換成了RawImage去實現,用面板Plane來代替記得加Collider哦
一般情況下我們用RawImage去實現精靈動畫當然也是通過UV資訊的大小調整
UVRect:X Y 表示比例的起點 ;W H表示比例的寬和高
WH用來調節小地圖的事業範圍: 比如這裡我除錯的WH設定為0.25,0.25就將RawImage縮小了0.25,在Canvas下始終顯示圖片的1/4.
XY用來控制小地圖的移動,也是與Player的位置實時更新的
但是以上操作為發現一個問題就是當移動到邊界時會暴露,超出視野,當然真實專案中是絕對不允許這種的,你可以偷個懶一般RPG場景的的邊緣留出來這些可能暴露的範圍,讓玩家限定範圍不在場景邊緣移動就好啦~當然也不是沒有解決的辦法using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class TestMap : MonoBehaviour { public Transform player; public Transform myTerrain; Collider myTerrainCol; RectTransform litMap; RectTransform sonRect; float widthRate; float heightRate; RawImage rawImage; Vector3 tmpAngle; float timeCount = 0; Rect rowRect; void Start() { myTerrain = GameObject.FindGameObjectWithTag("Terrian").transform; myTerrainCol = myTerrain.GetComponent<Collider>(); litMap = transform.parent.GetComponent<RectTransform>(); sonRect = transform.GetComponent<RectTransform>(); rawImage = transform.parent.GetComponent<RawImage>(); } void Update() { timeCount += Time.deltaTime; if (timeCount > 0.5f) { timeCount = 0; UpdatePos(); } } void UpdatePos() { widthRate = (player.transform.position.x - myTerrain.position.x) / myTerrainCol.bounds.size.x; heightRate = (player.transform.position.z - myTerrain.position.z) / myTerrainCol.bounds.size.z; //這是相對於RawImage的偏移量 根據UV取得的WH比例比如WH為0.25,那麼加的位移偏移量為0.5-1/8=0.375 WH為0.5那麼加的位移偏移量為0.5-1/4=0.25 rowRect = rawImage.uvRect; rowRect.x = widthRate + 0.375f; rowRect.y = heightRate + 0.375f; rawImage.uvRect = rowRect; tmpAngle = sonRect.localEulerAngles; tmpAngle.z = 90 - player.localEulerAngles.y; sonRect.localEulerAngles = tmpAngle; } }
這時我們就要加限制條件了,有兩種實現方法:
方案一:你可以在要暴露的範圍控制WH的範圍,越往邊界走,調節WH的可視範圍越大;
方案二:通過調節當要超出事業範圍時控制UV資訊的XY不再發生改變,而是通過調節Player的移動位置更新,實現方法就和Image更新位置的操作一樣了,
但是這個限定條件個人覺得很繁瑣,要加多層判定,這裡只提供大致思路 我做了幾個判定後發現可以限定視野不會暴露,但是PlayerIcon的位置會有微小的不同步,自己測試一下就好了
以下是我做了視野不會超出視野範圍的限定,實現效果就是我前面附上的動圖操作,也許你有更好的解決方案歡迎交流
下一篇我將會向大家介紹第三種實現等比例對映小地圖的方案------通過ScrollView去實現
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestMap : MonoBehaviour
{
public Transform player;
public Transform myTerrain;
Collider myTerrainCol;
RectTransform litMap;
RectTransform sonRect;
float widthRate;
float heightRate;
RawImage rawImage;
Vector3 tmpAngle;
float timeCount = 0;
Rect rowRect;
Vector2 tmpPos = Vector2.zero;
void Start()
{
myTerrain = GameObject.FindGameObjectWithTag("Terrian").transform;
myTerrainCol = myTerrain.GetComponent<Collider>();
litMap = transform.parent.GetComponent<RectTransform>();
sonRect = transform.GetComponent<RectTransform>();
rawImage = transform.parent.GetComponent<RawImage>();
}
void Update()
{
timeCount += Time.deltaTime;
if (timeCount > 0.5f)
{
timeCount = 0;
UpdatePos();
}
}
void UpdatePos()
{
widthRate = (player.transform.position.x - myTerrain.position.x) / myTerrainCol.bounds.size.x;
heightRate =(player.transform.position.z - myTerrain.position.z) / myTerrainCol.bounds.size.z;
// rowRect = rawImage.uvRect;
// rowRect.x = widthRate +0.375f;
// rowRect.y = heightRate +0.375f;
// rawImage.uvRect = rowRect;
rowRect = rawImage.uvRect;
if (widthRate + 0.375f > 0f && widthRate + 0.375f < 0.75f && heightRate + 0.375f > 0 && heightRate + 0.375f < 0.75f)
{
rowRect.x = widthRate + 0.375f;
rowRect.y = heightRate + 0.375f;
}
else
{
if (widthRate + 0.375f <= 0f)
{
rowRect.x = 0;
}
else if (widthRate + 0.375f >= 0.75)
{
rowRect.x = 0.75f;
}
else if (heightRate + 0.375f >= 0.75)
{
rowRect.y = 0.75f;
}
else if (heightRate + 0.375f <= 0f)
{
rowRect.y = 0;
}
//tmpPos.x = litMap.sizeDelta.x * widthRate;
//tmpPos.y = litMap.sizeDelta.y * heightRate;
//sonRect.anchoredPosition = tmpPos;
}
rawImage.uvRect = rowRect;
Debug.Log("rowRect==="+rowRect);
Debug.Log("rawImage.uvRect===" + rawImage.uvRect);
tmpAngle = sonRect.localEulerAngles;
tmpAngle.z = 90 - player.localEulerAngles.y;
sonRect.localEulerAngles = tmpAngle;
}
}