您的位置:首页 > 移动开发 > Unity3D

unity3D MiniMap等比例映射的实现(二) 通过RawImage UV信息控制小地图的移动

2018-02-03 22:01 441 查看
上一篇为大家介绍了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的位置实时更新的

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;

}
}

但是以上操作为发现一个问题就是当移动到边界时会暴露,超出视野,当然真实项目中是绝对不允许这种的,你可以偷个懒一般RPG场景的的边缘留出来这些可能暴露的范围,让玩家限定范围不在场景边缘移动就好啦~当然也不是没有解决的办法



这时我们就要加限制条件了,有两种实现方法:

方案一:你可以在要暴露的范围控制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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐