개발/Unity

유니티 에셋 - 런타임 파일 브라우저로 파일 업로드하기 (Upload Files using Runtime File Browser)

피로물든딸기 2022. 6. 29. 22:47
반응형

Unity 전체 링크

 

런타임 파일 브라우저로 파일 저장하기

 

유니티 PC 버전에서 런타임에 파일 브라우저를 이용해 파일을 불러오고 싶을 때가 있다.

만들어놓은 게임 맵(스테이지)을 불러오거나, SAVE 파일 등을 불러올 때 파일 브라우저가 있으면 편리하다.

간단한 파일 브라우저(Simple File Browser)를 이용해보자.

 

아래는 런타임에 파일 브라우저를 사용할 수 있는 무료 에셋이다.

https://assetstore.unity.com/packages/tools/gui/runtime-file-browser-113006

 

Runtime File Browser | GUI 도구 | Unity Asset Store

Use the Runtime File Browser from yasirkula on your next project. Find this GUI tool & more on the Unity Asset Store.

assetstore.unity.com

 

GitHub Page 다음과 같다.

https://github.com/yasirkula/UnitySimpleFileBrowser

 

GitHub - yasirkula/UnitySimpleFileBrowser: A uGUI based runtime file browser for Unity 3D (draggable and resizable)

A uGUI based runtime file browser for Unity 3D (draggable and resizable) - GitHub - yasirkula/UnitySimpleFileBrowser: A uGUI based runtime file browser for Unity 3D (draggable and resizable)

github.com


이제 에셋을 추가하자. 

Asset을 import하면 [Assets] → [Plugins] → [SimpleFileBrowser]가 보인다.

 

Resources 폴더에서 SimpleFileBrowserCanvas 프리팹을 찾는다.

 

씬에 추가하면 아래와 같은 화면을 볼 수 있다.

 

EventSystem을 따로 사용하고 있다면 프리팹에 있는 EventSystem은 삭제하는 것이 좋다.

두 개 이상의 EventSystem이 있다면 경고 메시지가 나온다.

 

Canvas를 추가하고 Upload 버튼을 만든 후, Upload 버튼을 누르면 파일 브라우저가 나오도록 하자.

따라서 이 씬에서 SimpleFileBrowserCanvas는 지운다. 

 

이제 빈 오브젝트(Ctrl + Shift + N)에 FileBrowserTest.cs를 추가한다. (깃허브EXAMPLE CODE)

using UnityEngine;
using System.Collections;
using System.IO;
using SimpleFileBrowser;

public class FileBrowserTest : MonoBehaviour
{
	// Warning: paths returned by FileBrowser dialogs do not contain a trailing '\' character
	// Warning: FileBrowser can only show 1 dialog at a time

	void Start()
	{
		// Set filters (optional)
		// It is sufficient to set the filters just once (instead of each time before showing the file browser dialog), 
		// if all the dialogs will be using the same filters
		FileBrowser.SetFilters( true, new FileBrowser.Filter( "Images", ".jpg", ".png" ), new FileBrowser.Filter( "Text Files", ".txt", ".pdf" ) );

		// Set default filter that is selected when the dialog is shown (optional)
		// Returns true if the default filter is set successfully
		// In this case, set Images filter as the default filter
		FileBrowser.SetDefaultFilter( ".jpg" );

		// Set excluded file extensions (optional) (by default, .lnk and .tmp extensions are excluded)
		// Note that when you use this function, .lnk and .tmp extensions will no longer be
		// excluded unless you explicitly add them as parameters to the function
		FileBrowser.SetExcludedExtensions( ".lnk", ".tmp", ".zip", ".rar", ".exe" );

		// Add a new quick link to the browser (optional) (returns true if quick link is added successfully)
		// It is sufficient to add a quick link just once
		// Name: Users
		// Path: C:\Users
		// Icon: default (folder icon)
		FileBrowser.AddQuickLink( "Users", "C:\\Users", null );

		// Show a save file dialog 
		// onSuccess event: not registered (which means this dialog is pretty useless)
		// onCancel event: not registered
		// Save file/folder: file, Allow multiple selection: false
		// Initial path: "C:\", Initial filename: "Screenshot.png"
		// Title: "Save As", Submit button text: "Save"
		// FileBrowser.ShowSaveDialog( null, null, FileBrowser.PickMode.Files, false, "C:\\", "Screenshot.png", "Save As", "Save" );

		// Show a select folder dialog 
		// onSuccess event: print the selected folder's path
		// onCancel event: print "Canceled"
		// Load file/folder: folder, Allow multiple selection: false
		// Initial path: default (Documents), Initial filename: empty
		// Title: "Select Folder", Submit button text: "Select"
		// FileBrowser.ShowLoadDialog( ( paths ) => { Debug.Log( "Selected: " + paths[0] ); },
		//						   () => { Debug.Log( "Canceled" ); },
		//						   FileBrowser.PickMode.Folders, false, null, null, "Select Folder", "Select" );

		// Coroutine example
		StartCoroutine( ShowLoadDialogCoroutine() );
	}

	IEnumerator ShowLoadDialogCoroutine()
	{
		// Show a load file dialog and wait for a response from user
		// Load file/folder: both, Allow multiple selection: true
		// Initial path: default (Documents), Initial filename: empty
		// Title: "Load File", Submit button text: "Load"
		yield return FileBrowser.WaitForLoadDialog( FileBrowser.PickMode.FilesAndFolders, true, null, null, "Load Files and Folders", "Load" );

		// Dialog is closed
		// Print whether the user has selected some files/folders or cancelled the operation (FileBrowser.Success)
		Debug.Log( FileBrowser.Success );

		if( FileBrowser.Success )
		{
			// Print paths of the selected files (FileBrowser.Result) (null, if FileBrowser.Success is false)
			for( int i = 0; i < FileBrowser.Result.Length; i++ )
				Debug.Log( FileBrowser.Result[i] );

			// Read the bytes of the first file via FileBrowserHelpers
			// Contrary to File.ReadAllBytes, this function works on Android 10+, as well
			byte[] bytes = FileBrowserHelpers.ReadBytesFromFile( FileBrowser.Result[0] );

			// Or, copy the first file to persistentDataPath
			string destinationPath = Path.Combine( Application.persistentDataPath, FileBrowserHelpers.GetFilename( FileBrowser.Result[0] ) );
			FileBrowserHelpers.CopyFile( FileBrowser.Result[0], destinationPath );
		}
	}
}

 

게임을 실행하면 파일 브라우저 리스트가 자동으로 나오게 된다.

 

따라서 Start() 함수를 public void ShowFileBrowser로 변경한다.

	public void ShowFileBrowser() { ... }

 

아까 만든 버튼에 FileMnager를 OnClick에 연결하고 ShowFileBrowser를 추가한다.

 

이제 Upload 버튼을 누르면 런타임에 파일 브라우저를 불러올 수 있다.


이제 json 파일을 받을 수 있도록 코드를 수정해보자.

FileBrowser의 Filter에 .json을 추가하고, SetDefaultFilter도 json으로 한다.

	public void ShowFileBrowser()
	{
		// Set filters (optional)
		// It is sufficient to set the filters just once (instead of each time before showing the file browser dialog), 
		// if all the dialogs will be using the same filters
		FileBrowser
			.SetFilters(true, new FileBrowser
			.Filter("Files", ".jpg", ".png", ".json")
			, new FileBrowser.Filter("Text Files", ".txt", ".pdf"));

		// Set default filter that is selected when the dialog is shown (optional)
		// Returns true if the default filter is set successfully
		// In this case, set Images filter as the default filter
		FileBrowser.SetDefaultFilter(".json");

 

bytes = FileBrowserHelpers.ReadBytesFromFile 아래에 bytes를 Encoding해서 string으로 변경한 후 출력해보자.

	IEnumerator ShowLoadDialogCoroutine()
	{
    	...
		if (FileBrowser.Success)
		{
			...
			byte[] bytes = FileBrowserHelpers.ReadBytesFromFile(FileBrowser.Result[0]);

			string str = System.Text.Encoding.UTF8.GetString(bytes);
			Debug.Log(str);
			
            ...
		}
	}

 

json 파일이 보이는 것을 알 수 있다.

 

실제 json 파일의 내용은 아래와 같다.

 

Debug.Log에 찍힌 내용과 동일하다.

 

JsonParser를 만들어서 여기에서 받은 string을 보내면 runtime에 json 파일을 받아서 처리할 수 있게 된다.

 

실제 PC 빌드에서도 잘 되는지 확인하기 위해 Text를 추가하자.

 

FileBrowserTest에 TextMeshPro를 추가한다.

using TMPro;

public class FileBrowserTest : MonoBehaviour
{
	public TextMeshProUGUI fileText;

 

그리고 str을 text로 넣는다.

string str = System.Text.Encoding.UTF8.GetString(bytes);
fileText.text = str;

 

파일 매니저에도 public으로 선언한 TextMeshProUGUI에 Text를 연결하자.

 

실제 게임 씬에서 잘 되는 것을 확인한 후, 빌드를 해보자.

 

exe 파일을 실행하면 정상적으로 업로드되는 것을 확인할 수 있다.

 

최종 코드는 아래와 같다.

using UnityEngine;
using System.Collections;
using System.IO;
using TMPro;
using SimpleFileBrowser;

public class FileBrowserTest : MonoBehaviour
{
	// Warning: paths returned by FileBrowser dialogs do not contain a trailing '\' character
	// Warning: FileBrowser can only show 1 dialog at a time

	public TextMeshProUGUI fileText;

	public void ShowFileBrowser()
	{
		// Set filters (optional)
		// It is sufficient to set the filters just once (instead of each time before showing the file browser dialog), 
		// if all the dialogs will be using the same filters
		FileBrowser
			.SetFilters(true, new FileBrowser
			.Filter("Files", ".jpg", ".png", ".json")
			, new FileBrowser.Filter("Text Files", ".txt", ".pdf"));

		// Set default filter that is selected when the dialog is shown (optional)
		// Returns true if the default filter is set successfully
		// In this case, set Images filter as the default filter
		FileBrowser.SetDefaultFilter(".json");

		// Set excluded file extensions (optional) (by default, .lnk and .tmp extensions are excluded)
		// Note that when you use this function, .lnk and .tmp extensions will no longer be
		// excluded unless you explicitly add them as parameters to the function
		FileBrowser.SetExcludedExtensions(".lnk", ".tmp", ".zip", ".rar", ".exe");

		// Add a new quick link to the browser (optional) (returns true if quick link is added successfully)
		// It is sufficient to add a quick link just once
		// Name: Users
		// Path: C:\Users
		// Icon: default (folder icon)
		FileBrowser.AddQuickLink("Users", "C:\\Users", null);

		// Show a save file dialog 
		// onSuccess event: not registered (which means this dialog is pretty useless)
		// onCancel event: not registered
		// Save file/folder: file, Allow multiple selection: false
		// Initial path: "C:\", Initial filename: "Screenshot.png"
		// Title: "Save As", Submit button text: "Save"
		// FileBrowser.ShowSaveDialog( null, null, FileBrowser.PickMode.Files, false, "C:\\", "Screenshot.png", "Save As", "Save" );

		// Show a select folder dialog 
		// onSuccess event: print the selected folder's path
		// onCancel event: print "Canceled"
		// Load file/folder: folder, Allow multiple selection: false
		// Initial path: default (Documents), Initial filename: empty
		// Title: "Select Folder", Submit button text: "Select"
		// FileBrowser.ShowLoadDialog( ( paths ) => { Debug.Log( "Selected: " + paths[0] ); },
		//						   () => { Debug.Log( "Canceled" ); },
		//						   FileBrowser.PickMode.Folders, false, null, null, "Select Folder", "Select" );

		// Coroutine example
		StartCoroutine(ShowLoadDialogCoroutine());
	}

	IEnumerator ShowLoadDialogCoroutine()
	{
		// Show a load file dialog and wait for a response from user
		// Load file/folder: both, Allow multiple selection: true
		// Initial path: default (Documents), Initial filename: empty
		// Title: "Load File", Submit button text: "Load"
		yield return FileBrowser.WaitForLoadDialog(FileBrowser.PickMode.FilesAndFolders, true, null, null, "Load Files and Folders", "Load");

		// Dialog is closed
		// Print whether the user has selected some files/folders or cancelled the operation (FileBrowser.Success)
		Debug.Log(FileBrowser.Success);

		if (FileBrowser.Success)
		{
			// Print paths of the selected files (FileBrowser.Result) (null, if FileBrowser.Success is false)
			for (int i = 0; i < FileBrowser.Result.Length; i++)
				Debug.Log(FileBrowser.Result[i]);

			// Read the bytes of the first file via FileBrowserHelpers
			// Contrary to File.ReadAllBytes, this function works on Android 10+, as well
			byte[] bytes = FileBrowserHelpers.ReadBytesFromFile(FileBrowser.Result[0]);

			string str = System.Text.Encoding.UTF8.GetString(bytes);
			fileText.text = str;

			// Or, copy the first file to persistentDataPath
			string destinationPath = Path.Combine(Application.persistentDataPath, FileBrowserHelpers.GetFilename(FileBrowser.Result[0]));
			FileBrowserHelpers.CopyFile(FileBrowser.Result[0], destinationPath);
		}
	}
}

 

파일의 저장은 링크를 참고하자.

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형