在Unity3d中将PNG图像作为纹理加载到运行时

时间:2013-04-04 20:16:09

标签: unity3d textures

我正在使用一系列PNG图像作为精灵在Unity中为增强现实应用程序创建平面动画。 PNG图像作为纹理加载,纹理应用于平面以创建跟踪增强现实目标的动画序列。

这是附加到平面并控制动画序列的脚本。

档案PNGSequence.js

#pragma strict
var tecture : Texture[];

var changeInterval : float = 0.06;
var isRunning = false;
var isLooping = false;

function Start () {
    var isRunning = true;
}

function Update () {
    if( isRunning == true) {
        Animation ();
    }
}

function Animation () {
    var index : int = Time.time/changeInterval;
    index = index % tecture.Length;
    renderer.material.mainTexture = tecture[index];
    if ( index == tecture.Length-1){
        if( isLooping == false){
            isRunning = false;
        }
           renderer.material.mainTexture = tecture[0];
    }
}

通过在编辑器中拖放PNG文件来分配纹理,如果我限制PNG计数,一切正常。然而,随着纹理数量的增加,我在Android上出现内存错误。

我想在运行时将PNG文件作为纹理加载以限制内存数量,但是我无法使代码正常工作。

我尝试过LoadImage。

var imageTextAsset : TextAsset = Resources.Load("test.png");
var tex = new Texture2D (4, 4);
tex.LoadImage(imageTextAsset.bytes);
renderer.material.mainTexture = tex;

我也尝试将图像直接加载为纹理(因为这似乎适用于编辑器)。

renderer.material.mainTexture = Resources.LoadAssetAtPath"Assets/Images/test.png",Texture);

两者都没有运气。有关如何实现这一目标的任何建议吗?

EDITED

由于Xerosigma提供的链接,我能够正常工作。我遇到了路径问题(我怀疑加载时纹理要求)。

在加载PNG纹理之外,我还发现Unity不对纹理进行内存管理。要恢复内存,需要在使用后手动卸载纹理。

纹理都放在“Resources”文件夹中。资源文件夹可以放在Assets层次结构中的任何位置 - 我为每个PNG序列创建了几个单独的文件夹来组织它们,然后在每个文件夹中添加一个Resources文件夹来保存实际的PNG。

纹理通过编辑器指定纹理计数(即100),基本名称(例如“texture_”)和零填充。

文件PNGSequenceRunTime.js

#pragma strict

var imageCount : int = 0;
var imageNameBase : String = "";
var imageNameZeroPadding : int = 0;

var changeInterval : float = 0.06;
var isRunning = false;
var isLooping = false;

private var texture : Texture = null;

function PlayRocket () {
    isRunning = true;
}

function Start () {
    var isRunning = false;
    var fileName : String = imageNameBase + ZeroPad(0,imageNameZeroPadding);
    texture = Resources.Load(fileName);
}

function Update () {
    if( isRunning == true) {
        PNGAnimation ();
    }
}

function PNGAnimation () {
    var index : int = Time.time/changeInterval;
    index = index % imageCount;
    var fileName : String = imageNameBase + ZeroPad(index,imageNameZeroPadding);
    Resources.UnloadAsset(texture);
    texture = Resources.Load(fileName);
    renderer.material.mainTexture = texture;


    if ( index == imageCount-1){
        Debug.Log("End of Animation");
        Debug.LogWarning("End of Animation");
        if( isLooping == false){
            isRunning = false;
        }
        fileName = imageNameBase + ZeroPad(0,imageNameZeroPadding);
        Resources.UnloadAsset(texture);
        texture = Resources.Load(fileName);
        renderer.material.mainTexture = texture;
    }
}

function ZeroPad(number : int, size : int) {
    var numberString : String = number.ToString();
    while (numberString.Length < size) numberString = "0" + numberString;
    return numberString;
}

2 个答案:

答案 0 :(得分:11)

在C#中:

// Load all textures into an array
Object[] textures = Resources.LoadAll("Textures", typeof(Texture2D));

// Load a single texture
Texture2D texture = Resources.Load("Texture") as Texture2D;

renderer.material.mainTexture = texture;

希望它有所帮助。您应该能够将它转换为JS没问题。只需查看Unity文档。

http://docs.unity3d.com/Documentation/ScriptReference/Resources.html

答案 1 :(得分:2)

通过将任何序列的.png图像(带有alpha通道)放在主Assets文件夹中的Resources / Sequence1文件夹中,我实现了同样的目的。输出是一个无缝的电影,完全根据图像的alpha通道播放透明度。

此代码应用于分配了具有透明/漫射着色器的默认新材质的平面。此着色器支持使用alpha作为透明度的PNG图像。您只需将包含图像的文件夹的名称赋予变量framespath。

#pragma strict

var framespath: String = "";
var vidframes: Object[];
var count: int;

function Start () {

    vidframes = Resources.LoadAll(framespath, Texture);
    Debug.Log(vidframes.Length);

    count = 0;
    renderer.material.mainTexture = vidframes[count];
}

function Update () {
    count++;
    renderer.material.mainTexture = vidframes[count];
    if (count == vidframes.Length-1)
    {
        count = 0;
    }
}