I am currently changing some texture on runtime for iOS and Android by using the NativeGallery asset. The asset basically opens the file explorer, let's you chose an image file from your phones gallery and loads it into the app.
The therefore used code is:
public class DisplayHandler : MonoBehaviour
{
public GameObject Display;
public void PickImage(int maxSize)
{
NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
{
Debug.Log("Image path: " path);
if (path != null)
{
// Create Texture from selected image
Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize);
if (texture == null)
{
Debug.Log("Couldn't load texture from " path);
return;
}
Material material = Display.GetComponent<Renderer>().material;
if (!material.shader.isSupported) // happens when Standard shader is not included in the build
material.shader = Shader.Find("Legacy Shaders/Diffuse");
material.mainTexture = texture;
// If a procedural texture is not destroyed manually,
// it will only be freed after a scene change
//Destroy(texture, 5f);
}
}); // , "Wählen Sie ein Bild aus", mime: "image/*" );
Debug.Log("Permission result: " permission);
}
}
Is it possible to get the same behaviour for Windows and Mac? So for example a button click opens an explorer/finder window where you can chose an image file. The HTML equivalent would be
#if UNITY_EDITOR_WIN
public void ShowExplorer(string itemPath)
{
itemPath = itemPath.Replace(@"/", @"\"); // explorer doesn't like front slashes
System.Diagnostics.Process.Start("explorer.exe", "/select," itemPath);
}
#endif
#if UNITY_EDITOR_OSX
public void ShowExplorer(string itemPath) {
var path = Path.Combine(Application.dataPath, "Resources");
var file = Directory.EnumerateFiles(path).FirstOrDefault();
if (!string.IsNullOrEmpty(file))
EditorUtility.RevealInFinder(Path.Combine(path, file));
else
EditorUtility.RevealInFinder(path);
}
#endif
which opens the explorer window on Windows and Finder on Mac, but as a separate window, not as a dialog to chose textures from.
CodePudding user response:
If anyone is interested in the solution: I used https://github.com/gkngkc/UnityStandaloneFileBrowser and adapted the script like that:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleOpenFileImage : MonoBehaviour, IPointerDownHandler
{
public GameObject output;
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void UploadFile(string gameObjectName, string methodName, string filter, bool multiple);
public void OnPointerDown(PointerEventData eventData) {
UploadFile(gameObject.name, "OnFileUpload", ".png, .jpg", false);
}
// Called from browser
public void OnFileUpload(string url) {
StartCoroutine(OutputRoutine(url));
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
void Start()
{
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
private void OnClick()
{
var extensions = new[] {
new ExtensionFilter("Image Files", "png", "jpg", "jpeg" )
};
var paths = StandaloneFileBrowser.OpenFilePanel("Title", "", extensions, false);
if (paths.Length > 0)
{
StartCoroutine(OutputRoutine(new System.Uri(paths[0]).AbsoluteUri));
}
}
#endif
private IEnumerator OutputRoutine(string url)
{
var loader = new WWW(url);
yield return loader;
output.GetComponent<Renderer>().material.mainTexture = loader.texture;
output.GetComponent<Renderer>().material.mainTextureScale = new Vector2(-1, -1);
}
}
Simply attach a gameobject to the script or define one with GameObject.Find and the texture will change on runtime with a picture selected anywhere from your computer.