377 lines
14 KiB
C#
377 lines
14 KiB
C#
/*
|
|
* ExternalReceiver
|
|
* https://sabowl.sakura.ne.jp/gpsnmeajp/
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2020-2022 gpsnmeajp
|
|
*
|
|
* 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.
|
|
*/
|
|
#pragma warning disable CS0162
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.Serialization;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditor.AnimatedValues;
|
|
using UnityEngine.Events;
|
|
using System.Linq;
|
|
|
|
namespace EVMC4U
|
|
{
|
|
public class Tutorial : EditorWindow
|
|
{
|
|
const bool check = false; //バージョンチェック条件式があったが、バージョン番号がなくなったので無効化
|
|
const int window_w = 400;
|
|
const int window_h = 400;
|
|
|
|
//ページ名
|
|
static string page = "";
|
|
|
|
//ボタン押下アニメーション
|
|
static AnimFloat anim = new AnimFloat(0.001f);
|
|
static string animTargetName = ""; //1つのボタンだけアニメさせる識別名
|
|
|
|
static string jsonError = "";
|
|
|
|
static TutorialJson tutorialJson = null;
|
|
static Dictionary<string, TutorialPage> tutorialPages = new Dictionary<string, TutorialPage>();
|
|
|
|
//JSON設定ファイル定義
|
|
[Serializable]
|
|
private class TutorialJson
|
|
{
|
|
public bool debug;
|
|
public TutorialPage[] pages;
|
|
public override string ToString()
|
|
{
|
|
return "TutorialJson debug:" + debug + " pages:" + pages.Length;
|
|
}
|
|
}
|
|
|
|
//JSONページ定義
|
|
[Serializable]
|
|
private class TutorialPage
|
|
{
|
|
public string name = "";
|
|
public string text = "";
|
|
public string image = "";
|
|
public TutorialButton[] buttons = new TutorialButton[0];
|
|
|
|
public override string ToString()
|
|
{
|
|
return "TutorialPage name:" + name + " text:" + text + " iamge:" + image + " buttons:" + buttons.Length;
|
|
}
|
|
}
|
|
|
|
//JSONボタン定義
|
|
[Serializable]
|
|
private class TutorialButton
|
|
{
|
|
public int x = 0;
|
|
public int y = 0;
|
|
public int w = 0;
|
|
public int h = 0;
|
|
|
|
public string text = "";
|
|
|
|
public string image = "";
|
|
public string uri = ""; //"page://" = page, "http://" or "https://" = url
|
|
public string fire = ""; //event
|
|
public override string ToString()
|
|
{
|
|
return "TutorialButton (" + x + "," + y + "," + w + "," + h + ") text:" + text + " image:" + image + " uri:" + uri;
|
|
}
|
|
}
|
|
|
|
[InitializeOnLoadMethod]
|
|
static void InitializeOnLoad()
|
|
{
|
|
//一度も開いたことない場合は、ここで開く
|
|
if (EditorUserSettings.GetConfigValue("Opened") != "1" || (check && EditorUserSettings.GetConfigValue("VRMCheckCaution") != "1"))
|
|
{
|
|
Open();
|
|
}
|
|
}
|
|
|
|
[MenuItem("EVMC4U/Oepn Tutorial")]
|
|
public static void Open()
|
|
{
|
|
//ウィンドウサイズを固定
|
|
var window = GetWindow<Tutorial>();
|
|
window.maxSize = new Vector2(window_w, window_h - 6);
|
|
window.minSize = window.maxSize;
|
|
|
|
//アニメーション定義
|
|
anim.value = 0.001f;
|
|
anim.speed = 10f;
|
|
anim.target = 0.001f;
|
|
anim.valueChanged = null;
|
|
|
|
if (Resources.Load<TextAsset>("tutorial/define") == null)
|
|
{
|
|
//読み込み準備ができていない
|
|
return;
|
|
}
|
|
|
|
//ページを初期位置に設定
|
|
page = "start";
|
|
if (EditorUserSettings.GetConfigValue("Language") == "ja")
|
|
{
|
|
page = "start_ja";
|
|
}
|
|
if (EditorUserSettings.GetConfigValue("Language") == "en")
|
|
{
|
|
page = "start_en";
|
|
}
|
|
|
|
|
|
//データを読み込む
|
|
tutorialPages = new Dictionary<string, TutorialPage>();
|
|
|
|
try
|
|
{
|
|
jsonError = "";
|
|
var r = Resources.Load<TextAsset>("tutorial/define");
|
|
tutorialJson = JsonUtility.FromJson<TutorialJson>(r.text);
|
|
if (tutorialJson.debug)
|
|
{
|
|
Debug.Log(tutorialJson);
|
|
}
|
|
|
|
//各ページのデータを読み込む
|
|
foreach (var p in tutorialJson.pages)
|
|
{
|
|
tutorialPages.Add(p.name, p);
|
|
if (tutorialJson.debug)
|
|
{
|
|
Debug.Log(p);
|
|
}
|
|
}
|
|
|
|
//一度開いたのを覚えておく
|
|
EditorUserSettings.SetConfigValue("Opened", "1");
|
|
}
|
|
catch (ArgumentException e)
|
|
{
|
|
//Debug.LogError(e);
|
|
jsonError = e.ToString();
|
|
tutorialJson = null;
|
|
}
|
|
|
|
//バージョンチェック(失敗したら失敗ページに飛ばす)
|
|
if (check)
|
|
{
|
|
EditorUserSettings.SetConfigValue("VRMCheckCaution", "1");
|
|
page = "versionCheckFailed";
|
|
}
|
|
else
|
|
{
|
|
EditorUserSettings.SetConfigValue("VRMCheckCaution", "0");
|
|
}
|
|
}
|
|
|
|
[MenuItem("EVMC4U/Reset Language")]
|
|
public static void ResetLanguage()
|
|
{
|
|
EditorUserSettings.SetConfigValue("Language", "");
|
|
Open();
|
|
}
|
|
|
|
void OnGUI()
|
|
{
|
|
//ページを開いたまま初期化されたら、初期ロード処理に飛ばす
|
|
if (page == "")
|
|
{
|
|
GUI.Label(new Rect(10, 10, window_w, window_h), "INVALID STATE\n\nチュートリアルの読み込みに失敗しました。Unityを再起動してください。\nそれでもダメな場合は、UnityPackageの導入からやり直してみてください\n\nTutorial load failed.\nPlease restart Unity.\nor Please re-import UnityPackage.");
|
|
Open();
|
|
return;
|
|
}
|
|
|
|
//アニメーションを立ち上げる
|
|
if (anim.valueChanged == null)
|
|
{
|
|
var repaintEvent = new UnityEvent();
|
|
repaintEvent.AddListener(() => Repaint());
|
|
anim.valueChanged = repaintEvent;
|
|
}
|
|
|
|
//アニメーション折り返し
|
|
if (anim.value > anim.target - 0.1f)
|
|
{
|
|
anim.target = 0.001f;
|
|
}
|
|
|
|
//ページの表示処理を開始
|
|
TutorialPage tutorialPage;
|
|
if (!tutorialPages.TryGetValue(page, out tutorialPage))
|
|
{
|
|
//JSONが多分バグってるときに表示
|
|
GUI.Label(new Rect(10, 10, window_w - 20, window_h), "JSON LOAD FAILED\n" + jsonError + "\n\nチュートリアルの読み込みに失敗しました。Unityを再起動してください。\nそれでもダメな場合は、UnityPackageの導入からやり直してみてください\n\nTutorial load failed.\nPlease restart Unity.\nor Please re-import UnityPackage.");
|
|
if (GUI.Button(new Rect(0, window_h - 30, window_w, 30), "Reload"))
|
|
{
|
|
Open();
|
|
}
|
|
return;
|
|
}
|
|
|
|
//デバッグログ
|
|
if (tutorialJson.debug)
|
|
{
|
|
Debug.Log("OnGUI: " + anim.value);
|
|
Debug.Log(tutorialPage);
|
|
}
|
|
|
|
//背景画像があれば表示
|
|
if (tutorialPage.image != "")
|
|
{
|
|
var bgtexture = Resources.Load<Texture>("tutorial/" + tutorialPage.image);
|
|
EditorGUI.DrawPreviewTexture(new Rect(0, 0, window_w, window_h), bgtexture);
|
|
}
|
|
|
|
//ページのテキストを表示(代替テキスト)
|
|
GUI.Label(new Rect(0, 0, window_w, window_h), tutorialPage.text);
|
|
|
|
//ボタンを1つずつ表示
|
|
foreach (var b in tutorialPage.buttons)
|
|
{
|
|
if (tutorialJson.debug)
|
|
{
|
|
Debug.Log(b);
|
|
}
|
|
|
|
//ボタンに画像があればそれを表示
|
|
if (b.image != "")
|
|
{
|
|
//画像を読み込む
|
|
var texture = Resources.Load<Texture>("tutorial/" + b.image);
|
|
|
|
//位置情報がない場合、下端として扱う
|
|
if (b.x == 0 && b.y == 0 && b.w == 0 && b.h == 0)
|
|
{
|
|
b.y = window_h - window_w * texture.height / texture.width;
|
|
b.w = window_w;
|
|
}
|
|
|
|
string buttonName = "btn#" + page + "#" + b.x + "-" + b.y + "-" + b.w + "-" + b.h;
|
|
float height = b.w * texture.height / texture.width;
|
|
|
|
Rect r = new Rect(b.x, b.y, b.w, height);
|
|
|
|
//アニメ対象の場合だけ動く
|
|
if (buttonName == animTargetName)
|
|
{
|
|
r = new Rect(b.x + anim.value, b.y + anim.value, b.w, height);
|
|
}
|
|
|
|
//ボタンを表示
|
|
if (GUI.Button(r, texture, new GUIStyle()))
|
|
{
|
|
//アニメーション処理と、遷移を実行
|
|
buttonFireProcess(b.fire);
|
|
buttonUriProcess(b.uri);
|
|
animTargetName = buttonName;
|
|
anim.target = 2f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//テキストボタンを表示
|
|
if (GUI.Button(new Rect(b.x, b.y, b.w, b.h), b.text))
|
|
{
|
|
buttonFireProcess(b.fire);
|
|
buttonUriProcess(b.uri);
|
|
}
|
|
}
|
|
}
|
|
|
|
//デバッグ再読み込みボタン
|
|
if (tutorialJson.debug)
|
|
{
|
|
if (GUI.Button(new Rect(0, window_h - 30, 30, 30), "#"))
|
|
{
|
|
Open();
|
|
}
|
|
}
|
|
}
|
|
|
|
void buttonUriProcess(string uri)
|
|
{
|
|
if (tutorialJson.debug)
|
|
{
|
|
Debug.LogWarning("buttonProcess: " + uri);
|
|
}
|
|
|
|
if (uri == null)
|
|
{
|
|
return;
|
|
}
|
|
if (uri.StartsWith("page://"))
|
|
{
|
|
page = uri.Replace("page://", "");
|
|
}
|
|
if (uri.StartsWith("http://") || uri.StartsWith("https://"))
|
|
{
|
|
System.Diagnostics.Process.Start(uri);
|
|
}
|
|
}
|
|
|
|
void buttonFireProcess(string fire)
|
|
{
|
|
switch (fire)
|
|
{
|
|
case "SaveLanguageJa":
|
|
{
|
|
EditorUserSettings.SetConfigValue("Language", "ja");
|
|
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone).Split(';').ToList();
|
|
if (symbols.Contains("EVMC4U_EN"))
|
|
{
|
|
symbols.Remove("EVMC4U_EN");
|
|
}
|
|
if (!symbols.Contains("EVMC4U_JA"))
|
|
{
|
|
symbols.Add("EVMC4U_JA");
|
|
}
|
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, String.Join(";", symbols.ToArray()));
|
|
|
|
break;
|
|
}
|
|
case "SaveLanguageEn":
|
|
{
|
|
EditorUserSettings.SetConfigValue("Language", "en");
|
|
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone).Split(';').ToList();
|
|
if (symbols.Contains("EVMC4U_JA"))
|
|
{
|
|
symbols.Remove("EVMC4U_JA");
|
|
}
|
|
if (!symbols.Contains("EVMC4U_EN"))
|
|
{
|
|
symbols.Add("EVMC4U_EN");
|
|
}
|
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, String.Join(";", symbols.ToArray()));
|
|
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
} |