Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Unity でストリーミングアセットを読みたい時の URI ジェネレーター
/*
* StreamingAssetsUriGen.cs
*
* Copyright 2017 enish
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if UNITY_WEBPLAYER || UNITY_WEBGL
#define URI_WEB
#elif UNITY_ANDROID
#define URI_ANDROID
#elif UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_XBOX360 || UNITY_XBOXONE
#define URI_WIN
#else
#define URI_OTHER
#endif
using UnityEngine;
using System;
using System.Linq;
using Path = System.IO.Path;
using Regex = System.Text.RegularExpressions.Regex;
/// <summary>
/// ストリーミングアセットを UnityEngine.WWW で読むための URI を作るクラス
/// </summary>
public class StreamingAssetsUriGen
{
/// <summary>
/// ストリーミングアセットの基底 URI
/// </summary>
private static string baseUri_ = null;
/// <summary>
/// ストリーミングアセットの基底 URI を取得します。
/// </summary>
/// <value>ストリーミングアセットの基底 URI</value>
public static string BaseUri
{
get
{
if (baseUri_ == null)
{
string path =
Application.streamingAssetsPath +
Path.DirectorySeparatorChar;
#if !UNITY_EDITOR && (URI_WEB || URI_ANDROID)
baseUri_ = CreateStreamingAssetsUriForAndroid(path);
#elif UNITY_EDITOR_WIN || !UNITY_EDITOR && URI_WIN
baseUri_ = CreateStreamingAssetsUriForWindows(path);
#else
baseUri_ = CreateStreamingAssetsUri(path);
#endif
}
return baseUri_;
}
}
/// <summary>
/// 予約文字 (ディレクトリ区切りを除く) にマッチする正規表現
/// </summary>
private static Regex reservedCharsRegex_ = null;
/// <summary>
/// URI 予約文字 (ディレクトリ区切りを除く) にマッチする正規表現を取得します。
/// </summary>
/// <values>予約文字 (':', '/' を除く) にマッチする正規表現</values>
public static Regex ReservedCharsRegex
{
get
{
if (reservedCharsRegex_ == null)
{
reservedCharsRegex_ = new Regex(
@"[\ud800-\udbff][\udc00-\udfff]|[\u0000-\u0020\?\#\[\]@!\$&\(\)'\*\+,;=%\u007f-\uffff]"
);
}
return reservedCharsRegex_;
}
}
/// <summary>
/// ストリーミングアセットの URI を取得します。
/// </summary>
/// <returns>アセットの URI</returns>
public static string GetStreamingAssetsUri()
{
return BaseUri;
}
/// <summary>
/// ストリーミングアセットの URI を取得します。
/// </summary>
/// <returns>アセットの URI</returns>
/// <param name="path">Assets/StreamingAssets からの相対パス ('/' 区切り)</param>
public static string GetStreamingAssetsUri(string path)
{
#if !UNITY_EDITOR && URI_ANDROID
// Android 5 未満では URI エスケープ不要
using (var version = new AndroidJavaClass("android.os.Build$VERSION"))
{
if (version.GetStatic<int>("SDK_INT") < 21)
{
return BaseUri + path;
}
}
#endif
return BaseUri + EscapeUriPath(path);
}
/// <summary>
/// ストリーミングアセットの読み込み
/// </summary>
/// <param name="path">Assets/StreamingAssets からの相対パス ('/' 区切り)</param>
/// <returns>読み込み用のオブジェクト。各自 Dispose() してね</returns>
public static WWW LoadStreamingAssets(string path)
{
return new WWW(GetStreamingAssetsUri(path));
}
#if UNITY_EDITOR || URI_WEB || URI_ANDROID
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// (Web, Android 用)
/// </summary>
/// <returns>The streaming assets URI for android.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUriForAndroid(string path)
{
// Web, Android では streamingAssetsPath がすでに URI
return path;
}
#endif
#if UNITY_EDITOR || URI_WIN
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// (Windows 用)
/// </summary>
/// <returns>The streaming assets URI for windows.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUriForWindows(string path)
{
// Windows 系は URI エスケープして System.Uri に投げると作ってくれる
return new Uri(EscapeUriPath(path)).AbsoluteUri;
}
#endif
#if UNITY_EDITOR || URI_OTHER
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// </summary>
/// <returns>The streaming assets URI.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUri(string path)
{
return new UriBuilder(Uri.UriSchemeFile, string.Empty, -1,
path, string.Empty).Uri.AbsoluteUri;
}
#endif
/// <summary>
/// ディレクトリ区切りを除く予約文字をエスケープ
/// </summary>
/// <returns>The URI path.</returns>
/// <param name="path">Path.</param>
static string EscapeUriPath(string path)
{
return ReservedCharsRegex.Replace(path,
m => string.Join(string.Empty,
System.Text.Encoding.UTF8.GetBytes(m.Value)
.Select(it => string.Format("%{0:X2}", it)).ToArray()
));
}
}
/*
* StreamingAssetsUriGenUE.cs
*
* Copyright 2017 enish
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if UNITY_WEBPLAYER || UNITY_WEBGL
#define URI_WEB
#elif UNITY_ANDROID
#define URI_ANDROID
#elif UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_XBOX360 || UNITY_XBOXONE
#define URI_WIN
#else
#define URI_OTHER
#endif
using UnityEngine;
/// <summary>
/// ストリーミングアセットを UnityEngine.WWW で読むための URI を作るクラス。
/// こっちは <see cref="System"/> 名前空間を使わないで実装してます。
/// </summary>
public class StreamingAssetsUriGenUE
{
/// <summary>
/// ストリーミングアセットの基底 URI
/// </summary>
private static string baseUri_ = null;
/// <summary>
/// ストリーミングアセットの基底 URI を取得します。
/// </summary>
/// <value>ストリーミングアセットの基底 URI</value>
public static string BaseUri
{
get
{
if (baseUri_ == null)
{
string path = Application.streamingAssetsPath;
#if !UNITY_EDITOR && (URI_WEB || URI_ANDROID)
baseUri_ = CreateStreamingAssetsUriForAndroid(path);
#elif UNITY_EDITOR_WIN || !UNITY_EDITOR && URI_WIN
baseUri_ = CreateStreamingAssetsUriForWindows(path);
#else
baseUri_ = CreateStreamingAssetsUri(path);
#endif
baseUri_ += "/";
}
return baseUri_;
}
}
/// <summary>
/// ストリーミングアセットの URI を取得します。
/// </summary>
/// <returns>アセットの URI</returns>
public static string GetStreamingAssetsUri()
{
return BaseUri;
}
/// <summary>
/// ストリーミングアセットの URI を取得します。
/// </summary>
/// <returns>アセットの URI</returns>
/// <param name="path">Assets/StreamingAssets からの相対パス ('/' 区切り)</param>
public static string GetStreamingAssetsUri(string path)
{
#if !UNITY_EDITOR && URI_ANDROID
// Android 5 未満では URI エスケープ不要
using (var version = new AndroidJavaClass("android.os.Build$VERSION"))
{
if (version.GetStatic<int>("SDK_INT") < 21)
{
return BaseUri + path;
}
}
#endif
return BaseUri + EscapeUriPath(path);
}
/// <summary>
/// ストリーミングアセットの読み込み
/// </summary>
/// <param name="path">Assets/StreamingAssets からの相対パス ('/' 区切り)</param>
/// <returns>読み込み用のオブジェクト。各自 Dispose() してね</returns>
public static WWW LoadStreamingAssets(string path)
{
return new WWW(GetStreamingAssetsUri(path));
}
#if UNITY_EDITOR || URI_WEB || URI_ANDROID
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// (Web, Android 用)
/// </summary>
/// <returns>The streaming assets URI for android.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUriForAndroid(string path)
{
// Web, Android では streamingAssetsPath がすでに URI
return path;
}
#endif
#if UNITY_EDITOR || URI_WIN
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// (Windows 用)
/// </summary>
/// <returns>The streaming assets URI for windows.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUriForWindows(string path)
{
// 元々 \ だった文字列は / に置換する
var str = EscapeUriPath(path).Replace("%5c", "/");
// パスが // で始まるときは file://hostname/path 形式
// そうでなければ file:///path 形式にする
return (str.Substring(0, 2) == "//" ? "file:" : "file:///") + str;
}
#endif
#if UNITY_EDITOR || URI_OTHER
/// <summary>
/// ストリーミングアセットの基底 URI を作成します。
/// </summary>
/// <returns>The streaming assets URI.</returns>
/// <param name="path">
/// <see cref="UnityEngine.Application.streamingAssetsPath"/>.
/// </param>
/// <summary>※ 引数で渡してるのは単体テストのため</summary>
public static string CreateStreamingAssetsUri(string path)
{
return "file://" + EscapeUriPath(path);
}
#endif
/// <summary>
/// 予約文字をエスケープ
/// </summary>
/// <returns>The URI path.</returns>
/// <param name="path">Path.</param>
static string EscapeUriPath(string path)
{
return WWW.EscapeURL(path)
.Replace("+", "%20")
.Replace("%2f", "/");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment