Unity3d制作游戏背包系统
这一次背包系统很大程度上是参考这个博客进行制作,这篇博客写得很详尽很好,我相对来说增添了一些这里面没有贴出来的细节,大家可以参照着这一篇一起把游戏背包制作出来
http://blog.csdn.net/qq_20496459/article/details/51421360
任务
参考 http://www.tasharen.com/ngui/exampleX.html ,使用 UI 制作背包系统(武器装备系统)
看这个参考需要使用到unity web player,在旧版浏览器或者IE浏览器上可以下载unity web player使用查看
前提学习
这一次作业与前面学习到的知识:camera的使用、多camera的场景、newUI使用息息相关,所以需要先将这些基础知识了解,这里就贴一个camera的unity官方文档,其他的大家可以自己去查询;
http://wiki.ceeger.com/script/unityengine/classes/camera/camera?s[]=camera
制作效果
我的制作效果就没有参考的那么炫酷厉害了,不过基本的要求基本上都达到了~
制作过程
UI层的制作
可以看到,Scene是我的UI层,利用UI Camera渲染呈现,而UI层中存在的东西有:一张画布(UI panel)即scene,然后下面再有一张子画布,画布下有装备栏还有背包栏,也是UI panel;
而在Bag和Equipment画布下是一个一个UI button,能够得到想要的效果,其中Mouse_Image是用以展示贴到鼠标上的图片,这个在后面还会进行解释;
其中,装备栏和背包栏使用了Grid Layout Group组件,便于分格:
上图是Bag的组件设置,Equipment的类似;
其中注意所有的UI Camera渲染的都是UI层的,并且深度设置为介于Main Camera的层和Hero Camera的层之间,主要是因为我的UI层是起着遮挡Main Camera显示以及在其表面加上两个栏的作用,然后我们要先渲染Hero,防止Hero被遮挡;
UI Camera的组件设置如下:
将UI层布置好之后就紧接着开始布置SF Scene Element了;
SF Scene Element
这一层很简单,主要就是来放背景图片,然后再加一个粒子系统:
从Main Camera的预览图可以看到这就是我们这一层所要达到的效果;
我们只要把图片放在Background里面,然后加一个Particle System制造出一个神秘的背景即可;
这里需要注意的是,图片需要设置为Sprite才能够放入image组件中:
在这里MainCamera的组件设置如下,它的深度为最低的一个,因为它需要放在其他的后面,制造出一种虚幻的效果:
粒子系统,自然简单一点就好,不需要修改太多;
主角
主角我是从Asset Store中下载来的,从Asset Store中一搜人物模型,竟然就搜到跟参考博客一样的模型,提供一下链接给大家:
https://www.assetstore.unity3d.com/cn/#!/content/44041
其实还有很多很不错的资源,比如我看到有骷颅人、小野人等等;
是不是感觉这人物怎么放的这么奇怪,对的,人物是放在了图片和UI的背后,然后相机也在这背后,因为这一层只是需要渲染出人物这一个模型即可,其他的层放在那儿都是干扰,所以就直接放在这里,便于Hero Camera的渲染;
其中,大家可以通过切换成3D来看到这个视图,前面两个我都是用2D视图的;
Hero Camera的组件设置如下:
这样,通过三个camera就将最终需要的场景给渲染出来了,是不是很不错~!
接下来,就应该让那些装备栏里面的物体能够被移动,以及画布随着鼠标的变化而变化了~!
代码编写
首先利用了上课给的一个scripts,能够让画布跟随着鼠标变化:
1 using UnityEngine; 2 3 public class TiltWindows : MonoBehaviour 4 { 5 public Vector2 range = new Vector2(5f, 3f); 6 7 Transform mTrans; 8 Quaternion mStart; 9 Vector2 mRot = Vector2.zero; 10 11 void Start () 12 { 13 mTrans = transform; 14 mStart = mTrans.localRotation; 15 } 16 17 void Update () 18 { 19 Vector3 pos = Input.mousePosition; 20 21 float halfWidth = Screen.width * 0.5f; 22 float halfHeight = Screen.height * 0.5f; 23 float x = Mathf.Clamp((pos.x - halfWidth) / halfWidth, -1f, 1f); 24 float y = Mathf.Clamp((pos.y - halfHeight) / halfHeight, -1f, 1f); 25 mRot = Vector2.Lerp(mRot, new Vector2(x, y), Time.deltaTime * 5f); 26 27 mTrans.localRotation = mStart * Quaternion.Euler(-mRot.y * range.y, mRot.x * range.x, 0f); 28 } 29 }
接着,创建一个空对象并命名为Manager,在其下挂载Game_Manager代码,Game manager利用实例化,可用来联系各个类,并且能够让其他类很方便地使用它里面的函数:
1 using UnityEngine; 2 using System.Collections; 3 using Game_Manager; 4 5 namespace Game_Manager { 6 7 public class Game_Scene_Manager : System.Object { 8 private static Game_Scene_Manager _instance; 9 private static Mouse_Image _Mouse; 10 private int IsHair = 0; // 是否头部有装备 11 private int IsWeapon = 0; // 是否有武器装备 12 private int IsFoot = 0; // 是否有脚部装备 13 14 public static Game_Scene_Manager GetInstance() { 15 if (_instance == null) { 16 _instance = new Game_Scene_Manager(); 17 } 18 return _instance; 19 } 20 21 public void SetMouse(Mouse_Image _mouse) { 22 if (_Mouse == null) { 23 _Mouse = _mouse; 24 } 25 } 26 27 public Mouse_Image GetMouse() { 28 return _Mouse; 29 } 30 31 public void GenAll() { 32 IsFoot = 1; 33 IsHair = 1; 34 IsWeapon = 1; 35 } 36 37 public int GetHair() { return IsHair; } 38 public int GetWeapon() { return IsWeapon; } 39 public int GetFoot() { return IsFoot; } 40 41 public void SetHair(int a) { IsHair = a; } 42 public void SetWeapon(int a) { IsWeapon = a; } 43 public void SetFoot(int a) { IsFoot = a; } 44 } 45 46 } 47 48 public class Mouse : MonoBehaviour { 49 // Use this for initialization 50 void Start () { 51 52 } 53 54 // Update is called once per frame 55 void Update () { 56 57 } 58 }
还记得我们在UI层里面创建了一个Mouse_Image吗?它就是为了实现点击图片时,图片跟随鼠标移动的效果的,当鼠标点击一个背包栏,进行判定能够将图片移动后,图片会放入Mouse_Image中,Mouse_Image跟随着鼠标移动,因此就实现了这样的效果,其中Mouse_Image是UI Image类,需要在Mouse_Image下挂上这一个代码:
1 using UnityEngine; 2 using System.Collections; 3 using Game_Manager; 4 using UnityEngine.UI; 5 6 public class Mouse_Image : MonoBehaviour { 7 8 private Game_Scene_Manager gsm; 9 private Image mouse_image; 10 private int mouse_type = 0; 11 public Sprite none; 12 public Sprite hair; // 保存相应的装备 13 public Sprite weapon; // 保存相应的装备 14 public Sprite foot; // 保存相应的装备 15 public Color None; 16 public Color NotNone; 17 public Camera cam; 18 19 void Awake() { 20 gsm = Game_Scene_Manager.GetInstance(); 21 gsm.SetMouse(this); 22 mouse_image = GetComponent<Image>(); 23 } 24 25 public int GetMouseType() { 26 return mouse_type; 27 } 28 29 public void SetMouseType(int Mouse_type) { 30 mouse_type = Mouse_type; 31 } 32 33 void Update () { 34 if (mouse_type == 0) // 每一帧进行更新,检查鼠标上是否需要有装备,根据mousetype更新,如果mousetype为0则装备无 35 { 36 mouse_image.sprite = none; 37 mouse_image.color = None; 38 } 39 else 40 { // mousetype不为零,根据mousetype加上相应装备 41 //Debug.Log("I am mouse image"); 42 //Debug.Log(mouse_type); 43 44 mouse_image.color = new Color(1F, 1F, 1F, 1F); 45 //Debug.Log(mouse_image.color); 46 if (mouse_type == 1) mouse_image.sprite = hair; 47 else if (mouse_type == 2) mouse_image.sprite = weapon; 48 else if (mouse_type == 3) mouse_image.sprite = foot; 49 } 50 transform.position = new Vector3 (Input.mousePosition.x-600, Input.mousePosition.y-230, 0); 51 } 52 }
接下来就是背包栏的每一格点击会发生的事件了,若有装备在背包栏中,要么能够让装备转移到鼠标上,要么鼠标上已经有了图片,不能移动;若没有装备在此格中,则点击此格,如果鼠标上有装备,那么装备会放入背包栏中,如果鼠标上没有,那么什么也不发生,因此我们可以给背包栏的每一个格即UI Button添加一个script,装备栏也类似,不过装备栏中的每个格确定了装备应该是什么类型的;
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; // 0->没有装备,1...有不同装备 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 On_equip_Button() { Debug.Log("my bag click!"); int MouseType = gsm.GetMouse().GetMouseType(); // 得到鼠标目前的mousetype if (bag_image.sprite != UISprite && MouseType == 0) // 若鼠标没有图片在上面,并且bag的image不为空有装备,则取走bag_image的装备 { Debug.Log(mouse_type); bag_image.sprite = UISprite; bag_image.color = UISprite_color; gsm.GetMouse().SetMouseType(mouse_type); // 将当前装备的type给鼠标 mouse_type = 0; // 此背包的mousetype变为0,则当前背包啥都没有 } else { // 若鼠标上有装备,则改背包的image sprite改变,根据type变为不同装备图片 Debug.Log("my bag equipped!"); 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; // mousetype变为鼠标的mousetype bag_image.color = weapon_color; // 有装备了 gsm.GetMouse().SetMouseType(0); // 鼠标装备消失 } } }
上面是挂在bag的每一个Button上面的,其中bag中的组件设置,以及对这个script的变量设置要注意,我在这里就遇到了几个问题,其中weapon_color不要设置成为透明了,否则我们将装备移动的效果就看不到了,由于我的button是有颜色的,所以我的UISprite_color也不能够透明,需要跟原本的颜色一致;
然后hair,weapon,foot这些记得依次根据自己的赋值,这些是当mouse_type改变时,这个格子中会放入的装备,以一个bag button设置为示例,其他都类似:
其中,点击事件不要忘记添加,每一个需要将自己函数里面写的点击事件添加进去;
然后装备栏的代码如下:
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 using Game_Manager; 5 6 public class equip : MonoBehaviour { 7 8 private Game_Scene_Manager gsm; 9 private Image equip_image; 10 public int mouse_type; 11 public Sprite weapon; // 为此背包中相应的装备 12 public Sprite UISprite; 13 public Color weapon_color; 14 public Color UISprite_color; 15 16 void Awake() 17 { 18 gsm = Game_Scene_Manager.GetInstance(); 19 equip_image = GetComponent<Image>(); 20 } 21 22 public void On_equip_Button() { 23 Debug.Log("equip click"); 24 int MouseType = gsm.GetMouse().GetMouseType(); // 得到鼠标上的mousetype 25 if (equip_image.sprite == weapon && MouseType == 0) // 取走装备区装备,当装备区含有装备并且mousetype=0鼠标上没有装备 26 { 27 equip_image.sprite = UISprite; 28 equip_image.color = UISprite_color; 29 gsm.GetMouse().SetMouseType(mouse_type); 30 } 31 else 32 { 33 // 只有相同各类型的装备能够放到相应的装备区,并且不能够重复装备 34 if (mouse_type == MouseType && equip_image.sprite != weapon) { 35 // 将装备佩戴到装备区中 36 equip_image.sprite = weapon; 37 equip_image.color = weapon_color; 38 mouse_type = MouseType; 39 gsm.GetMouse().SetMouseType(0); 40 } 41 } 42 } 43 44 // Use this for initialization 45 void Start () { 46 47 } 48 49 // Update is called once per frame 50 void Update () { 51 // 防止重复装备 52 if (mouse_type == 1 && gsm.GetHair() == 1) 53 { 54 Debug.Log("mouse_type"); 55 gsm.SetHair(0); // 已装备头部不能够再装备头部 56 equip_image.sprite = weapon; 57 equip_image.color = weapon_color; 58 } else if (mouse_type == 2 && gsm.GetWeapon() == 1) 59 { 60 gsm.SetWeapon(0); // 已装备武器不能够再装备武器 61 equip_image.sprite = weapon; 62 equip_image.color = weapon_color; 63 } else if (mouse_type == 3 && gsm.GetFoot() == 1) 64 { 65 gsm.SetFoot(0); // 已装备脚部 66 equip_image.sprite = weapon; 67 equip_image.color = weapon_color; 68 } 69 } 70 }
基本上和背包栏类似,但是由于装备栏每一个格只会装一个类型的,并且不能够重复装,所以多了一些判断,又少了一些变量;
其中以一个装备栏设置为例,其他类似:
最后,所有的代码完成,挂上去,最终就得到了想要的效果啦~
还有,在装备栏装上装备后,自己可以做一个动画,人物穿上某一个盔甲,或者拿上一把剑等等,并且将动画按照装备分类分别添加,就能够展现出简单的穿戴装备的效果了~!
总结
这一次通过制作游戏背包发现之前的很多知识都没有掌握透彻,比如多camera如何渲染场景,其实这些也不是什么难的知识,只是自己没有用心,以后一定要多用心去学习!
然后还是有一些自己想要完成的没有完成,比如穿戴剑、刀、弓箭、衣服、战靴等等,由于现在的代码写的有限制,每种类型的装备就只产生一个穿戴的效果,不过应该实现起来也不会很难,以后有时间再去实现~