9

我正在使用一系列 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);

也没有运气。关于如何做到这一点的任何建议?

已编辑

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

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

纹理都放置在“资源”文件夹中。资源文件夹可以放置在资产层次结构中的任何位置——我为每个 PNG 序列创建了几个单独的文件夹来组织它们,然后在每个文件夹中添加了一个资源文件夹来保存实际的 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;
}
4

2 回答 2

12

在 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

于 2013-04-04T21:57:49.217 回答
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;
    }
}
于 2013-11-18T12:57:33.160 回答