这次制作了一个切换装备的UI界面,首先上效果图
有点恐怖,嘿嘿,下面说一下制作思路
新建一个空对象命名为SF Scene Elements,里面包含一个main camera,一个空对象BackGround,一个粒子系统。 在BackGround中添加Sprite Renderer组件,将选好的背景添加。 值得注意,我一开始下载的是图片资源,怎么都不能挂到Sprite上,后来知道要将图片的Texture Type改为Sprite才行 调整粒子系统,做出比较炫酷的样子,点击播放可以查看效果
自然,首先想到的就是将我们的骷髅兵放在相对于main camera合适的位置。但是通过老师的指引,我发现了一种更好的办法:用摄像机的叠加渲染效果。 原理很简单,当一个游戏场景中包含多个摄像机时,会根据摄像机组件Depth的大小决定渲染顺序。那么我们就可以先用一个摄像机把背景渲染出来,然后再用另外一个摄像机把骷髅兵(不包括天空盒)渲染出来,就可以达到效果。 新建一个摄像机为Hero Camera,把它放到十分遥远的地方(反正和其余游戏对象都没有关联就行),将Clear Flags设为Depth only,这样它就不会渲染天空盒。 由于这个摄像机是很遥远的,只会渲染骷髅兵,其他的游戏对象不会进入它的视角范围内,所以Culing Mask可以设为Everything。 然后把骷髅兵作为这个摄像机的子对象加入,调整位置,再为骷髅兵添加动画 如图,骷髅兵是在画布后面被渲染的,作为我们的幕后英雄,它的渲染效果是这样的(它会动的,我不会录视频….)
这里说一下我对用不同相机渲染游戏的理解:这样可以将游戏中相应的模块独立出来,以后可以拿来继续使用,有良好的延续性。其次,功能独立,这样便于游戏的设计
可以看出游戏中包含两个UI界面,一个是装备栏,一个是背包栏,首先新建一个画布Canvas,里面添加一个子对象Panel,Panel中包含这两个UI界面,Bag,Equipment应该也同样为Panel
Bag里有九个格子,Equipment有三个,可以通过Grid Layout Group组件来实现,由于点击需要触发事件,所以我把这些格子都设为了Button,设置相关参数,比如Equipment的Hand(Grid Layout Group其实已经把位置规定好了,只需要调整文本位置和图片就行)
同样用到了多摄像头渲染的原理,与Scene画布同级创建一个摄像机,设定作用层为UI 可以在右下角窗口看到,UI Camera拍到的内容 设置完这一切我们就可以达到一开始图片的效果了
你以为这样就完了吗,不不不。既然作为切换装备的UI界面,装备要是不能切换岂不是欺骗人民群众。结合相关案例分析,我的思路是: 有一个单例模式下形成的类Mouse记录当前选取的装备 一个Equip类挂载到每一个装备按钮上定义装备栏点击触发事件 一个MyBag类挂载到每一个背包按钮上定义背包栏点击触发事件 一个Equipment类记录当前鼠标选取的装备。
获取当前鼠标选取的装备
using UnityEngine; using System.Collections; using Game_Manager; namespace Game_Manager { public class EquipmentManager : System.Object { private static EquipmentManager _instance; private static Equipment _Equipment; public static EquipmentManager GetInstance() { if (_instance == null) { _instance = new EquipmentManager(); } return _instance; } public void SetEquipment(Equipment _equipment) { if (_Equipment == null) { _Equipment = _equipment; } } public Equipment GetEquipment() { return _Equipment; } } } public class Mouse : MonoBehaviour { // Use this for initialization void Start() { } // Update is called once per frame void Update() { } }创建一个空对象Manager挂载
我将它挂载到一个Image对象上(简陋版…),让它时时跟随鼠标移动,但是如果没有选取装备,则将这个对象颜色设为透明,如果选取了装备,则设为不透明。关于装备种类有三种,用int类型来区分:
1:盾牌2:武器3:战靴 using UnityEngine; using System.Collections; using UnityEngine.UI; using Game_Manager; public class Equipment : MonoBehaviour { private EquipmentManager gsm; private Image Equipment_image; private int Equipment_type = 0; public Color None; public Color NotNone; void Awake() { gsm = EquipmentManager.GetInstance(); gsm.SetEquipment(this); Equipment_image = GetComponent<Image>(); } public int GetEquipmentType() { return Equipment_type; } public void SetEquipmentType(int equipment_type) { Equipment_type = equipment_type; } public Image GetImage() { return Equipment_image; } void Update() { if (Equipment_type == 0) // 什么都不是 { Equipment_image.color = None; // 透明颜色 } else { Equipment_image.color = NotNone; // 不透明,可见 } transform.position = new Vector3(Input.mousePosition.x - 425, Input.mousePosition.y - 165, 0); } }有一个int类型的种类信息记录装备的类型,这样在给人物添加对应种类装备错误时就不会放上去,这样可以避免人物把剑当鞋子之类的乌龙。拿走装备前提是鼠标当前没有选取装备,佩戴装备前提是鼠标选取了与对应装备栏种类相同的装备。关于拿走装备骷髅兵会脱掉相应装备,佩戴装备骷髅兵会穿上装备的实现也很简单,就是将相关组件disable掉或者重新激活,因此需要一个GameObject对象,挂上对应的对象组件就行
using UnityEngine; using System.Collections; using UnityEngine.UI; using Game_Manager; public class Equip : MonoBehaviour { private EquipmentManager gsm; private Image equip_image; public int Equipment_type; public Sprite IdelSprite; public GameObject equipment; void Awake() { gsm = EquipmentManager.GetInstance(); equip_image = GetComponent<Image>(); } public void On_equip_Button() // 按钮被按触发事件 { int EquipmentType = gsm.GetEquipment().GetEquipmentType(); if (equip_image.sprite != IdelSprite && EquipmentType == 0) // 装备栏有武器时,抓取,此时要求没有选中任何武器所以MouseType要为0 { gsm.GetEquipment().GetImage().sprite = equip_image.sprite; equip_image.sprite = IdelSprite; gsm.GetEquipment().SetEquipmentType(Equipment_type); if (equipment != null) equipment.SetActive(false); } else { if (EquipmentType == Equipment_type && equip_image.sprite == IdelSprite) // 放置到装备栏,此时要求装备栏中该位置为空闲,否则原来的武器会消失 { equip_image.sprite = gsm.GetEquipment().GetImage().sprite; gsm.GetEquipment().SetEquipmentType(0); if (equipment != null) equipment.SetActive(true); } } } }比如盾牌装备栏 这里的Bip01 L就是骷髅兵的盾牌对象。同时记得给On Click登记相应事件
由于MyBag会随时放置不同种类的装备,所以也会包含一个int类型的Element_Type记录当前所放的装备类型,当物品放置到背包时,Equipment类就会把对应装备的种类传给背包,同理,取出装备时背包会将装备类型传给Equipment类。
using UnityEngine; using System.Collections; using UnityEngine.UI; using Game_Manager; public class MyBag : MonoBehaviour { private EquipmentManager gsm; private Image bag_image; public int Equipment_type = 0; public Sprite IdelSprite; void Awake() { gsm = EquipmentManager.GetInstance(); bag_image = GetComponent<Image>(); } public void On_equip_Button() { int EquipmentType = gsm.GetEquipment().GetEquipmentType(); if (bag_image.sprite != IdelSprite && EquipmentType == 0) // 该处有装备,拿走 { gsm.GetEquipment().GetImage().sprite = bag_image.sprite; bag_image.sprite = IdelSprite; gsm.GetEquipment().SetEquipmentType(Equipment_type); Equipment_type = 0; } else { if (bag_image.sprite == IdelSprite) { bag_image.sprite = gsm.GetEquipment().GetImage().sprite; Equipment_type = EquipmentType; gsm.GetEquipment().SetEquipmentType(0); } } } }所以,背包中的装备、装备种类值只能通过预处理阶段或者后期和Equipment类合作修改
这个类可以使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); } }取走盾牌放入背包(只能放入空闲背包,不然不会让你放入),骷髅兵:“咦,我的盾牌呢” 给骷髅兵换上一面新盾牌,骷髅兵:“哦,在这啊”
把盾牌和剑都取下来,骷髅兵:“天啊,我撞鬼啦”
装上新的盾牌(放到剑栏就不会有反应,拒绝放入) 骷髅兵:“我像不像美国队长”
鞋嘛,这货没穿鞋,我就不演示了,同时UI框也朝向了鼠标移动的位置,反正截图看不出来(信我啊)
本次实验加深了我对摄像机使用的理解(多层渲染)。对于UI的设计其实很简单,无论美术功底好不好都能创造出不错的UI界面,很多UI对象的功能我都不是很熟悉,都是后期不断尝试最后弄清楚的,对于计算机类实验,不要害怕尝试,要大胆探索,unity中有很多有趣的东西,是官方手册说不完的,还需要我们更深入的探索。本次实验我参考了较多的案例,有很多自己的理解,欢迎大家提出意见,我好予以改正!
