1

所以我试图制作一个完整的精灵,它分为两部分,一个是头部,另一个是身体。

我在检查器中设置了 2 个纹理,并通过我想要的代码创建了另一个纹理。我所做的是获取我想要的身体像素并设置它们。这里没问题,当我想放头部时问题就来了,因为它是 128x128 并且我没有全部使用,所以它会选择这个的透明像素并删除身体的像素。

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

public class MSSGameHandler : MonoBehaviour
{

[SerializeField] private Texture2D baseTexture;
[SerializeField] private Texture2D headTexture;
[SerializeField] private Texture2D bodyTexture;
[SerializeField] private Material guestMaterial;
private Sprite mysprite;

private void Awake()
{
    Texture2D texture = new Texture2D(512, 512, TextureFormat.RGBA32, true);

    Color[] spriteSheetBasePixels = baseTexture.GetPixels(0, 0, 512, 512);
    texture.SetPixels(0, 0, 512, 512, spriteSheetBasePixels);



    Color[] bodyPixels = bodyTexture.GetPixels(0, 0, 128, 128);
    texture.SetPixels(0, 256, 128, 128, bodyPixels);

    Color[] headPixels = headTexture.GetPixels(0, 0, 128, 128);
    texture.SetPixels(0, 294, 128, 128, headPixels);

    texture.Apply();

    guestMaterial.mainTexture = texture;
    //mysprite = Sprite.Create(texture)

}

}
4

2 回答 2

2

好吧,SetPixels您会覆盖所有现有像素

您应该“手动”循环它们并检查 alpha 值

var finalpixels = new Color[512 * 512];

var spriteSheetBasePixels = baseTexture.GetPixels(0, 0, 512, 512);
for(var i = 0; i < finalpixels.Length; i++)
{
    finalpixels[i] = spriteSheetBasePixels [i];
}

var bodyPixels = bodyTexture.GetPixels(0, 0, 128, 128);
for(var x = 0; x < 128; x++)
{ 
    for(var y = 256; y < 256 + 128; y++)
    {
        finalpixels[x + y * 512] = bodyPixels[x + (y - 256) * 128];
    }
}

var headPixels = headTexture.GetPixels(0, 0, 128, 128);
for(var x = 0; x < 128; x++)
{
    for(var y = 294; y < 294 + 128; y++)
    {
        var pixel = headPixels[x + (y - 256) * 128];

        if(Mathf.Approximately(pixel.a, 0)) continue;

        finalpixels[x + y * 512] = pixel;
    }
}

texture.SetPixels(finalPixels);

身体形象

在此处输入图像描述

头像

在此处输入图像描述

结果(在 RawImage 中)

在此处输入图像描述

对不起我的绘画技巧:D

于 2019-09-13T17:07:53.140 回答
1

将这两个纹理合并在一起会在应用程序开始时增加不必要的加载时间,而对每帧的好处却很少。并且,如果您决定移动头部和身体的相对位置(例如,作为空闲动画的一部分),则必须对性能造成影响以重新创建显示新相对位置的新纹理。

因此,改为将头部和身体放入单独的对象中,然后使用排序组组件将它们排序在一起。

示例字符:
由精灵和游戏对象的层次结构组成的角色

分组前
两个角色纠缠在一起

将排序组应用于根对象(ChombiBoy在本例中为 ):
在根对象上排序组组件

Order in Layer对组进行排序后(顶部呈现的字符在其中具有更高的值Sorting Group):
两个字符正确显示

(图片取自 Unity 文档)

对排序组进行排序

Unity 使用排序层的概念来允许您将精灵分成组以获得覆盖优先级。排序层顺序较低的排序组被较高排序层中的组覆盖。

有时,同一排序层中的两个或多个对象可能会重叠(例如,横向滚动游戏中的两个玩家角色,如下例所示)。Order in Layer 属性可用于将一致的优先级应用于同一层中的排序组。与排序层一样,较低的数字首先呈现,并被具有较高层数的排序组遮挡,后者在稍后呈现。有关编辑排序层的详细信息,请参阅标签和层的文档。

排序组的后代根据最近或下一个排序组的其他后代进行排序(取决于排序是按距离还是按层排序)。换句话说,排序组只为其后代创建一个本地排序空间。这允许组内的每个渲染器使用排序层和层中的顺序进行排序,但在包含排序组的本地。

于 2019-09-13T17:18:18.113 回答