在 Unity3d 中在运行时加载 PNG 图像作为纹理 [英] Loading a PNG image as a texture at runtime in Unity3d

查看:40
本文介绍了在 Unity3d 中在运行时加载 PNG 图像作为纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using a series of PNG images as sprites to create animations on a plane for an augmented reality application in Unity. The PNG images are loaded as textures, and the textures are applied to a plane to create an animation sequence that tracks with an augmented reality target.

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

Here is the script that is attached to the plane and controls the animation sequence.

#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 上出现内存不足错误.

Textures are assigned by drag-and-drop of PNG files in the editor and everything works fine if I limit the PNG count. As my texture count increases, however, I'm getting out of memory errors on Android.

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

I would like to load the PNG files as textures at run time to limit the number memory, but I'm having trouble getting the code working.

我试过 LoadImage.

I've tried LoadImage.

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

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

I've also tried loading the image directly as a texture (since this seems to work with the editor).

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

两者都不走运.关于如何实现这一点有什么建议吗?

No luck with either. Any suggestions on how to accomplish this?

已编辑

多亏了 Xerosigma 提供的链接,我才能完成这项工作.我遇到了路径问题(我怀疑加载时的纹理要求).

I was able to get this working thanks to the link provided by Xerosigma. I had an issue with paths (and I suspect with the Texture requirement on load).

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

Outside of loading the PNG textures, I also discovered that Unity does not do memory management on textures. To recover memory, textures need to be manually unloaded after use.

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

Textures are all placed in a "Resources" folder. The resources folder can be placed anywhere in the Assets hierarchy - I created several individual folders for each of my PNG sequences to organize them, then added a Resources folder within each to hold the actual PNGs.

通过指定纹理计数(即 100)、基本名称(例如texture_")和零填充,通过编辑器分配纹理.

Textures are assigned through the editor by specifying a texture count (ie. 100), a base name ("texture_" for instance), and zero padding.

#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;
}

推荐答案

在 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 文档.

Hope it helps. You should be able to convert it into JS no problem. Just look at the Unity documentation.

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

这篇关于在 Unity3d 中在运行时加载 PNG 图像作为纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆