Aseprite の UI を見やすくする

はじめに

Aseprite は優れたドット絵エディターですが、自身がドット絵エディターであることを主張するかのように、UI にもドットフォントが採用されています。

f:id:Gigacee:20200427003258p:plain
Aseprite のデフォルトのトップ画面

これはこれで味があって良いのですが、さすがに見づらいので、普通の見た目に変更しようと思います。

テーマを変更する

Aseprite にはテーマを変更できる機能が備わっているので、これを用いてアウトラインフォントを使用するテーマに変更します。

Minimal Dark HD をダウンロードし、次に Aseprite の [Edit] > [Preferences] > [Extensions] > [Add Extension] で拡張機能追加ウィンドウを開き、ダウンロードしたテーマファイルを追加します。

f:id:Gigacee:20200427003304p:plain
[Preferences] をクリックし……

f:id:Gigacee:20200427003309p:plain
[Extensions] 内の [Add Extension] をクリック

f:id:Gigacee:20200427003314p:plain
ダウンロードしたテーマを選択

これで、Aseprite に Minimal Dark HD テーマが追加されました。[Edit] > [Preferences] > [Themes] で Minimal Dark HD を選択すると、Aseprite の外観が変わり、フォントがアウトラインのものになります。

f:id:Gigacee:20200427003318p:plain
[Theme] 内の [Minimal Dark HD] を選択して [Select]

f:id:Gigacee:20200427003322p:plain
Minimal Dark HD テーマが適用された

日本語化する

UI が英語のままで問題ない場合はここまでで OK ですが、Aseprite には有志による日本語訳も用意されており、日本語化が可能です。ついでにそれもやっておきます。

Aseprite JP Wiki* から日本語化ファイルをダウンロードし(Zip ファイルですが、解凍する必要はありません)、先ほどと同じように [Edit] > [Preferences] > [Extensions] > [Add Extension] で日本語化ファイルを追加します。

すると、[Edit] > [Preferences] > [General] > [Language] の項目に「japanese」が追加されるので、それを選択すると、UI が日本語になります、が……。

f:id:Gigacee:20200427003331p:plain
[Language] を [japanese] にすると日本語化されるが……

f:id:Gigacee:20200427003335p:plain
このままだと、日本語のフォントがおかしい

日本語のフォントがおかしくなってしまっているので、これも修正します。[編集] > [環境設定] > [テーマ] で Minimal Dark HD を選択後、右下の [フォルダを開く] を押してテーマのフォルダを開き、theme.xml を開きます。

f:id:Gigacee:20200427003342p:plain
[テーマ] 内で [Minimal Dark HD] を選択した上で、右下の [フォルダを開く] を押す

f:id:Gigacee:20200427003348p:plain
Minimal Dark HD がインストールされているフォルダが表示されるので、theme.xml を開く

6 行目 ~ 13 行目がフォントを設定している部分なので、ここを好きな日本語フォントに書き換えます。ここでは源真ゴシックPに書き換えます。フォントはあらかじめ OS にインストールしておいてください。

<!-- 変更前 -->

<fonts>
    <font id="default" name="SegoeUi" type="truetype" file="segoeui.ttf" size="12">
        <fallback font="Unicode" size="12" />
    </font>
    <font id="mini" font="SegoeUi" size="11">
        <fallback font="Unicode" size="11" />
    </font>
</fonts>

<!-- 変更後 -->

<fonts>
    <font id="default" name="genshingothic" type="truetype" file="genshingothic-p-regular.ttf" size="12">
        <fallback font="Unicode" size="12" />
    </font>
    <font id="mini" font="genshingothic" size="11">
        <fallback font="Unicode" size="11" />
    </font>
</fonts>

書き換えができたら、Aseprite を再起動して、フォントが変わっているのを確認します。

f:id:Gigacee:20200427003354p:plain
日本語フォントが指定したフォントに変更された

まとめ

以上で、Aseprite の UI を見やすくすることができました。theme.xml をいじれば、フォントのサイズなども変更することができるので、自分好みの設定を見つけてみてください。

本当はフォントは Yu Gothic UI にしたかったんですけど、なぜかできなかったんですよね……。やり方をご存じの方がいらっしゃったら、コメントで教えてくださると嬉しいです!

Project ウィンドウで任意のディレクトリを一番上にする

Unity プロジェクトのディレクトリ構成についてです。

Unity では、AssetStore などから外部アセットをインポートすると、ほとんどの場合 Assets/ ディレクトリ直下に配置されます。そのため、自身で作成したシーンやスクリプトを Assets/ 直下に作ってしまうと、外部アセットと混ざって見つけづらくなってしまいます。

f:id:Gigacee:20200403162617p:plain

これを避けるため、自身で作ったファイルは一つのディレクトリにまとめて管理するというハックがあります。

f:id:Gigacee:20200403162621p:plain

ですが、そのまとめたディレクトリ自体が他の外部アセット群の中に埋もれてしまうという問題は残ったままです。なんとかしてこのディレクトリを一番上に持っていきたいのですが、どうしたらよいでしょうか。

ちなみに、環境は Windows です。

「_MyProject」

こういう場合によく使われるのは、先頭に _ を付けるというやり方です。ですが……。

f:id:Gigacee:20200403162624p:plain

このように、なぜか Unity の Project ウィンドウ内では数字の方が序列が上になっていて、数字から始まる外部アセットがある場合は一番上に来てくれません。

「-MyProject」

今度は - にしてみます。そうすると、ちゃんと一番上に来てくれました。

f:id:Gigacee:20200403162629p:plain

が、今度はエクスプローラーで問題が起こります。

f:id:Gigacee:20200403162633p:plain

このように、 - は無いものとして扱われてしまいます。なんでや……。

「#MyProject」

Unity 内でもエクスプローラーでも一番上に表示されるような記号はないものか……と探してみたら、ありました。 # です。

f:id:Gigacee:20200403162638p:plain

f:id:Gigacee:20200403162641p:plain

良いですね! これで内部のファイルが見つけやすくなったと思います。

JavaScript からマクロを実行する

既存のタグを JavaScript から実行する方法は探せば見つかるのですが、マクロを実行する方法は見つからなかったので、自分で調べた方法を書き残しておきます。

コード

[macro name="macro_test"]
    マクロが呼ばれました。
[endmacro]

[iscript]
    let macro = TYRANO.kag.stat.map_macro["macro_test"]

    TYRANO.kag.ftag.nextOrderWithIndex(macro.index, macro.storage)
[endscript]

実行結果

f:id:Gigacee:20200202173741p:plain

TYRANO.kag.stat.map_macro にマクロが一式入っているので、その中から実行したいマクロを探して、そのデータを nextOrderWithIndex に渡しています。

引数を渡す場合

以下のように書くことで、引数も渡せます。

コード

[macro name="macro_test"]
    [font color="&mp.color"]
        マクロが呼ばれました。
    [resetfont]
[endmacro]

[iscript]
    let macro = TYRANO.kag.stat.map_macro["macro_test"]

    TYRANO.kag.stat.mp = {
        color: "0xff00ff"
    }

    TYRANO.kag.ftag.nextOrderWithIndex(macro.index, macro.storage)
[endscript]

実行結果

f:id:Gigacee:20200202175002p:plain

注意

直接 nextOrderWithIndex を実行しているので、内部的にはイレギュラーな処理になっています。もしかしたらどこかでエラーが起こるかも……。新しい情報が見つかったら、この記事もアップデートしたいと思います。

GitKraken Glo のカードの一覧を CSV に出力する

個人用のタスク管理ツールとして、「GitKraken Glo」という Trello 風のカンバンボードを使っているのですが、このサービス、エクスポート機能がまだ無いんですよね。

幸い API は公開されていて、それを Python から叩ける py-glo-board というライブラリを作ってくださった方がいらっしゃるので、今回はこれを利用して、全カードの一覧を CSV に出力するスクリプトを作成しました。

github.com

全カードと言っておいて申し訳ないのですが、1 ボード 100 枚のカードまでしか取ってこれません💦 使う際は、不要なカラムをアーカイブするなどして、100 枚以下に収めてください😭(Pull Request 歓迎です🙌)

サウンドデバイスの名前に「2-」がついてしまう問題

サウンドデバイスを異なるポートに接続したり外したりをしていると、たまに名前の頭に「2-」というプレフィックスが付いてしまいます。

f:id:Gigacee:20191218125157p:plain

実害は無いのですが、なんとも気持ち悪い。消してしまいましょう。

デバイスマネージャーを開き……。

f:id:Gigacee:20191218125200p:plain

該当のサウンドデバイスをアンインストールします。

再起動を要求されるので、そのまま再起動。すると……。

f:id:Gigacee:20191218125201p:plain

晴れて綺麗なデバイス名になりました😊

DOTweenList: DOTween の複数の Tween をまとめて再生したり、待機したりできるようにする

はじめに

DOTween を使っていて、複数のアニメーションを同時に再生したり、完了を待機したりしたいという場面はよくありますよね。

単体のアニメーションなら作るのも楽ですが、アニメーションというものは複数の動きが複雑に連関しがちなもので、複雑になればなるほどコードも長く、ぐちゃぐちゃになっていきます。

例えば「A, B, C のアニメーションがすべて完了するまで待機」みたいなことをしたい場合、それらすべてに完了コールバックを設定して、すべてのコールバックが実行されたかどうかを毎フレーム確認する……みたいに書かねばならず*1、大変面倒です。

bool flagA;
bool flagB;
bool flagC;

void PlayTweens()
{
    transformA.DOMoveX(100f, 1f).OnComplete(() => flagA = true);
    transformB.DOMoveX(100f, 2f).OnComplete(() => flagB = true);
    transformC.DOMoveX(100f, 3f).OnComplete(() => flagC = true);
}

void Update()
{
    if (flagA && flagB && flagC)
    {
        // すべての Tween が完了したら実行される処理
    }
}

さらにその上、アニメーション中にボタンを押したらスキップできる、みたいな仕様が加わることも……。

そういったことがもっと簡単にできるように、複数の Tween を一つにまとめて一括で処理をしたり、待機したりできるようなクラスを作ってみました。

github.com

これを用いると、先の例はこんなふうに書けます。

async UniTask PlayTweensAsync()
{
    await new DOTweenList(
        transformA.DOMoveX(100f, 1f),
        transformB.DOMoveX(100f, 2f),
        transformC.DOMoveX(100f, 3f)
    );

    // すべての Tween が完了したら実行される処理
}

簡潔で、なかなか良くないですか?

説明

GitHub の README にも説明書きはありますが、ここではそれよりもう少し詳しめに説明をしていこうと思います。

注意

以下のアセットが別途必要です。

待機のところで UniTask を使用しています*2

インストール

上記 2 つのアセットをインポートしたあと、DOTweenList.cs を任意のディレクトリに配置してください。

UnityPackage を使用してインストールすることもできます。

使い方

準備

まず、DOTweenList に処理したい Tween を詰めます。以下の 3 つの方法があります:

(i) コンストラクター

var dotweenList = new DOTweenList(
    rectA.DOAnchorPosX(600f, 0.6f),
    rectB.DOAnchorPosX(600f, 0.8f),
    rectC.DOAnchorPosX(600f, 1f)
);

一番簡単。まとめたい Tween が最初から全部揃っている場合は、これを使うと良いでしょう。

(ii) Add()メソッド

var dotweenList = new DOTweenList();

dotweenList.Add(rectA.DOAnchorPosX(600f, 0.6f));
dotweenList.Add(rectB.DOAnchorPosX(600f, 0.8f));
dotweenList.Add(rectC.DOAnchorPosX(600f, 1f));

Add()を使えば、あとから別の Tween を追加することもできます。

(iii) AddTo()拡張メソッド

var dotweenList = new DOTweenList();

rectA.DOAnchorPosX(600f, 0.6f).AddTo(dotweenList);
rectB.DOAnchorPosX(600f, 0.8f).AddTo(dotweenList);
rectC.DOAnchorPosX(600f, 1f).AddTo(dotweenList);

Add()の拡張メソッド版です。お好みの方をお使いください。

処理を実行

DOTweenList には、以下の処理を実行できます。

// 再生
dotweenList.PlayForward();

// 逆再生
dotweenList.PlayBackwards();

// 最初に戻す
dotweenList.Rewind();

// 最後に進める
dotweenList.Complete();

// 強制終了
dotweenList.Kill();

メソッド名の末尾にByIdを加えることで、特定の ID の Tween のみに処理を実行できます。

dotweenList.PlayForwardById("id");

dotweenList.PlayBackwardsById("id");

dotweenList.RewindById("id");

dotweenList.CompleteById("id");

dotweenList.KillById("id");

また、PlayForward()PlayBackwards()には引数として bool 値を渡すことができ、true を設定するとアニメーションが途中であっても強制的に最初から(PlayBackwards()なら最後から)再生することができます。

// 最初から再生
dotweenList.PlayForward(true);

// こう書くのと同じ
dotweenList.Rewind();
dotweenList.PlayForward();

この他、以下のメソッドが用意されています。

// Tween がどれか一つでも再生中なら true を返す
dotweenList.IsPlaying();

// リストをクリアする
dotweenList.Clear();

// すべての Tween の再生開始から終了までにかかる時間を取得する
// 注意:Tween が再生中であっても、開始からの時間が返る
dotweenList.GetTotalTime();

// 特定の ID を持つすべての Tween の再生にかかる時間を取得する
// 注意:Tween が再生中であっても、開始からの時間が返る
dotweenList.GetTotalTimeById("id");

待機

awaitを付与することで、再生終了まで待機することができます。

// 再生を開始し、終了まで待機する
await dotweenList.PlayForward();

// すでに再生中の Tween を待つこともできる
await dotweenList;

// 昔ながらのコルーチンで待機しても OK
yield return dotweenList.PlayForward();

そして目玉機能! 拡張メソッドのSkippable()を用いれば、指定した条件で Tween をスキップすることができます。

// 再生終了まで待機する。何かキーを入力するとスキップする
await dotweenList.PlayForward().Skippable(() => Input.anyKeyDown);

DOTween Animation

DOTween Pro の機能である DOTween Animation を DOTweenList に詰める場合は、以下のように書きます。

var dotweenList = new DOTweenList(GetComponent<DOTweenAnimation>().GetTweens());

最後に

使っていておかしなところや改善点を見つけたら、Issues でご報告ください。Pull Request も大歓迎です!

*1:もしかしたらもっと良い書き方があるのかも知れませんが……もしあったらコメントで教えて下さい!

*2:UniTask は、Tween に限らず非同期処理をしたいときにめちゃくちゃ有用なので、await/async を使っているならぜひ導入すべきです。

UniTask.Delay にスキップ機能を追加する

ゲームを作っていると、「一定時間待機するが、途中で何かキーを押したらスキップできる」みたいな処理を入れたいときがよくあります。

「一定時間待機する」は

await UniTask.Delay(delay_ms)

で、「途中で何かキーを押したらスキップ」は

await UniTask.WaitUntil(() => Input.anyKeyDown)

で、それぞれ実現できるので、これをWhenAnyで融合すれば良いのですが、いちいち書くのも面倒なので、以下のようなメソッドを作りました。

using System;
using System.Threading;
using UniRx.Async;
using UnityEngine;

public static class UniTaskHelper
{
    public static async UniTask DelaySkippable(int delay_ms, Func<bool> cond)
    {
        var cts = new CancellationTokenSource();

        await UniTask.WhenAny(
            UniTask.Delay(delay_ms, cancellationToken : cts.Token),
            UniTask.WaitUntil(cond, cancellationToken : cts.Token)
        );

        cts.Cancel();
    }
}

以下のようにして使います:

await UniTaskHelper.DelaySkippable(1000, () => Input.anyKeyDown);

Input.anyKeyDown の部分を変えれば、好きな条件でスキップできるようになります。

※ このコードの原型は、naichi さんに教えていただきました。どうもありがとうございました😌

The coloring of this site is Dracula PRO🧛🏻‍♂️
This website uses the FontAwesome icons licensed under CC BY 4.0.

2020 GIGA CREATION