ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

C# よく使う文字列をコピペするための補助ツール

作りました。こちらからDLできます。

GitHubにも実行ファイルとソリューション一式をアップしています。
ライセンスは MIT License です。

「しばらくの間、同じような文字列を頻繁にコピペする」という時に使ってみてください。
ちなみに自分はバージョン管理ソフトのコメントコピペ集として使うために作りました。

f:id:moko_03_25:20180828025825p:plain

7つの項目xタブで3ページは固定です。

同梱している「Default.ini」にテキストの内容を記憶します。
ツールを終了する際の保存ダイアログに対応しました(2018.9/6)。

Vectorとか探せばもっと良いツールがあるかも知れませんが探していません。。

UserControlは超便利!


プログラムとしては、テキストボックスの内容を何らかのファイルに保存して読み書きする部分以外は「初めてツール作るよ」という人でも作れるくらい簡単だと思います。チュートリアルに向いているかもと思いました。

なにせツールの挙動周りでやってる主なことはこれだけです。

・CopyボタンでTextBoxの文字列をクリップボードにコピー
・ClearボタンでTextBoxの文字列を消去
・TextBox内で Ctrl+A を押すと文字列を全選択する
・ツール起動時にTexBox内にiniファイルから文字列を読み込む
・ツール終了時にTexBox内の文字列をiniファイルに書き込む


ただし大量に同じコントロールを配置していますが、これを私みたいな超初心者だと同じ命令をコントロールの数だけ根性で書いていきがちだと思います。そこを効率良く記述・管理するのに「UserControl」という機能を利用しました。こちら大変便利です!

ユーザーコントロールを作成する (C#プログラミング)

コントロールの集合体をまとめて1つのクラスにして、Form1に配置する際にインスタンスが生成される感じです。つまり下図のような1セットで1つのコントロールのように扱えます。

f:id:moko_03_25:20180905034136j:plain

こちらを利用すれば、Copyボタンの挙動、Clearボタンの挙動、TextBoxの挙動や文字列のiniからの読み込みと書き込みなどを、ひとつ分記述するだけで済むのでとても楽です。

一番最初は、それぞれの挙動を21個分ずらずらっと書いてました。こんな感じで‥。

f:id:moko_03_25:20180905033824j:plain

さすがにこれはひどいなと。。

UserControlのプロパティ


さて、UserControl内にコントロールを色々配置したは良いものの、ではTextBoxの文字列をForm1からアクセスしたい場合はどうしよう?と思いましたが、プロパティが便利でした。

// TextBoxの中身をプロパティでアクセス可能にする
[Browsable(true)]
public string TextBoxText
{
    get
    {
        return this.tbText.Text;
    }
    set
    {
        this.tbText.Text = value;
    }
}


このように記述すれば、Form1のデザイナーにUserControlを配置した際のプロパティウインドウにもちゃんと設定が表示されます。便利!

逆に隠蔽したい場合には Browsable(false) にしておけば良いようですね。

UserControlのクローズ処理


標準ではUserControl自身がクローズした際のイベントが用意されておらず、じゃあUserControl側からForm1のクローズイベントを受け取ろうと思っても、こちらも標準では用意されていないようで、ツール終了時にUserControl自身でiniファイルへ書き込むのに手間取りました。

ググると色んな方法があるようですが、こちらの記事で紹介されているコンストラクタ内でDisposeを使った方法が一番シンプルで良いと思います。

iniファイルのフォーマットは非常にシンプルです。こんな感じ。

[TextBox_00]
Text=A
[TextBox_01]
Text=B
[TextBox_02]
Text=C


[セクション]
キー = 保存する値

‥という感じです。

iniファイルへの書き込み・読み込みですが、セクション名をForm1に配置した各UserControl自身の名前にすることでやり取りをスムーズにしました。名前はTextBox_00~TextBox_20の21個になります。「this.Name」でUserControl自身がForm1に配置された際の名前を取得できます。

しかし、そうするとUserControlのコンストラクタで初期化時にiniから文字列を読み込みたくても、この時点ではまだ生成されてForm1配置時の名前が設定される前なので自身のインスタンスの名前を取得できません。

なのでコンストラクタではなく「userControl_Load」イベントでiniから読み込むようにするとうまくいきました。UserControlのクローズイベントは無いけどロードイベントはあったので助かりました。。

ただしDisposeでの終了時では「this.Name」で名前を取得しようとしてもすでにTextBoxが解放されているためか取得できません。そこで「TextChanged」イベントでTextBoxの内容が変わる度に変数に文字列を保存しておき、変数の内容をiniに書き込むようにすると大丈夫でした。つまり変数の値ならDispose時にちゃんと取得できたという感じです。

iniファイルを扱うクラス


今回、テキストの保存には初めてiniファイルを利用してみました。
ずっと以前から馴染みがある設定ファイルですし一度使ってみたかったんですよね。

ところが.netでは設定の外部保存はXML推奨みたいでiniファイルを扱うライブラリが用意されていないらしく、iniファイルを扱うための古いDLLを読んで、それを扱うためのコードを含めるのがちょいと面倒な感じでした。

iniファイルを扱うコードは検索すると色んな方の事例が出てきますが、こちらの記事の内容がシンプルで分かりやすかったので参考にさせていただきました!感謝です!

クラスを新規作成してこちらの記述をまるっと書くと良い感じです。
今回は文字列しか書き込まないので、読み書きのメソッドはstringのものだけにしています。

ただし二点注意があり、まずusingに下記の一文を追加する必要があります。

using System.Runtime.InteropServices;


また、iniファイルからは一行しか読まないため、改行部分「"\r\n"」を何かしら改行を表す文字列に置き換えてやる必要があります。

これはiniファイルを読み書きするメソッド内で置換を行うとなぜかうまくいかず、userControl内でTextBoxの文字列を扱う部分で置換させたら素直にいけました。

こんな感じです。

// 定数
// iniファイルで改行を表す記号をここで定義
const string rn = "<rn>";

// iniファイルからの読み込み
string s = ini.getValueString(myName, "Text");
// 独自の改行記号を改行に置換
tbText.Text = s.Replace(rn, "\r\n");

// 改行を独自に定義した改行記号に変更
myText = tbText.Text.Replace("\r\n", rn);


iniファイルの良いところは中身の記述がシンプルな点で、ユーザーがテキストエディタで開いた時に項目が一目で分かり編集しやすいところですね!

逆に言えば想定しない編集をされてしまう危険性もあると。。

お次はjsonファイルを試してみたいと思っています。

タブコントロールの利用


タブは標準では背景色を変えるプロパティが無いなど色々不便です。
そしてググっても情報もあまり出てきません。

ツール起動時にiniファイルの文字列を各タブの名前に設定する方法が軽くググっても出てこなかったのですが、「Form1_Load」イベントに下記のように記述するとうまくいきました。

private void Form1_Load(object sender, EventArgs e)
{
    // iniファイルを扱うクラスのインスタンスを生成
    nifileUtils ini = new InifileUtils();

    // iniファイルからタブ名を読み込んで設定
    tabControl1.TabPages[0].Text = ini.getValueString("Tab0", "Text");
    tabControl1.TabPages[1].Text = ini.getValueString("Tab1", "Text");
    tabControl1.TabPages[2].Text = ini.getValueString("Tab2", "Text");
}


タブコントロールにはページをいくつも増やせるため、各ページの情報はコレクションの形で格納されているようです。なので TabPages[0] のようにindexを指定した上で .Text と続けてやればタブのボタン部分の文字列のプロパティにアクセスできました。

以上、色々と詰まったところなどでした。

CEDEC2018 モンスターハンターのエフェクトエディタの講演の感想

早速、ファミ通の記事がきていましたね。早い‥!

ライブ配信では仕事しつつだったのでちらっちらっとしか見れなかったのですが、タイムシフト配信のおかげでじっくり視聴できました。タイムシフト配信は本当にありがたい!

また、非常に盛り沢山な内容で大変参考になりました。。

せっかくなので、視聴して感じたことをががっと書いてみたいと思います。
※写真撮影・SNS投稿どちらもOKとのことなので動画の一部も引用させていただいています

続きを読む

C# ソリューションの基本的なファイル構成について

Visual Studio 2017 を使い始めると、新しいプロジェクトを作成した際にやたら沢山のファイル構成ができて「どれが何のファイルなの?」と混乱します。

Visual Studio 内だと、それらのファイルのデータがツリー構造で表示される「ソリューションエクスプローラー」も同様で、どれを触ればいいのか分かりません。

そこで、構成について自分が分かる範囲でメモっておきたいと思います。

続きを読む

UE4 マテリアルのVectorLength関数

マテリアルの「VectorLength」関数についてメモしておきます。

f:id:moko_03_25:20180628021234j:plain

入力した座標に対して「原点からの距離」を返してくれます。

中身を開いて綺麗に並べるとこのような感じ。
0 との距離 = 原点からの距離を Distance を使って算出しています。
2次元の場合と3次元の場合とどちらにも使えるようになっていますね。

f:id:moko_03_25:20180628021244j:plain

グラフにしてみるとこんな感じですね。
入力した座標が原点からどれくらいの距離(長さ・大きさ)かを出してくれます。

f:id:moko_03_25:20180628021249j:plain

Distanceノードについても記事にしているのでこちらもどうぞ。

UE4 マテリアルのDistanceノード

マテリアルの「Distance」ノードについてメモしておきます。

f:id:moko_03_25:20180628015332j:plain

Distanceは日本語で「距離」ですが、その名前の通り 2つの座標の距離を返す関数のようです。

f:id:moko_03_25:20180628015326j:plain
例えば今の図を Distance を使ったノード構成にすると下図になります。
底辺1・高さ1の直角三角形の斜辺を求めると √2 なので 1.414..の結果になっています。

f:id:moko_03_25:20180628015329j:plain

こちらは分かりやすい例ですが、二点の座標がどこにあったとしても、距離は直角三角形の斜辺になります。つまり2次元でも3次元でも三平方の定理平方根の計算が入るため、四則演算と比べると重ためになる感じでしょうか。。

UQ mobile 機種変更メモ

2年間のandriod端末の使用を経てiPhoneに戻りました。
やっぱりiPhoneは本体とUIともにデザインも触り心地も最高だー!

↓ 初めて UQ mobile を契約した時の記事 ↓
auからUQ mobileに乗り換えてみた <前篇> - ゲームエフェクトデザイナーのブログ (新)
auからUQ mobileに乗り換えてみた <後篇> - ゲームエフェクトデザイナーのブログ (新)

UQに変える前のスマホの請求額が月6000円を超えていたのが、ここ2年は月額1680円のプランで大体2000円ほどになっていたため10万円以上は浮いたのではないかと思います。

ただ、購入したandroid端末がスペックが低くてストレスに耐え続けていた感じだったので、丁度2年というのもあってiPhoneに機種変更しました。

今現在 UQ mobile が取り扱っている iPhone の機種は「SE」か「6s」のみ。
同じスペックだけどSEサイズが好きなのでSE一択。

今回選んだプランは「ぴったりプランM」。

「増量オプション」は2年間無料で毎月3GBまでチャージ可能というもの。
最近契約した人はチャージすると有効期限が2ヶ月延長され、余った分は翌月に繰り越されるため余れば10GB・20GBとどんどん貯めていけるようになっている模様。
また、プランの S / M / L は月単位で自由に切り替えられるため、合計データが十分貯まったらSプランに変更して残り一年を安く済ませる‥みたいなことが可能だそうな。

注意がひとつあって、うちの奥さまもぴったりプランなので家族割が申し込めるのですが、今回変更したぴったりプランが適用されるのが翌月から&ぴったりプランになってからじゃないと家族割は申し込めないのだそうです。

ということは家族割が適用されるのは翌々月になる?としたらなんだかなあという感じです。

ケースは「IIIIfi+」の赤を購入。水色と白も良かったので迷いました。

せっかくコンパクトなiPhoneSEに対して側面のゴム部分?が分厚い感じでゴテっとしないか心配でしたが、装着してみたら思っていたよりもずっと良い感じでとても満足。

f:id:moko_03_25:20180626013529j:plain

f:id:moko_03_25:20180626013527j:plain

指紋認証も優秀だし、触っていて心躍るこの感じは久々な気がする‥!

今使っているノートPC「Lesance NB G7541」のスペックメモ

2~3年くらい前でしょうか、それとも4~5年前でしょうか、もういつ買ったか記憶が無いのですが、勉強会用に購入したUE4Substance・Houdiniといったアプリケーションが動くスペックのノートPC「Lesance NB G7541」は長い間活躍してくれましたが、最近動作がすごく重くてしんどい印象があり、でかくて重いことからも買い替えを検討中。

初期化してやったら軽快になったりするのかな。。

 主なスペックと印象を書いておきたいと思います。

●液晶サイズ:15.6 インチ

 でかいです。
 画面は見やすいですが大きめのカバンが必要。
 電車で座って膝の上に置くと隣の人の邪魔になる感じで持ち運びには不便。
 でかい分、キーボードにテンキーがついてます。

 次買うなら14インチあたりが良いなあと。。

●アダプター:でかい
 本体に加えてアダプターがこれまた巨大です。
 店頭で見逃しやすい落とし穴ではないかなと。
 当然ながらアダプターはできるだけコンパクトなものが良いですね‥

●重量:3.1 kg
 体感としてはかなり重いです。
 「落としたらこれ絶対壊れるやつだ!」って感じがします。
 次買うなら 2kg 切って欲しいところ。

●解像度:フルHD (1920x1080)
 UE4などウイドウを多く並べたいツールではフルHDはありがたいです。

●CPU:Core i7 3610QM(Ivy Bridge) 2.3GHz/4コア
 10万ちょいくらいのノート見てると結構良い方な感じも。。
 正直CPUの性能ってよく分かりません。
 例えばHoudini使用時、2.3GHzで4コアと3GHzで2コアを比較するとどうなんでしょう‥
 どれくらい重たい作業を並列で処理するかとは思うのですが‥

GPUGeForce GTX 670M
 CPU同様そこそこ良い方?
 ディスプレイ解像度も大切ですが、出力解像度も大切で。。
 低スペックのノートでデスクトップを複製出力すると小さく表示されて困る場合も。

●メモリ:8GB
 スロット4で空きスロット2なので増設可能。

●HDD:698GB
 十分すぎる感じです。
 基本的にプライベートではデスクトップマシンで作業するので。。

●出力:HDMI端子・DVI端子・ディスプレイポート
 でかいだけあって色々揃ってますがHDMIしか使ってません。
 勉強会用なのでHDMIで出力できるのは必須な感じで。

●DVDドライブ:あり
 全く使用していません。。必要無かったな~と。

こちら納品書とか残ってなくておいくらだったか分からないのですが‥
確かお値段が安かった気がするんですよね。

Officeが入ってないのもあって、7~9万円あたりだったような。。

性能とお値段でのコスパは良いのかなと。
代わりにでかくて重くてバッテリーは持たないのですが。。

ちなみに今お目当てのノートPCはこちら。

Amazonで12万5000円。

PS4で使えるワイヤレスキーボード SKB-WL23BK

メモっておきます。

以前、PS4で使うために何か良いキーボードないかなーと思ってヨドバシカメラで購入したのがサンワサプライの「SKB-WL23BK」です。

コンパクトサイズなこと、キーを打った感触が好みだったことからこちらにしました。

こちら、PS4で使える一覧に無かったので不安ながらも購入したのですが、ちゃんと使えています。

UE4 円柱状に投影するCylindricalUVsについて

マテリアルでテクスチャを円柱状に投影マッピングしたい場合、マテリアル関数「CylindricalUVs」を使ったりするかと思います。今回はこちらの中身について。

f:id:moko_03_25:20180618103629j:plain

続きを読む