Unity3D——UGUI实现背包系统

来源:互联网 发布:安卓锁屏拍照软件 编辑:程序博客网 时间:2024/05/02 04:31

先放个最终效果看看!



设计思路:

界面中存在三个层,最前面的层是一个panel,上面放置了背包栏(九个button一个text)、装备栏(三个button)、一个图片UI控件。中间的层放置了一个人物3D模型,最后面的层用于显示背景图片。

这个背包系统的重点是背包栏的逻辑。这里使用一个单例的场景管理器用于获取第一个panel中的图片UI控件。在背包栏和装备栏中设置一个mouse_type用于记录当前绑定图片的类型(头盔为1、武器为2、鞋子为3),然后每次点击背包栏或者装备栏中的一个按钮则将按钮的图片置为一个透明的精灵,然后把对应的精灵按照mouse_type设置在那个图片UI控件上,并让图片跟随鼠标移动,实现装备的切换效果。最后再点击目标按钮的时候再根据图片UI控件的mouse_type来给目标按钮设置合适的精灵。


编写步骤:

1. 项目目录


2. 新建一个canvas,并设置为如下图所示的属性,注意要设置为UI层和Render Mode为World Space


然后在这个canvas下新建一个Panel,设置如下图所示属性


接着在这个panel下新建两个panel,并添加grid layout group组件,帮助管理内部放置的button控件,设置属性如下图所示

 

再在这两个panel下放置对应个数的button,设置属性以一个为例,其他类似


接着在装备栏放置一个Text作为标题,这里添加了一个shadow组件来让文字显得更有立体感


最后再新建一个Image控件,即设计思路所提及的图片UI控件,这个控件用于跟随鼠标的运动


然后新建一个Camera,用来看UI界面,设置如下图所示属性,注意设置深度


最后把这个Camera挂载到最开始新建的Canvas上即可

3. 新建一个专门拍摄人物模型的Camera,注意设置clear flags为don’t clear和culling mask为如下图所示(取消显示UI和background,防止不同的摄像机看到重复的地方而显示得不好看)


然后还需要注意设置深度为最大,保证人物模型能够显示在最上面的层


最后在这个Camera下放置一个人物3D模型(在asset store下载一个即可),然后在其中加入一个循环动画即可


值得一提的是,一开始仅仅设置动画是有可能不能够让它动起来的。根据错误信息,我了解到首先需要把这个动画文件的rig标签下的animation type改成legacy才行


然后在animations标签下将wrap mode(下面那个wrap mode)修改为Loop才能实现动画的循环播放


4. 设置背景图片

首先新建一个空对象,这里设置一个新的layer,名字叫做Background,用于防止之前人物模型摄像机观察到这个层


然后在这个空对象下面新建一个空对象,并添加一个Sprite Renderer组件用于显示图片精灵


这里我使用了自己导入的图片,因此需要手动转换为精灵,图片是不能设置在上面的组件里面的


最后新建一个Camera,用于观察这一层的游戏对象。这个Camera设置了最低的深度,表示显示在最底层(毕竟是背景嘛),然后culling mask设置为不观察到UI即可



至此,UI界面搭建完成!




5. 参照参考博客的思路编写panel随鼠标旋转的代码。大致的思路是首先获取panel的transform和自身旋转角度,然后根据鼠标的位置更新panel的旋转角度。这里我调了旋转后角度参数,才能让现实的效果更加正确一些(博客里面的参数貌似有点问题导致旋转错了方向)

// Use this for initializationvoid Start () {    mTrans = transform; // 获得panel的transform    mStart = mTrans.localRotation; // 获得panel的自身旋转角度}// Update is called once per framevoid 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);    // 根据鼠标移动修改panel旋转角度    mTrans.localRotation = mStart * Quaternion.Euler(-mRot.y * range.y, mRot.x * range.x, 0f);}
然后把这个脚本挂载到panel即可
6. 实现场景控制器。这个控制器比较简单,仅仅需要实现单例模式和图片UI控件的getter/setter即可

namespace Game_Manager {    public class Game_Scene_Manager : System.Object {        private static Game_Scene_Manager _instance;        private static Mouse_Image _Mouse;        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;        }    }}
然后将其挂载到新建的空对象UIManager上即可

7. 实现背包栏的点击事件。这里的思路是首先获取场景控制器中图片UI控件的mouse_type。如果按钮的图片不为透明且mouse_type为0的时候,说明当前活动为从背包栏取下物件,则设置图片为透明并设置图片UI控件的mouse_type为当前mouse_type和设置当前背包栏mouse_type为0,表示图片UI控件正携带这张表示物件的图片。如果按钮的图片为透明,则判断图片UI控件的mouse_type来给按钮设置新的图片精灵,最后设置两者的mouse_type

public void On_BackUp_Button() {    int MouseType = gsm.GetMouse().GetMouseType();    if (bag_image.sprite != UIMask && MouseType == 0) {        bag_image.sprite = UIMask;        gsm.GetMouse().SetMouseType(mouse_type);        mouse_type = 0;    } else if (bag_image.sprite == UIMask) {        if (MouseType == 1)            bag_image.sprite = head;        else if (MouseType == 2)            bag_image.sprite = arm;        else if (MouseType == 3)            bag_image.sprite = shoes;        mouse_type = MouseType;        gsm.GetMouse().SetMouseType(0);    }}
装备栏的点击事件同理
public void On_equip_Button() {    int MouseType = gsm.GetMouse().GetMouseType();    if (equip_image.sprite == weapon && MouseType == 0) {        Debug.Log("equip: " + mouse_type);        equip_image.sprite = UIMask;        gsm.GetMouse().SetMouseType(mouse_type);    } else if (equip_image.sprite == UIMask) {        if (MouseType == mouse_type) {            equip_image.sprite = weapon;            gsm.GetMouse().SetMouseType(0);        }    }}
然后把这两个脚本分别挂载对应的button上。注意,每个button需要设置好初始的mouse_type,如果有初始图片精灵则根据图片的种类设置好mouse_type,例如B2因为初始化一个头盔的图片精灵的参数所以设置为1,其他的public对象也要设置好


与此同时,记得在On Click()中添加按钮对应的点击事件函数,如下图所示


8. 最后编写跟随鼠标移动的图片UI控件的脚本。这里的实现思路是在update函数内检查mouse_type是否更改。如果是0,则设置图片为透明的,否则则设置成对应的物件图片精灵。然后再使得图片UI控件的位置跟随鼠标的位置。注意,这里一定要将屏幕坐标转换为世界坐标才能够使得图片UI控件能够正常跟随鼠标,并且一定要如下图所示加上才能够使得鼠标的位置世界坐标修改有反应(我这里不加的话鼠标的世界坐标一直是(0,0,-350))

// Update is called once per framevoid Update () {    // Debug.Log(mouse_type);    if (mouse_type == 0) {        mouse_image.sprite = none;        mouse_image.color = None;    } else {        mouse_image.color = NotNone;        if (mouse_type == 1)            mouse_image.sprite = head;        else if (mouse_type == 2)            mouse_image.sprite = arm;        else if (mouse_type == 3)            mouse_image.sprite = shoes;        Vector3 mp = Input.mousePosition;        Vector3 mmp = cam.ScreenToWorldPoint(mp + new Vector3(0, 0, 350));        //transform.position = new Vector3(mp.x - 450, mp.y - 200, 0);        transform.position = new Vector3(mmp.x, mmp.y, 0);        // Debug.Log("mp: " + mp);        // Debug.Log("mmp: " + mmp);    }}
然后将这个脚本挂载到图片UI控件上即可


参考博客:http://blog.csdn.net/qq_20496459/article/details/51421360


GitHub地址:https://github.com/SkyeBeFreeman/BackPackSystem

阅读全文
0 0