Unity3D——UGUI实现背包系统

先放个最终效果看看!



设计思路:

界面中存在三个层,最前面的层是一个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 initialization
void Start () {
    mTrans = transform; // 获得panel的transform
    mStart = mTrans.localRotation; // 获得panel的自身旋转角度
}
	
// Update is called once per frame
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);
    // 根据鼠标移动修改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 frame
void 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

  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个item列表可以通过 Unity3D 中的UGUI组件来完成,以下是一个简单的实现步骤: 1. 创建一个ScrollView对象,它会成为你的item列表的容器。 2. 在ScrollView对象下创建一个Content对象,用于放置所有的item。 3. 创建一个item的Prefab,包含你需要显示的元素。 4. 在运行时,动态生成多个item对象,将它们放置在Content对象下,以此来构建item列表。 5. 根据需要,可以对item列表进行滚动、添加或删除item等操作。 具体实现可以参考以下步骤: 1. 创建ScrollView和Content对象 在场景中创建一个空对象,命名为ScrollView。将Canvas组件的Render Mode设置为Screen Space - Overlay,然后将ScrollView对象的RectTransform组件的Anchors和Pivot都设置为(0, 0)。这样,ScrollView对象的左下角就会位于屏幕左下角。在ScrollView对象下创建一个空对象,命名为Content。将Content对象的RectTransform组件的Anchors和Pivot也都设置为(0, 0),以便于它能够与ScrollView对象的位置重合。 2. 创建item的Prefab 在项目资源中创建一个新的Prefab,将你需要显示的元素放入其中。例如,可以在Prefab中添加一个Text对象,用于显示item的标题。确保这个Prefab的RectTransform组件的Anchors和Pivot都设置为(0, 0),以便于在生成item时它们能够正确地布局。 3. 动态生成item对象 在脚本中,使用Instantiate()方法动态生成多个item对象,并将它们作为Content对象的子对象。例如: ```csharp public GameObject itemPrefab; public int itemCount = 20; void Start() { for (int i = 0; i < itemCount; i++) { GameObject item = Instantiate(itemPrefab, content.transform); // 设置item的位置和大小 item.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -i * item.GetComponent<RectTransform>().rect.height); } } ``` 这段代码会生成20个item对象,将它们放置在Content对象下,并设置它们的位置和大小。这里假设item的高度是固定的。 4. 对item列表进行滚动 为了让item列表能够滚动,需要将ScrollView对象下的Scrollbar组件与Content对象的RectTransform组件相绑定。在ScrollView对象下添加一个Scrollbar组件,将它的Direction设置为Vertical,并将它的Size设置为0.2(或根据需要调整)。然后将Scrollbar组件的Value属性绑定到Content对象的RectTransform组件的anchoredPosition.y属性上。这样,当拖动Scrollbar时,Content对象就会相应地向上或向下滚动。 5. 添加或删除item 如果需要动态地添加或删除item,可以在脚本中使用Instantiate()和Destroy()方法来完成。例如: ```csharp public void AddItem() { GameObject item = Instantiate(itemPrefab, content.transform); // 设置新的item的位置和大小 item.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -itemCount * item.GetComponent<RectTransform>().rect.height); itemCount++; } public void RemoveItem() { if (itemCount > 0) { Destroy(content.transform.GetChild(itemCount - 1).gameObject); itemCount--; } } ``` 这样,就可以在运行时动态地添加或删除item了。当添加一个新的item时,只需生成一个新的GameObject,并将它放置在Content对象下;当删除一个item时,只需销毁Content对象下的最后一个子对象即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值