前言
第一种:合并类换装(只需一种材质球)
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateZheng : MonoBehaviour
{
public SkinnedMeshRenderer[] sk;
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
List<CombineInstance> combines = new List<CombineInstance>();
List<Texture2D> textures = new List<Texture2D>();
for (int i = 0; i < sk.Length; i++)
{
CombineInstance instance = new CombineInstance();
instance.mesh = sk[i].sharedMesh;
instance.transform = sk[i].transform.localToWorldMatrix;
combines.Add(instance);
textures.Add(sk[i].sharedMaterial.GetTexture("_BackTex") as Texture2D);
}
mesh.CombineMeshes(combines.ToArray());
//合并纹理
Texture2D texture = new Texture2D(0,0);
Rect[] rects=texture.PackTextures(textures.ToArray(),0);
//通过矩形数据rects重新计算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));
}
}
mesh.uv = uv.ToArray();
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"));
material.SetFloat("_PosX",texture.width/face.width);
material.SetFloat("_PosY", texture.height / face.height);
GetComponent<MeshRenderer>().material = material;
}
// Update is called once per frame
void Update()
{
}
}
创建一个cube,将该脚本挂载在它的身上
注意:要将脸的相对位置调一下
实现效果前:
实现效果后:
卡哇伊捏~
第二种:多个子网格合并换装
代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreatePin : MonoBehaviour
{
public SkinnedMeshRenderer[] sk;
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
List<CombineInstance> combines = new List<CombineInstance>();
for (int i = 0; i < sk.Length; i++)
{
CombineInstance instance = new CombineInstance();
instance.mesh = sk[i].sharedMesh;
instance.transform = sk[i].transform.localToWorldMatrix;
combines.Add(instance);
}
mesh.CombineMeshes(combines.ToArray(), false,true);
GetComponent<MeshFilter>().mesh = mesh;
}
// Update is called once per frame
void Update()
{
}
}
注意,需要用到多个材质球
记得把脸调回到最初的位置
拥有多个子网格