3D人物换装

该代码段展示了如何在Unity中实现3D角色的换装功能。通过加载不同的GameObject(衣物预制体),合并网格,重新分配材质和骨骼信息,实现了角色的衣物更换。同时,文章还提到了一种轮转图的布局方式,用于展示和切换不同衣物。

   public void ChangeOfOutFit()
    {
        skinneds[0] = Resources.Load<GameObject>("Player/tou"+touid);
        skinneds[1] = Resources.Load<GameObject>("Player/yifu"+yifuid);
        skinneds[2] = Resources.Load<GameObject>("Player/tui"+tuiid);
        //1.找到当前所有骨骼及名称
        var allbones = GetComponentsInChildren<Transform>();
        //2.把所有骨骼以名称作为Key存入字典中 方便后续查找
        Dictionary<string, Transform> dicbones = new Dictionary<string, Transform>();
        for (int i = 0; i < allbones.Length; i++)
        {
            dicbones.Add(allbones[i].name, allbones[i]);
        }

        //3。寻找每个对应部位中需要使用的骨骼,并将其保存
        List<Transform> bones = new List<Transform>();
        List<CombineInstance> combines = new List<CombineInstance>();
        List<Material> materials = new List<Material>();

        for (int i = 0; i < skinneds.Length; i++)
        {
            //寻找网格
            CombineInstance combine = new CombineInstance();
            combine.mesh = skinneds[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;
            combine.transform = skinneds[i].transform.localToWorldMatrix;
            combines.Add(combine);
            //添加材质球
            materials.Add(skinneds[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial);
            //寻找骨骼
            var bodybones = skinneds[i].GetComponentInChildren<SkinnedMeshRenderer>().bones;
            for (int j = 0; j < bodybones.Length; j++)
            {
                //使用的是自己的骨骼不是预制体上的骨骼
                bones.Add(dicbones[bodybones[j].name]);
            }
        }

        Mesh mesh = new Mesh();
        //网格合并
        mesh.CombineMeshes(combines.ToArray(),false);
        GetComponent<SkinnedMeshRenderer>().sharedMesh = mesh;
        GetComponent<SkinnedMeshRenderer>().materials = materials.ToArray();
        GetComponent<SkinnedMeshRenderer>().bones = bones.ToArray();
    }

骨骼添加组件并调用方法

进行3D预制体的合并

    private List<Transform> sorts = new List<Transform>();

    //设置人物图片位置所处深度
    player.transform.localScale = new Vector3(1, 1, (max - min) * 0.5f + min);
    sorts.Add(player);

    void Move()
        {
            var moveAng = dis / r;
            for (int i = 0; i < num; i++)
            {
                var x = Mathf.Sin(i * ang + moveAng) * r;
                var z = Mathf.Cos(i * ang + moveAng) * r;
                var p = (z + r) / (2 * r);
                //设置缩放
                var scale = (max - min) * p + min;

                if (list.Count <= i)
                {
                    var n = i;
                    var temp = Instantiate(prefab.gameObject, transform, false);
                    temp.GetComponent<Image>().sprite = Resources.Load<Sprite>($"PlayerImg/img{n}");
                    temp.GetComponent<Button>().onClick.AddListener(() =>
                    {
                        //按钮触发根据衣服名称编号更改
                        switch (n / 2)
                        {
                            case 0:
                            {
                                combin.yifuid = n % 2;
                                break;
                            }
                            case 1:
                            {
                                combin.tuiid = n % 2;
                                break;
                            }
                            case 2:
                            {
                                combin.touid = n % 2;
                                break;
                            }
                        }

                        combin.ChangeOfOutFit();//刷新服装
                    });
                    list.Add(temp);
                    sorts.Add(temp.transform);
                }

                //设置偏移
                list[i].transform.localPosition = new Vector3(x, p * -100, 0);
                list[i].transform.localScale = Vector3.one * scale;
            }

            //对图片缩放的Z值进行比较   因为人物不参与缩放x,y值无参考意义
            sorts.Sort((a, b) =>
            {
                if (a.localScale.z < b.localScale.z)
                {
                    return -1;
                }
                else if (a.localScale.z == b.localScale.z)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            });
    
            //更换图片显示位置
            for (int i = 0; i < sorts.Count; i++)
            {
                sorts[i].SetSiblingIndex(i);
            }
        }

使用轮转图调用换装方法实现3D换装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值