유니티 PC 버전에서 런타임에 파일 브라우저를 이용해 파일을 불러오고 싶을 때가 있다.
만들어놓은 게임 맵(스테이지)을 불러오거나, SAVE 파일 등을 불러올 때 파일 브라우저가 있으면 편리하다.
간단한 파일 브라우저(Simple File Browser)를 이용해보자.
아래는 런타임에 파일 브라우저를 사용할 수 있는 무료 에셋이다.
https://assetstore.unity.com/packages/tools/gui/runtime-file-browser-113006
GitHub Page 다음과 같다.
https://github.com/yasirkula/UnitySimpleFileBrowser
이제 에셋을 추가하자.
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:
Unity Pro:
Unity 프리미엄 학습:
'개발 > Unity' 카테고리의 다른 글
유니티 - 쿼터니언과 회전의 덧셈 (How to Add Two Quaternions) (0) | 2022.07.02 |
---|---|
유니티 에셋 - 런타임 파일 브라우저로 파일 저장하기 (Save Files using Runtime File Browser) (0) | 2022.07.02 |
유니티 - SmoothDamp를 코루틴에서 사용하기 (SmoothDamp with Coroutine) (0) | 2022.06.28 |
유니티 - 머티리얼 로드하고 바꾸기 (Load and Change Materials) (0) | 2022.06.26 |
유니티 디버깅 - Error Pause를 활성화하여 에러 발생 시 게임 멈추기 (0) | 2022.06.26 |
댓글