【问题标题】:Merge textures at Runtime在运行时合并纹理
【发布时间】:2015-01-29 19:07:36
【问题描述】:

除了使用 SetPixels() 之外,还有什么方法可以将一个纹理“烘焙”到另一个纹理? 现在我正在尝试使用类似的东西,但它太慢了:

public static Texture2D CombineTextures(Texture2D aBaseTexture, Texture2D aToCopyTexture, int x, int y)
{
    int aWidth = aBaseTexture.width;
    int aHeight = aBaseTexture.height;

    int bWidth = aToCopyTexture.width;
    int bHeight = aToCopyTexture.height;

    Texture2D aReturnTexture = new Texture2D(aWidth, aHeight, TextureFormat.RGBA32, false);

    Color[] aBaseTexturePixels = aBaseTexture.GetPixels();
    Color[] aCopyTexturePixels = aToCopyTexture.GetPixels();

    int aPixelLength = aBaseTexturePixels.Length;
    for(int y1 = y, y2 = 0; y1 < aHeight && y2 < bHeight ; y1++, y2++)
    {
        for(int x1 = x, x2 = 0 ; x1 < aWidth && x2 < bWidth; x1++, x2++)
        {
            aBaseTexturePixels[x1 + y1*aWidth] = Color.Lerp(aBaseTexturePixels[x1 + y1*aWidth], aCopyTexturePixels[x2 + y2*bWidth], aCopyTexturePixels[x2 + y2*bWidth].a);
        }
    }

    aReturnTexture.SetPixels(aBaseTexturePixels);
    aReturnTexture.Apply(false);

    return aReturnTexture;
}

问题是,我需要在 2d 表面上显示很多精灵(血液、敌人尸体等),并且仅实例化每个精灵会大大降低 fps。

【问题讨论】:

  • 欢迎来到 Stack Overflow!请编辑您的问题并添加一些关于您迄今为止尝试过的信息。

标签: unity3d textures


【解决方案1】:

如果您在实例化预制件时担心 fps 下降,您绝对应该构建一个对象池系统。因此,您将拥有一个系统:

  1. 实例化池中的所有对象并使其远离主摄像头
  2. 一旦您需要该对象,您将从池中“借用”它
  3. 一旦不再需要对象,您会将其返回到对象池(例如,当 sprite 不在相机视图中时)

将其全部烘焙到一种纹理并不是最佳做法。为此,您将需要大量 RAM。考虑上述步骤,这是非常常见的做法

这里的好例子:

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

public class BackgroundPool : MonoBehaviour 
{
    public static BackgroundPool instance;
    public List<BackgroundSection> sectionsLibrary = new List<BackgroundSection>();
    public int poolSize = 4;
    public List<BackgroundSection> pool = new List<BackgroundSection>();


    void Awake()
    {
        instance = this;

        DateTime startGenTime = DateTime.Now;

        //generateSectionsPool
        for (int i=0; i<sectionsLibrary.Count; i++)
        {
            for (int j=0; j<poolSize; j++)
            {
                if (j == 0) 
                {
                    sectionsLibrary[i].positionInPool = sectionsLibrary[i].transform.position;
                    pool.Add(sectionsLibrary[i]);
                }
                else
                {
                    BackgroundSection section = (BackgroundSection)Instantiate(sectionsLibrary[i]);

                    section.transform.parent = this.transform;
                    section.transform.position = new Vector3((-(ExtensionMethods.GetBounds(sectionsLibrary[i].gameObject).extents.x * 2) * j) + sectionsLibrary[i].transform.position.x,
                                                         sectionsLibrary[i].transform.position.y);
                    section.transform.localEulerAngles = Vector3.zero;

                    section.gameObject.name = sectionsLibrary[i].gameObject.name + ":" + j.ToString();
                    section.positionInPool = section.transform.position;
                    pool.Add(section);  
                }
           }
        }
        Debug.Log("Background Pool generated in: " + (DateTime.Now - startGenTime).TotalSeconds.ToString() + " s");
    }


    public BackgroundSection GetPiece(Scenery scenery, SceneryLayer _layer)
    {
        List<BackgroundSection> allScenery = new List<BackgroundSection>();
        foreach (BackgroundSection section in pool) { if (section.scenery == scenery) allScenery.Add(section); }

        List<BackgroundSection> matchingPieces = new List<BackgroundSection>();
        foreach (BackgroundSection section in allScenery)  { if (section.sceneryLayer == _layer) matchingPieces.Add(section); }

        if (matchingPieces.Count > 0) 
        {
            BackgroundSection pickedSection = matchingPieces[UnityEngine.Random.Range(0,matchingPieces.Count-1)];
            pool.Remove(pickedSection);
            return pickedSection;
        }
        else
        {
            Debug.LogError("Cann't get background piece matching criteria, scenery: " + scenery + ", layer" + _layer);
            return null;
        }
    }


    public void ReturnPiece(BackgroundSection section)
    {
        pool.Add(section);
        section.transform.parent = this.transform;
        section.transform.position = section.positionInPool;
    }
}

【讨论】:

    猜你喜欢
    • 2011-11-22
    • 2021-09-18
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多