之前学习的时候,也学习了小地图的制作,后来过了好长时间就忘记怎么弄。看了 siki老师小地图视频就跟着学习了。视频是14年的siki老师用的还是NGUI制作的,然后我就改成用UGUI制作的,下面就是我的 制作过程。
第一种方式:利用Shader实现
先说一下思路,我们在每个角色(Player和Enemy)头顶上放一张面片、用另一个相机根据Layer渲染,这里我们只渲染面片和地面,就完成了用面片替代角色的作用。
先看一下第一种的效果
1、场景制作
这里我用 Capsule作为Player和Enemy的替代。布阵场景如图
2、相机设置
3.MiniMapMaterial制作
4.UGUI小地图
第二中方式:实时计算相对位置
先看一下第二种的效果
第二种主要使用代码实现的
下面是具体代码
Player角色位移脚本
using UnityEngine;
/// <summary>using UnityEngine;
using UnityEngine.UI;
public class MiniMap : MonoBehaviour
{
//MinMap单例
public static MiniMap Instance;
//Icon预置体
private GameObject _iconPrefab;
//Sprite预置体
private Sprite _spritePrefab;
//Icon的父物体
private Transform parent;
// Use this for initialization
private void Awake()
{
Instance = this;
_iconPrefab = Resources.Load("Icon") as GameObject;
parent = GameObject.FindGameObjectWithTag("Parent").transform;
}
//根据名字产生不同的ICone
public GameObject CreateIcon(string iconName)
{
_spritePrefab = Resources.Load<Sprite>(iconName);
GameObject go = Instantiate(_iconPrefab);
go.GetComponent<Image>().sprite = _spritePrefab;
go.transform.SetParent(parent);
go.transform.position = parent.GetComponent<RectTransform>().position;
return go;
}
}
/// 控制角色位移/// </summary>public class PlayerMove : MonoBehaviour{ public float Speed = 4f; private float timer = 0; void Update() { float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); transform.Translate(new Vector3(h, 0, v) * Speed * Time.deltaTime); }} Enemy角色位移脚本
using UnityEngine;
/// <summary>
/// 控制Enemy位移
/// </summary>
public class EnemyMove : MonoBehaviour
{
public float Speed = 4f;
public float Duration = 4f;
private float timer = 0f;
private float dir_x = 0f;
private float dir_z = 0f;
void Update()
{
timer += Time.deltaTime;
if (timer >= Duration)
{
dir_x = Random.Range(-1f, 1f);
dir_z = Random.Range(-1f, 1f);
timer = 0f;
}
transform.Translate(new Vector3(dir_x, 0, dir_z) * Speed * Time.deltaTime);
}
}
MiniMap控制Icon产生脚本
using UnityEngine;
using UnityEngine.UI;
public class MiniMap : MonoBehaviour
{
//MinMap单例
public static MiniMap Instance;
//Icon预置体
private GameObject _iconPrefab;
//Sprite预置体
private Sprite _spritePrefab;
//Icon的父物体
private Transform parent;
// Use this for initialization
private void Awake()
{
Instance = this;
_iconPrefab = Resources.Load("Icon") as GameObject;
parent = GameObject.FindGameObjectWithTag("Parent").transform;
}
//根据名字产生不同的ICone
public GameObject CreateIcon(string iconName)
{
_spritePrefab = Resources.Load<Sprite>(iconName);
GameObject go = Instantiate(_iconPrefab);
go.GetComponent<Image>().sprite = _spritePrefab;
go.transform.SetParent(parent);
go.transform.position = parent.GetComponent<RectTransform>().position;
return go;
}
}
MiniMapItem控制小地图界面的脚本using UnityEngine;
using UnityEngine.UI;
public class MiniMapItem : MonoBehaviour
{
public string IconName;
public float Rate = 5f;
public GameObject _minMap;
private Transform _player;
private Transform _iconTrans;
private Color color;
private Color colorHide;
//是否要跟换Color标志
private bool isChange1 = false;
private bool isChange2 = false;
private void Start()
{
_minMap = MiniMap.Instance.CreateIcon(IconName);
_player = GameObject.FindGameObjectWithTag("Player").transform;
_iconTrans = _minMap.transform;
color = _iconTrans.GetComponent<Image>().color;
colorHide = new Color(color.r, color.b, color.b, 0);
}
//计算Palyer和自身的相对为,赋予到Icon的像素位置
private void FixedUpdate()
{
if (_minMap == null)
{
return;
}
Vector3 offset = transform.position - _player.position;
_iconTrans.localPosition = new Vector3(offset.x, offset.z, 0) * Rate;
}
//限定图标在固定区域出现
//运动限定区域外将图标的Color 的a=0
private void Update()
{
if (_minMap == null)
{
return;
}
//Mathf.Abs(_iconTrans.localPosition.x) > 150f || Mathf.Abs(_iconTrans.localPosition.y) > 150f
Vector3 vc = _iconTrans.localPosition;
float max = Mathf.Max(Mathf.Abs(vc.x), Mathf.Abs(vc.y));
if (Check(max, 150))
{
if (isChange1)
{
_iconTrans.GetComponent<Image>().color = colorHide;
isChange1 = false;
}
isChange2 = true;
}
else
{
if (isChange2)
{
_iconTrans.GetComponent<Image>().color = color;
isChange2 = false;
}
isChange1 = true;
}
}
//Enemy消亡同时将Icon Destory掉
private void OnDestroy()
{
GameObject.Destroy(_minMap);
}
private bool Check(float x, float limte)
{
if (x > limte)
{
return true;
}
else
{
return false;
}
}
}
终于写完了,哈哈。其实算不上完全的原创。主要还是看siki老师的视频制作的,自己稍微做了一点修改。
下面附带siki老师视频的地址链接:http://pan.baidu.com/s/1hswxHzA 密码:whev
我制作的下载地址链接:http://pan.baidu.com/s/1hsAAPRQ 密码:titk