I found a tutorial on YouTube that accurately added File Explorer and image upload to a 'RawImage' on a canvas using Unity 2017.3.1f1.
What I'm trying to do is add the same image after 'button press' to a 3D object like a cube or plane as shown by the colored cube. When I run the below code, it registers as being present on the cube but doesn't render. Any help is appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
public class Explorer : MonoBehaviour
{
string path;
public RawImage image;
public void OpenExplorer()
{
path = EditorUtility.OpenFilePanel("Overwrite with png", "", "png");
GetImage();
}
void GetImage()
{
if (path != null)
{
UpdateImage();
}
}
void UpdateImage()
{
WWW www = new WWW("file:///" + path);
image.texture = www.texture;
}
}
There is a tiny bug in your code. It should work sometimes and fail other times. The chances of it working or not depends on the size of the image. It will work if the image is really small but fail when it is a large image.
The reason for this is because of the code in your UpdateImage
function. The WWW
is supposed to be used in a coroutine function because you need to yield or wait for it to finish loading or downloading the file before accessing the texture with www.texture
. Your are not doing this now. Change it to a coroutine function then yield it and it should work fine,.
void GetImage()
{
if (path != null)
{
StartCoroutine(UpdateImage());
}
}
IEnumerator UpdateImage()
{
WWW www = new WWW("file:///" + path);
yield return www;
image.texture = www.texture;
}
If some reason you can't use a coroutine because it's an Editor plugin then forget about the WWW
API and use use File.ReadAllBytes
to read the image.
void GetImage()
{
if (path != null)
{
UpdateImage();
}
}
void UpdateImage()
{
byte[] imgByte = File.ReadAllBytes(path);
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(imgByte);
image.texture = texture;
}
To assign the image to a 3D Object, get the MeshRenderer
then set the texture to the mainTexture
of the material the renderer is using:
//Drag the 3D Object here
public MeshRenderer mRenderer;
void UpdateImage()
{
byte[] imgByte = File.ReadAllBytes(path);
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(imgByte);
mRenderer.material.mainTexture = texture;
}