由于之前做的作品UI都不太好看,开始学习了一下UI的制作。这次想做一个类似http://www.tasharen.com/ngui/exampleX.html 里的背包界面,就游戏中点开换装备的UI。
我实现后的UI是这样的:
一个是装备拖拽功能,效果图(由于大小限制,我只能缩小一下动态图了):
还有就是Random wearing功能(左上角的按钮),按下去后就会在装备栏(左边)生成装备。
好了,接下来是实现。
乍一看是不是挺高大上的感觉挺难实现的,等我先讲一下实现的思路先,装备栏还有背包栏以及左上角的按钮都是button来的。也就是说这些功能都是button触发事件的逻辑实现的。具体的装备嘛,也就是button的背景图而已。雪花是默认的粒子系统,人物是商店免费下载,然后各个模块显示的前后问题,就是摄像机的问题了,用多个不同depth的摄像机就可以了,比如我用了三个,一个给背景图,一个给装备栏背包栏,一个给人物。还有一个看起来比较难的问题,就是拖拽装备怎么实现的,这个确实需要一个比较巧妙的方法,我从一开始就生成一个稍微大一点的UI的image设为透明的,然后由始到终都跟着鼠标移动,只有当鼠标点击到了有装备的栏,这个image的背景图就会变成相应的图片,然后点到一个空的栏,如果能放的话,image就重新变回透明的空白。
理清思路后是不是觉得容易了很多?
好了,接下来是具体实现了。
先总体看一下需要什么先:
就按照这个顺序讲吧
UICamera是用来现实装备栏被包栏等界面的,要拖到Scene的Event Camera处。修改了一下Clear Flags和Culling Mask等参数,这个摄像机的参数如下:
接下来是Scene部分,Scene是一个Canvas,注意要把Render Mode设成World Space,还有挂载上面的摄像机,参数如图:
然后里面的元素有:
Bag是背包栏,euqipment是装备栏,Random是左上角的装备生产按钮。两个Text分别是背包栏和装备栏的title,Mouse_Image就是上面所说的一直跟着鼠标移动的图片了。
Bag,equipment都是Panel,然后在里面生成相应数量的button,背包栏以及装备栏还有它们的button之一参数分别如下:
接着Random是button,Mouse_Image是Image,Mouse_Image参数为:
接下来的SFSceneElements是一个空对象,在里面生成一个摄像机,一个粒子系统以及一个空对象background(用来放背景图的)。
摄像机参数为(culling mask去掉UI):
背景:
粒子系统就默认就好。
接下来的是显示英雄的摄像机参数:
下载后的人物预设直接拖到摄像机就可以了。
接下来是行为逻辑的实现,首先是画面根据鼠标移动而漂浮的功能。代码如下:
using UnityEngine;
public class TiltWindow : MonoBehaviour
{
public Vector2 range = new Vector2(5f, 3f);
Transform mTrans;
Quaternion mStart;
Vector2 mRot = Vector2.zero;
void Start()
{
mTrans = transform;
mStart = mTrans.localRotation;
}
void Update()
{
Vector3 pos = Input.mousePosition;
float halfWidth = Screen.width * 0.5f;
float halfHeight = Screen.height * 0.5f;
float x = Mathf.Clamp((pos.x - halfWidth) / halfWidth, -1f, 1f);
float y = Mathf.Clamp((pos.y - halfHeight) / halfHeight, -1f, 1f);
mRot = Vector2.Lerp(mRot, new Vector2(x, y), Time.deltaTime * 5f);
mTrans.localRotation = mStart * Quaternion.Euler(-mRot.y * range.y, mRot.x * range.x, 0f);
}
}
我把这个挂到了Bag和Equipment上。
接下来是关于物品拖拽的实现,主要思路就是,当鼠标点击button,如果button上有贴图同时鼠标没图片,那么鼠标的Image变成button背景图的图片同时button背景图变成空白且透明。如果点击的时候,button处于空物品状态,并且鼠标上有贴图,那么,鼠标上贴图贴在UIbutton上同时鼠标上图片变回空白且透明。
uml图如下:
新建一个Mouse代码如下,挂在到一个新的空对象Maneger上。
using UnityEngine;
using System.Collections;
using Game_Manager;
namespace Game_Manager
{
public class Game_Scene_Manager : System.Object
{
private static Game_Scene_Manager _instance;
private static Mouse_Image _Mouse;
private int IsHair = 0;
private int IsWeapon = 0;
private int IsFoot = 0;
public static Game_Scene_Manager GetInstance()
{
if (_instance == null)
{
_instance = new Game_Scene_Manager();
}
return _instance;
}
public void SetMouse(Mouse_Image _mouse)
{
if (_Mouse == null)
{
_Mouse = _mouse;
}
}
public Mouse_Image GetMouse()
{
return _Mouse;
}
public void GenAll()
{
IsFoot = 1;
IsHair = 1;
IsWeapon = 1;
}
public int GetHair() { return IsHair; }
public int GetWeapon() { return IsWeapon; }
public int GetFoot() { return IsFoot; }
public void SetHair(int a) { IsHair = a; }
public void SetWeapon(int a) { IsWeapon = a; }
public void SetFoot(int a) { IsFoot = a; }
}
}
public class Mouse : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
接下来是代码equip,挂载到装备栏的每一个button上(注意head,hand,foot对应button的mouse_type分别设为1,2,3)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using Game_Manager;
public class equip : MonoBehaviour
{
private Game_Scene_Manager gsm;
private Image equip_image;
public int mouse_type;
public Sprite weapon;
public Sprite UISprite;
public Color weapon_color;
public Color UISprite_color;
void Awake()
{
gsm = Game_Scene_Manager.GetInstance();
equip_image = GetComponent<Image>();
}
public void OnButton()
{
int MouseType = gsm.GetMouse().GetMouseType();
if (equip_image.sprite == weapon && (MouseType == 0 || MouseType == mouse_type))
{
equip_image.sprite = UISprite;
equip_image.color = UISprite_color;
gsm.GetMouse().SetMouseType(mouse_type);
}
else
{
if (MouseType == mouse_type)
{
equip_image.sprite = weapon;
equip_image.color = weapon_color;
gsm.GetMouse().SetMouseType(0);
}
}
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (mouse_type == 1 && gsm.GetHair() == 1)
{
gsm.SetHair(0);
equip_image.sprite = weapon;
equip_image.color = weapon_color;
}
else if (mouse_type == 2 && gsm.GetWeapon() == 1)
{
gsm.SetWeapon(0);
equip_image.sprite = weapon;
equip_image.color = weapon_color;
}
else if (mouse_type == 3 && gsm.GetFoot() == 1)
{
gsm.SetFoot(0);
equip_image.sprite = weapon;
equip_image.color = weapon_color;
}
}
}
MyBag就挂载到背包栏的每一个button上
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using Game_Manager;
public class MyBag : MonoBehaviour
{
private Game_Scene_Manager gsm;
private Image bag_image;
public int mouse_type = 0;
public Sprite hair;
public Sprite weapon;
public Sprite foot;
public Sprite UISprite;
public Color weapon_color;
public Color UISprite_color;
void Awake()
{
gsm = Game_Scene_Manager.GetInstance();
bag_image = GetComponent<Image>();
}
public void OnButton()
{
int MouseType = gsm.GetMouse().GetMouseType();
if (bag_image.sprite != UISprite && (MouseType == 0 || MouseType == mouse_type))//取出来
{
bag_image.sprite = UISprite;
bag_image.color = UISprite_color;
gsm.GetMouse().SetMouseType(mouse_type);
mouse_type = 0;
}
else//放进去
{
if (MouseType == 1) bag_image.sprite = hair;
else if (MouseType == 2) bag_image.sprite = weapon;
else if (MouseType == 3) bag_image.sprite = foot;
mouse_type = MouseType;
bag_image.color = weapon_color;
gsm.GetMouse().SetMouseType(0);
}
}
}
到了挂载到鼠标上Image的代码:
using UnityEngine;
using System.Collections;
using Game_Manager;
using UnityEngine.UI;
public class Mouse_Image : MonoBehaviour
{
private Game_Scene_Manager gsm;
private Image mouse_image;
private int mouse_type = 0;
public Sprite none;
public Sprite hair;
public Sprite weapon;
public Sprite foot;
public Color None;
public Color NotNone;
public Camera cam;
void Awake()
{
gsm = Game_Scene_Manager.GetInstance();
gsm.SetMouse(this);
mouse_image = GetComponent<Image>();
}
public int GetMouseType()
{
return mouse_type;
}
public void SetMouseType(int Mouse_type)
{
mouse_type = Mouse_type;
}
void Update()
{
if (mouse_type == 0)
{
mouse_image.sprite = none;
mouse_image.color = None;
}
else
{
mouse_image.color = NotNone;
if (mouse_type == 1) mouse_image.sprite = hair;
else if (mouse_type == 2) mouse_image.sprite = weapon;
else if (mouse_type == 3) mouse_image.sprite = foot;
}
transform.position = new Vector3(Input.mousePosition.x - 960, Input.mousePosition.y - 208, 0);
}
}
最后是挂到Random按钮上的代码:
using UnityEngine;
using System.Collections;
using Game_Manager;
using UnityEngine.UI;
public class GenThings : MonoBehaviour
{
private Game_Scene_Manager gsm;
public void OnButton()
{
gsm.GenAll();
}
void Awake()
{
gsm = Game_Scene_Manager.GetInstance();
}
}
这样就大功告成了,由于时间问题,给人物真实换上装备的画面就不实现了。