有一个很恶心的需求就是打包后,要动态换图片,而且这个项目版本已经没有编辑器版本,只能从打包后的StreamingAssets 中读一个图片,到UI中
因为是打包以后,如果不通过反编译的话 只能去访问StreamingAssets 去加载一个图片
private Image mainBg;
mainBg = GetComponent<Image>();
var asset = ResourceMgr.Inst.LoadAssetAsStream("RoleIMG.jpg");
Texture2D texture = new Texture2D(asset.texture.width, asset.texture.height);
asset.LoadImageIntoTexture(texture);
mainBg.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
ResourceMgr 是自己封的一个读取类 结尾可以给出,用到了类中 LoadAssetAsStream
public WWW LoadAssetAsStream(string name, bool isCache = true)
{
if (_resourceTable.Contains(name))
return _resourceTable[name] as WWW;
var www = new WWW("file:///" + Path.Combine(_streamPath, name));
Debug.Log(Path.Combine(_streamPath, name));
while (!www.isDone) {}
return www;
}
返回一个www,这里会生成一个 Texture2D,然后用返回的www 这个值去调用api LoadImageIntoTexture()
这里为什么生成一个Texture2D,如果不生成直接用 www.texture 会产生失色,根据强哥说是Mipmap问题,具体原因如果有小伙伴得知 希望给出。
失色图:
最终效果图:
最后用:
Sprite.Create去生成 sprite 赋给 定义的 image 即可 mainBg.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
附上ResourceMgr 读取类
using System.Collections;
using System.IO;
using UnityEngine;
#region Modify (修改,或者新增了功能请在此进行记录(name、todo 、time)!谢谢)
#endregion
//using Object = UnityEngine.Object;
public class ResourceMgr
{
#region Instance
private static ResourceMgr _inst;
public static ResourceMgr Inst
{
get { return _inst = _inst ?? new ResourceMgr(); }
}
#endregion
private ResourceMgr()
{
Init();
}
private string _streamPath;
private Hashtable _resourceTable; //缓存从Resource中加载的资源
private void Init()
{
_resourceTable = new Hashtable();
_streamPath = Application.streamingAssetsPath;
}
public T LoadAsset<T>(string path, bool isCache = true) where T : Object
{
if (_resourceTable.Contains(path))
return _resourceTable[path] as T;
var assets = Resources.Load<T>(path);
if (assets == null)
{
Debug.LogFormat(" assets is not found at Path:{0}", path);
return null;
}
if (isCache)
_resourceTable.Add(path, assets);
return assets;
}
public WWW LoadAssetAsStream(string name, bool isCache = true)
{
if (_resourceTable.Contains(name))
return _resourceTable[name] as WWW;
var www = new WWW("file:///" + Path.Combine(_streamPath, name));
Debug.Log(Path.Combine(_streamPath, name));
while (!www.isDone) {}
return www;
}
public T InstantiateAsset<T>(string path) where T:Object
{
var obj = LoadAsset<T>(path);
var go = GameObject.Instantiate<T>(obj);
if (go == null)
Debug.LogError("Instantiate {0} failed!", obj);
return go;
}
public void ClearAssetsCache()
{
foreach (Object asset in _resourceTable)
{
#if UNITY_EDITOR
GameObject.DestroyImmediate(asset, true);
#else
GameObject.DestroyObject(asset);
#endif
}
_resourceTable.Clear();
}
}