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如何渲染场景,其实这些也不是什么难的知识,只是自己没有用心,以后一定要多用心去学习!

然后还是有一些自己想要完成的没有完成,比如穿戴剑、刀、弓箭、衣服、战靴等等,由于现在的代码写的有限制,每种类型的装备就只产生一个穿戴的效果,不过应该实现起来也不会很难,以后有时间再去实现~

posted @ 2017-05-09 03:50  小预备  阅读(30696)  评论(0编辑  收藏  举报