본문 바로가기
개발/Unity

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

by 피로물든딸기 2022. 6. 29.
반응형

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

반응형

댓글