FC2ブログ
    06 «1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.» 08

    ハルシオンシステムの気ままBlog

    株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

     

    【ハルシオンシステム】TextMeshProのStyleSheetを使ってみた 

    こんにちは。
    大坂です。

    TextMeshProのスタイルシートを使ってみたのでメモ。

    スタイルシートは、[TextMesh Pro]-[Resources]-[Style Sheets]フォルダに「Default Style Sheet」っていうのが入っているのでそのまま使用。


    最初から設定されているものが結構ありますね。


    こんな感じで書いてあげると使えます。




    「</style>」でタグを閉じていますが、
    スタイルタグ以降の文字全部にスタイルを適用する場合はタグを閉じなくても大丈夫です。

    次に新しいスタイルを追加する方法。
    新しく追加するには「Default Style Sheet」のInspctorの下の方にある「+」ボタン押すと追加できます。


    以前、TextMeshProで途中の文字のFontを変えたい時の記事を書きましたが、毎回書くのが面倒なので設定してみます。


    これで「<style="Num">」と書けばフォントが指定したものに変わるので、少し楽になりますね。
    今回は数字の部分だけに適用してみました。



    ちゃんと100の文字だけ変わってますね。

    自分でよく使うタグはスタイルシートにまとめて書いておくと楽ですね。
    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityボタンに連打禁止制御を簡単にかけてみる。もっと簡単な方法あるかもしれませんが・・・ 

    こんにちは。坂内っす。
    30度超えの日々が続きますね・・・・
    来週末東京ゲームダンジョンなんですが、コロナが再び猛威を振るい過去最高の感染者を出してますが・・・・
    行こうと思ってたんだけどどうしようかなぁ・・・やめた方がいいかもなぁ・・・どうしようかなぁ

    さて、Unityでゲームを作ってるとボタンって絶対用意しますよね。
    そのボタンって連打制御されてますか?

    たまに連打制御してなくて、バグが出ちゃうとかありますよね。

    そこで、簡単な連打制御についてメモ。

    こんな画面を作ってみた。


    [Blog20220725.cs]

    using System.Collections;
    using DG.Tweening;
    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20220725 : MonoBehaviour
    {
    [SerializeField] Button btnStart;
    [SerializeField] GameObject objImage;


    void Start()
    {
    btnStart.onClick.AddListener(() => StartCoroutine(MakeImage()));
    }

    IEnumerator MakeImage() {
    Image image = Instantiate(objImage, transform, false).GetComponent<Image>();
    image.DOFade(0f, 3f);
    yield return new WaitForSeconds(3f);
    Destroy(image.gameObject);
    }
    }



    ボタンを押すと、Imageのオブジェクトが生成され、3秒かけて透明になり、最後はオブジェクトを削除する。

    ただこれだけの動きをします。


    このままだと連打制御を入れてないので、連打をするとこうなってしまう。



    オブジェクトが押すたびに増えてしまいます。

    連打制御をいれてみましょう。

    といっても、ただフラグで制御するだけですけどね。

    [Blog20220725.cs]

    using System.Collections;
    using DG.Tweening;
    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20220725 : MonoBehaviour
    {
    [SerializeField] Button btnStart;
    [SerializeField] GameObject objImage;

    bool isProc;

    void Start()
    {
    btnStart.onClick.AddListener(() => StartCoroutine(MakeImage()));
    }

    IEnumerator MakeImage() {
    if (isProc) {
    yield break;
    }
    isProc = true;

    Image image = Instantiate(objImage, transform, false).GetComponent<Image>();
    image.DOFade(0f, 3f);
    yield return new WaitForSeconds(3f);
    Destroy(image.gameObject);
    isProc = false;
    }
    }



    これで連打しても処理が終わるまで次の処理が発生しません。



    こんな感じ。

    これくらいの処理での連打なら問題ないかもしれませんが、シーン遷移とかのボタンで連打されるとまずバグりますよね。

    ということで、以外と大事なのに忘れがちな連打制御についてでした。

    もっと簡単にできる方法もあると思いますが、手軽に制御する方法でした。

    では、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Jsonの書き出し読み込みの時の文字コード 

    こんにちは。
    大坂です。

    Jsonファイルの書き出し読み込みの時の文字コードで少しはまったのでメモがてら。
    もともとあるJsonファイルを書き出して、読み込みなおしたときの話。

    コード。書き出しと、読み込み部分のみ。

    public static string ReadSaveFile(string fileName)
    {
    string file = Application.persistentDataPath + "/" + fileName;
    Encoding encoding = Encoding.UTF8;
    using (StreamReader sr = new StreamReader(file, encoding))
    {
    return sr.ReadToEnd();
    }
    }

    public static void WriteSaveFile(string fileName, string data)
    {
    string file = Application.persistentDataPath + "/" + fileName;
    Encoding encoding = Encoding.UTF8;
    using (StreamWriter sw = new StreamWriter(file, false, encoding))
    {
    sw.Write(data);
    }
    }

    読み込み後のJsonへの変換がうまくいかない。
    Jsonファイルをいくら比較してみても違いが判らなかったのですが、元ファイルの文字コードと書き出し後の新ファイルの文字コードを確認すると
    元ファイル:Shift_JIS
    新ファイル:UTF-8(BOM付き)

    ふむ。まぁ日本語もないしShift_JISでいいかとEncodingをShift_JISに変更

    Encoding部分のみ以下に変更

    Encoding encoding = Encoding.GetEncoding("Shift_JIS");


    これでUnity上ではうまくいったのでよかったと思って、しばらくして実機で動かしたら動かない。
    System.Text.Encoding で Shift JIS を使いたいで解決もできますが、
    なんとなくでUTF-8(BOMなし)にしたらいいじゃないかと思ったので、とりあえずやってみた。

    Encoding部分のみ以下に変更

    Encoding encoding = new UTF8Encoding(false);


    これでUnity上でも実機でも動くようになりました。
    プロジェクトにもよると思いますが、自分で書きだしたJsonを読み込んだときにうまく変換できないときは、文字コードも確認してみるといいかもしれませんね。

    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】シーンをロードするエディタ拡張 

    こんにちは。
    大坂です。

    シーンが多くて、さらにプロジェクトフォルダ内でシーンが別々の場所に置いてあるとシーンを開くのが面倒なときがありますね。
    シーン名で検索してHierarchyにドラッグ&ドロップしたり、ダブルクリックして開いたり。

    プロジェクト内のシーンを検索するエディタ拡張で楽にシーンを開けるので紹介。

    using UnityEditor;
    using UnityEngine;
    using UnityEditor.SceneManagement;
    using System.IO;

    public class SceneLoader : EditorWindow
    {
    private readonly string projectFolderName = "ProjectName";
    private readonly int buttonWidth = 80;

    private Vector2 _scrollPosition = Vector2.zero;
    private string[] scenePaths;

    [MenuItem("Window/SceneLoader")]
    public static void OpenWindow() {
    EditorWindow.GetWindow();
    }

    private void OnEnable() {
    // 全てシーンを検索
    var scenes = AssetDatabase.FindAssets("t:Scene");
    scenePaths = new string[scenes.Length];
    for (var i = 0; i < scenes.Length; ++i) {
    // シーンのパスを取得
    scenePaths[i] = AssetDatabase.GUIDToAssetPath(scenes[i]);
    }
    Repaint();
    }

    private void OnGUI() {
    _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
    foreach (string path in scenePaths) {
    // 指定したプロジェクト名のフォルダのみ表示
    if(path.Contains(projectFolderName)) {
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(Path.GetFileNameWithoutExtension(path), GUILayout.Width(100));
    if (GUILayout.Button("Load", GUILayout.Width(buttonWidth))) {
    // シーンをHierarchyに追加。他のを閉じて指定したものだけを開く場合は「OpenSceneMode.Additive」をけす。
    EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
    }
    var scene = EditorSceneManager.GetSceneByPath(path);
    if (GUILayout.Button("UnLoad", GUILayout.Width(buttonWidth))) {
    // シーンをアンロード
    EditorSceneManager.CloseScene(scene, false);
    }
    if (GUILayout.Button("Remove", GUILayout.Width(buttonWidth))) {
    // シーンをHierarchyから削除
    EditorSceneManager.CloseScene(scene, true);
    }
    EditorGUILayout.EndHorizontal();
    }
    }
    EditorGUILayout.EndScrollView();
    }
    }

    こんな感じで作って開くとこんなWindowが作られます。


    シーンを探したりが面倒な人は使ってみてくださいまし。
    ではではノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityアプリからメールを送る方法。 

    坂内っす。
    東京ゲームダンジョン、Bitsummitまで1カ月が切りましたね。
    遊びには行こうと思ってます。

    ポケガ3を作ってて、Unityのスマホアプリ内からメール送信を実装したので、それをまとめてみた。
    ゲーム内で、質問とかご意見とかメールでおくるやつ。

    Application.OpenURL

    これを使います。

    実際にはスマホに入ってるメーラーを起動するだけなんですけどね。



    string NewLineString = "\n";

    public void SendMail() {
    string subject = "ゲームに関する質問・ご意見";

    string deviceName = SystemInfo.deviceModel;

    // デバイス名、OS、アプリのバージョン、言語をメールに貼り付け
    string body = NewLineString + NewLineString + "以下はこのままお送りくださいませ" + NewLineString;
    body += "Device:" + deviceName + NewLineString;
    body += "OS:" + SystemInfo.operatingSystem + NewLineString;
    body += "Ver:" + Application.version + NewLineString;
    body += "Language:" + Application.systemLanguage.ToString() + NewLineString;

    //エスケープ処理
    body = System.Uri.EscapeDataString(body);
    subject = System.Uri.EscapeDataString(subject);

    Application.OpenURL($"mailto:{Constant.MailAddr}?subject={subject}&body={body}");
    }



    2016年にも同じような記事書いてますが、もう一度!

    この時と違うのが、エスケープ処理ですね。

    string title = WWW.EscapeURL("文字");

    ってやってたんですが、WWW.EscapeURLが古くなり、使えなくなるとのことで、System.Uri.EscapeDataStringに変わってます。
    ここ、注意くださいませ。

    必要な情報をbodyにつけて送ってもらえば色々と調査とかしやすいかもしれませんね。

    ということで、Unityアプリからメールを送る方法でした。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Tupleの戻り値をわかりやすく使う 

    こんにちは。
    大坂です。

    以前Tupleの記事は何個書いてありますが、受取った後「Item1」とかで使うとわかりにくいよねっていうお話。


    void Start()
    {
    var (ran, isSuccess) = TupleTest();

    Debug.Log($"{ran}:{isSuccess}");
    }


    public (int, bool) TupleTest()
    {
    int ran = Random.Range(0, 100);
    if(ran < 50)
    {
    return (ran, true);
    }
    else
    {
    return (ran, false);
    }
    }



    「Item1」とかにするよりこの方が可読性良く使えますね。
    では今週もこれにてノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityの実行中にいじったオブジェクトの位置などを、停止後に持ってきたい時こうすればいいよって話 

    7月になっちゃいました。
    1年も後半戦にはいっちゃいましたね。
    やべー 今年おわっちゃうよ!!

    Unityの実行中にオブジェクトの位置とかを変えた時って、「あ・・・」ってなりますよね。
    ここに置きたいんだけど、実行中だった・・・

    もちろん停止すると、動かす前の座標に戻ってしまう・・・・


    こんな感じで、停止すると元の位置に戻ってしまいます。


    そんな時、慌てないでコンポーネントをコピーしましょう。



    移動したオブジェクトのコンポーネントをコピーします。(ここでは位置を残したいので、Transformのコンポーネントをコピー)

    停止し、オブジェクトのTransformにペーストします。

    これで実行中の位置をもって来ることができました。

    1つのものしかコピペできないですが、少しは使いやすいんじゃないでしょうか。

    メモ程度ですが、こんな感じで本日の記事終わりです。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0