akyboxブログ

旧AkiIroブログ

【UE5】キーボード入力が効かないときに確認すること

AutoInputの設定は適切に設定されているか


Disableになっていないか確認する

AutoProcessPlayerは適切に設定されているか


Disableになっていないか確認する

他のActorに入力を奪われていないか


ConsumeInputが有効になっていると他に入力を奪われうる

Gitを使ってたらhooksフォルダとlfsフォルダが突然できて消えなくなった

突如出現したhooksとlfsフォルダ
画像のように突然hookslfsフォルダが出現する現象に出くわしました。

削除してもすぐに再生成されてしまいます。

このフォルダは通常は.gitフォルダの中ににあるはず…なぜ?

.gitフォルダの中にもある
調べてみるとどうやらgit-lfsの不具合のようです。

github.com

私の環境はWindowsgit-lfsのバージョンは2.11.0でした。

最新では直っているらしいので手元の環境を更新し、lfshooks.gitフォルダの中に戻してあげることで解決しました。

ちなみに更新後は
gitバージョン:2.37.3
git-lfsバージョン:3.2.0

Fedoraでフルスクリーン表示した動画が切れる(Tearing)

Fedora Tearing Fullscreen Video

対象

以下の動画で画面が切れてしまう(Tearing)系Fedoraユーザー
www.youtube.com
つまり本稿は個人的な備忘録です。

調べると以下の掲示板やQAがヒットします。
https://bugzilla.mozilla.org/show_bug.cgi?id=1134077
https://ask.fedoraproject.org/en/question/80141/screen-tearing-fedora-23-gtx-970/

なんとなく以下の拡張をいれれば解決するという雰囲気です。
github.com

以下のサイトに行ってGnome-Extensionを有効にしたら、
Installed Extensions - GNOME Shell Extensions

書いてあるとおり、以下のコマンドを実行します。

bash -c '(cd ~/.local/share/gnome-shell/extensions; curl -LkSs https://api.github.com/repos/kazysmaster/gnome-shell-extension-disable-unredirect/tarball | tar -xvz --wildcards --strip 1 "kazysmaster-gnome-shell-extension-disable-unredirect-???????/unredirect@vaina.lt")'

もしフォルダがないとか言われたら、何かしら別の拡張を有効にしたりすればフォルダがつくられるはずです。

うまくいけば、こんな風に拡張機能が足されて、有効にしたらTearingは直るかもしれません。
f:id:AkiIro:20190206013659p:plain

【Unity】コマンドプロンプト(CMD)を開くEditor拡張

f:id:AkiIro:20180910225729g:plain
gifはechoでTESTと言わせているだけです.

Unityからプロセスを起動する

ざっと以下のスクリプトでgifのようなことができます.

Unityからコマンドプロンプトを起動するスクリプト.

以下の部分はcmd.exeに投げるコマンドなので,ここを変えれば当然いろいろなことができます.

"/k echo TEST"

ここを

"/c echo TEST"

とするかCallの引数 isHide を true とすることでウィンドウを隠せます.

ご自由にご活用ください.

Unity-QuickSheet入門 ~SpreadSheetを読みこむ~

Unity-QuickSheetでSpreadSheetを読んでScriptableObjectをつくる.

Unity-QuickSheetとは
github.com

ざっくりExcelやSpreadSheetをScriptableObjectにすることができます.

本家のドキュメントはこちら. Google Howto · Unity-QuickSheet
本記事は大体焼き増しです.

大きく2ステップ

  • OAuthのセットアップ
  • Unity側で受け取りのセットアップ

ドライブにアクセスするためにOAuth2をセットアップ(Setting up OAuth2 for accessing Google Drive)

SpreadSheetを作る

一行目はフィールドの名前に利用されます.
なのでIntとかFloatといった名前はやめましょう.
そしてValueもやめましょう.(体験談)

理由は後々わかりますが,シート名をHogeDataみたいにすると悲しいことになります.(体験談)

OAuth2の設定をする

プロジェクトを作る

このページからやります. http://console.developers.google.com/
プロジェクトを作ります. f:id:AkiIro:20180820231945p:plain 名前とかは適当で大丈夫です.

OAuthClientIDを取得する

f:id:AkiIro:20180820232248p:plain
サービス名を設定する IDの作成にはサービス名の設定が必要だと言われたらおとなしく設定します. f:id:AkiIro:20180820232336p:plain サービス名は適当で大丈夫です.

気を取り直してOAuthClientIDをつくります. f:id:AkiIro:20180820232430p:plain
アプリケーションの種類はその他で名前は適当です.

うまくいけばこんな画面がでるはずです. f:id:AkiIro:20180820232922p:plain
OKで閉じます.

設定用JSONをダウンロードする

ここからダウンロードします. f:id:AkiIro:20180820233345p:plain

手に入れたJSONを使ってClientIDとClientSecretを入力します.
以下のフォルダーにGoogle Data Settingsというアセットがあるはずです.

Assets/QuickSheet/GDataPlugin/Editor

f:id:AkiIro:20180820233039p:plain
I have OAuth2 JsonをチェックしてJSONを参照するとClientIDとClientSecretは自動的に入力されます.
入力されたらStart Authenticationを押します.
ブラウザが開いて進めていくとこんな画面がでます.
f:id:AkiIro:20180820234139p:plain
これがアクセスコードなので,AccessCodeに貼り付けます.
Finish Authencationを押して完了です.

ランタイムパスとエディターパスは公式によると

Runtime Path: Data/Runtime
Editor Path: Data/Editor

これで十分らしいので何も考えず設定します.
後ほどわかりますがRuntimePathはランタイムに使われるスクリプトが置かれ,EditorPathはエディターで使われるスクリプトが置かれます. フォルダーがないと後でエラーします.(つまりこの場合Assets/Data/Runtimeを用意しておく必要があります.)

以上でOAuthのセットアップは完了です.

Unity側でデータを受け取るScriptableObjectを作る

Unity上での操作です.

設定ファイルをつくる(Creating Google Spreadsheet Setting File)

f:id:AkiIro:20180820234508p:plain
場所はどこでもいいですが,私はToolというフォルダを作りました.
f:id:AkiIro:20180820235447p:plain
ファイル名とシート名を入力してImportボタンを押すと以下のようになります.
f:id:AkiIro:20180820234648p:plain
(なお,シート名がDataとなっているのは完全に失敗です.)
Typeを設定してGenerateします.
うまくいけばRuntimePathとEditorPathにスクリプトがつくられます.

以下のようになった人は

f:id:AkiIro:20180820234906p:plain
フォルダが用意されていません.RuntimePathとEditorPathにあたるフォルダをつくっておきます.

スプレッドシートのデータをインポートする(Importing Spreadsheet Data)

受け皿になるScriptableObjectをつくります.
f:id:AkiIro:20180820235416p:plain
Downloadボタンを押せば
f:id:AkiIro:20180820235703p:plain
以上です.お疲れ様でした.

【Unity】ReadMeつくるEditor拡張

ReadMeをつくる

f:id:AkiIro:20180604003939g:plain
見ての通りの選択フォルダにReadMe.txtをつくる.
それだけの拡張です.ええ,それだけです.
自分用gistですが,ご自由にお使いください.

gist.github.com

日本語がInspector上に出ない問題

UnityはBOM付きUTF-8じゃないとInspectorに表示できないので, エンコーディングを固定してやる必要があります.
このあたりの詳しい説明は以下の記事様が参考になります.
blog.nishimu.land

私はこちらのVisualStudioの拡張機能で対応しました.
ForceUTF8 (with BOM) - Visual Studio Marketplace
参考はこちらの記事様

pronama.azurewebsites.net

【C/C++】scanfでループしたので標準入力から数値を受け取ることについてまとめる

scanfでループする

以下のコードは不正な入力(例えばabc)を与えると無限ループします.

/*
    scanfに不正入力をするとループするテスト
*/
#include <stdio.h>
#include <stdlib.h>

int main(void){
    int x = 0;
    while(true){
        printf("Please input x\n");
        scanf("%d", &x);
        printf("x = %d\n", x);
        if(x == -1) break;
    }
    return EXIT_SUCCESS;
}

この原因はscanfが予期しないデータの入力によって,
バッファのデータをそのまま残して動作を終了していることにあります.

scanfは予期しない入力があると無限ループに陥る(C学習中) - 虎塚

標準入出力関数(1)

変換指定文字列で、期待していなかったデータを入力すると、 バッファのデータをそのまま残し、動作を終了してしまいます。

fflush(stdin);
scanf("%*c");

このあたりも試してバッファのクリアを狙ってみましたが,思うような動作には至りませんでした.

fgetsのあとatoiする

// 独自関数fgetiを実装する
// ほぼ問題ないがatoiが範囲外の処理ができない
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define N 512

int fgeti(int*, FILE*);

int main()
{
    int x;
    while(true)
    {
        printf("Please input a number\n");
        if (fgeti(&x, stdin) == EOF)
        {
            continue;
        }
        printf("x = %d\n", x);
    }
}

int fgeti(int* p, FILE *fp)
{
    char buf[N];
    if (fgets(buf, N, fp) == NULL)
    {
        return EOF;
    }
    *p = atoi(buf);
    if(*p == 0 && (strcmp(buf, "0\n")!=0))
    {
        return EOF;
    }
    return 1;
}

こうすることで大抵の処理には耐えますが,範囲(INT_MIN〜INT_MAX)外と
123abcのような頭に数字のついた入力に耐えません.
文字列から数値への変換 - forest book
なお,atoiは変換できない文字列の際に0を返すことにも注意です.
【C言語】atoi関数|ato関数群(atoi, atol, atoll, atof)完全解説 | MaryCore

fgetsのあとstrtolする

atoiよりエラーに強いstrtolを使って
strtoiという関数を定義しました.

strtolは第二引数のendptrに変換出来ない文字列を格納します.
C言語関数辞典 - strtol

// 独自関数fgetiを実装する
// atoiからstrtoi(自作)に変更
// これでどんな入力にも対応できる...はず
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define N 512

int fgeti(int*, FILE*);
int strtoi(const char*);

int main()
{
    int x;
    while(true)
    {
        printf("Please input a number\n");
        if (fgeti(&x, stdin) == EOF)
        {
            continue;
        }
        printf("x = %d\n", x);
    }
}

int fgeti(int* p, FILE *fp)
{
    char buf[N];
    if (fgets(buf, N, fp) == NULL)
    {
        return EOF;
    }
    *p = strtoi(buf);
    if(*p == 0 && (strcmp(buf, "0\n")!=0))
    {
        return EOF;
    }
    return 1;
}

int strtoi(const char* str)
{
    char* endptr;
    long lstr = strtol(str, &endptr, 10);
    if (*endptr != '\0' || lstr < INT_MIN || INT_MAX < lstr)
    {
        return 0;
    }
    return (int)lstr;
}

少なくともscanfで直接受け取るよりは堅牢かと思います.