unity 实现游戏内的人物模型等等进行换装,自定义模型的外观 展现游戏的个性化

一.模型的整理,了解换装,找到对应指定的模型网格

换装:换装是指在游戏或虚拟场景中,改变角色或物体的外观,通常是通过替换模型、纹理或材质来实现

需要准备多个不同的模型和对应的纹理。每个模型代表一个不同的外观,而纹理则是模型的贴图,用于给模型上色或添加细节。以下是模型各个骨骼部位的网格示例

 二.合并多个SkinnedMeshRenderer的网格和纹理,并为合并后的物体创建一个新的Mesh和材质,然后用一个新的Material来渲染合并后的模型

下面附上完整代码,具有详细注释;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CombineMesh : MonoBehaviour
{
    //SkinnedMeshRenderer是网格过滤器
    public SkinnedMeshRenderer[] sk;
    void Start()
    {
        // 创建一个新的Mesh用于存储合并后的网格数据
        Mesh mesh = new Mesh();
        // 存储CombineInstance的列表,每个CombineInstance代表一个合并网格的实例
        List<CombineInstance> combines = new List<CombineInstance>();
        // 存储合并后的纹理
        List<Texture2D> textures = new List<Texture2D>();  

        // 遍历所有的SkinnedMeshRenderer
        for (int i = 0; i < sk.Length; i++)
        {
            CombineInstance instance = new CombineInstance();
            // 设置CombineInstance的网格为当前SkinnedMeshRenderer的共享网格
            instance.mesh = sk[i].sharedMesh;
            // 设置变换矩阵,将网格变换到世界坐标系
            instance.transform = sk[i].transform.localToWorldMatrix;
            // 将CombineInstance添加到列表中
            combines.Add(instance);
            // 获取背景纹理并添加到纹理列表中
            textures.Add(sk[i].sharedMaterial.GetTexture("_BackTex") as Texture2D);  
        }
        // 使用CombineMeshes方法将所有CombineInstance合并到新的Mesh中
        mesh.CombineMeshes(combines.ToArray()); 

        // 创建一个新的纹理用于合并后的网格
        Texture2D texture = new Texture2D(0, 0);
        // 将纹理列表中的纹理合并到新纹理,并返回合并后的纹理矩形数据
        Rect[] rects = texture.PackTextures(textures.ToArray(), 0);  

        // 重新计算合并后网格的UV坐标
        List<Vector2> uv = new List<Vector2>();
        for (int i = 0; i < sk.Length; i++)
        {
            Vector2[] olduv = sk[i].sharedMesh.uv;
            for (int j = 0; j < olduv.Length; j++)
            {
                float uvx = rects[i].x + rects[i].width * olduv[j].x;
                float uvy = rects[i].y + rects[i].height * olduv[j].y;
                uv.Add(new Vector2(uvx, uvy));
            }
        }
        // 将重新计算的UV坐标应用到新的Mesh上
        mesh.uv = uv.ToArray(); 
        // 将新的Mesh赋给物体的MeshFilter组件
        GetComponent<MeshFilter>().mesh = mesh; 

        Texture2D face = sk[0].sharedMaterial.GetTexture("_MainTex") as Texture2D;
        // 创建新的材质
        Material material = new Material(Shader.Find("Custom/Face"));
        // 设置背景纹理
        material.SetTexture("_BackTex", texture);
        // 设置主纹理
        material.SetTexture("_MainTex", sk[0].sharedMaterial.GetTexture("_MainTex"));
        // 设置PosX参数,用于纹理坐标映射
        material.SetFloat("_PosX", texture.width / face.width);
        // 设置PosY参数,用于纹理坐标映射
        material.SetFloat("_PosY", texture.height / face.height);
        // 将新的材质赋给物体的MeshRenderer组件
        GetComponent<MeshRenderer>().material = material;  
    }
}

 设置模型对应部位的网格

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值