2014年6月14日土曜日

[Unreal Engine 4] TextRenderComponentで徐々に文字を表示するBlueprint

まず,UE4のTextRenderComponentで日本語を表示するまで,の手順でTextRenderComponentで日本語表示ができる状態になっているとします.

コンテンツブラウザで,Blueprintを追加します.


クラスはアクタを選択します.


追加したBlueprintには,BP_ScriptRenderという名前をつけました.



追加したBlueprintをダブルクリックし,コンポーネントの追加からTextRenderを選びます.


TextRenderの名前をTargetにし,フォントの設定で作成した日本語用のフォントとマテリアルを使うように変更します.日本語が出ることを確認するため,Textを日本語のメッセージに変えておきましょう.


保存してから,通常の画面に戻り,Blueprintをドラッグアンドドロップし,配置しましょう.
裏面からは見えなかったりするので,画面に映る状態に調整しましょう.


調整が終わったら,Blueprintに戻り,イベントグラフの編集に移ります.
まずは,float型の変数を追加し,Counterという名前にします.


Begin Playイベントを追加し,ゲーム起動時に色々初期化するようにします.
まず,マイブループリントからTargetを選び,ドラッグアンドドロップでイベントグラフに配置します.


ピンから線を引っ張って話すと,コンポーネントの追加ができるので,Set Textを入力して検索し,追加しましょう.


デフォルトでは空文字列を設定するようになっているので,Begin PlayイベントをSet TextにつないでやればOKです.同時に,Counterにも0をセットするように追加しておきましょう.次の図のようになります.


次に,Tickイベントを使って,Counterを更新するようにします.TickイベントからDelta secondsを取得し,Counterの値に追加し,それをCounterにセットする,という流れです.


次に,表示する文字列を入れておくための変数を追加します.変数の種類はTextにします.


Get Substringというコンポーネントを使うと,文字列の一部を取り出すことができるので,これを使ってテキストの開始からCounter番目の文字までを取り出します.Source StringにScriptをつなぎます.(Textからstringに変換するコンポーネントが自動的に追加されます).更に,Length(取り出す文字列の長さ)にCounterをつなぎます.(floatからintegerに変換するコンポーネントが自動的に追加されます).Start indexは,文字列をどこから取り出すか(0が最初の文字),なので0にしておきます.できたものが次の図のようになります.


最後に,Counterの更新からTickイベントを受け取って,TargetのSet Textコンポーネントに取り出した文字列を設定するようにします.


これで,再生すると1秒に1文字ずつ表示されます.

2014年6月10日火曜日

UE4のTextRenderComponentで日本語を表示するまで

どうにかTextRenderComponentで日本語が表示できたので,メモ.

まず,日本語を含むフォントテクスチャを作る.これについては,こちらを参照.
次に,フォント表示用のマテリアルを作成する.コンテンツブラウザの新規からマテリアルを選択する.


マテリアルには,とりあえずMSGothicMaterialと名前をつけた.このマテリアルをダブルクリックし,マテリアルエディタを開く.


最初からある最終結果を表すノードを選び,左下のプロパティからBlend modeの設定をMaskedに変更する.


次に,右クリックメニューからFont Samplerを追加する.


Font Samplerの一番下の丸(アルファ成分?)をオパシティマスクにつなぎ,マテリアルを保存する.


最後に,適当なところにTextRenderComponentのアクタを配置したら,右側のプロパティから表示したい文章をTextに設定し,マテリアルとフォントに作成したフォントとマテリアルを設定すれば,日本語が表示される.

ただ,日本語のように漢字も含めると文字数が多い場合、テクスチャが複数枚になるのだけれど、まだそこの扱い方が分かっていない.
さっさと日本語出せるようにして,アドベンチャーゲームのように1文字ずつ表示されるような機能作ってみたい.

2014年6月7日土曜日

Unreal Engine 4で日本語フォントを作る方法

まず,コンテンツブラウザで「新規」,「マテリアル & テクスチャ」、「Font」の順に選び,
フォントを追加します.

日本語で使えるフォントを選びます.ここでは,とりあえずMSゴシックを選んでみました.

コンテンツブラウザにできた新しいフォントをダブルクリックし,フォントエディタ(正式名称が見つけられませんでした.)を開きます.

右側にあるプロパティから,「Import Options」の中の「Unicode Range」に「3040-309F,30A0-30FF,4E00-9FFF」を入力します.
それぞれ,平仮名、片仮名,漢字に対応しています.そして,アセットメニューから「再インポート」を選びます.

これで,日本語を含むフォントができます.

ただ,日本語フォントを作っても,TextRenderComponentには日本語表示が崩れるというバグがあるようです.
(AnswerHubへ)

プレビューではちゃんと日本語が表示できるので,TextRenderComponent以外に何かしらフォントを表示する方法では表示できるかも?

その後の経緯が見つけられないのと,4.2でも表示がおかしくなることから,まだ直っていないのかも.

TypeScriptのリファレンス指定ではまる

川俣さんのTypeScript入門(Amazon)を買って,
TypeScriptを使ってみた.

まず,jQueryを使うための型定義を取得する部分で躓く.Visual StudioのNuGetを使えばよいらしいが,
nodeとCLIで実行している場合の方法が分からなかった.調べてみると,tsdというツールを使うのが楽そう.

npm install -g tsd

で,TypeScriptのコードを書いている場所でtsdを使ってjQueryの型定義ファイルをインストールする.

tsd query jquery -a install

すると,typingsというフォルダができて,その中のjqueryというフォルダの中にjquery.d.tsというファイルができる.

これを,TypeScriptのファイルで参照するように設定するのだが,最初に書き方を間違えた.

// 間違い
// 

コメントと勘違いしてしまったが,"/"は3つでなくてはいけないらしい.
気になって4つの場合も試してみたが,きっちり3つでなくてはいけない.

// まだ間違い
/// 

これで通ると思いきや,まだ駄目らしい.まさかと思いpathの前後の空白を削ってみると,うまく通った.
つまり,次が正解になる.

// 正解
/// 

代入演算子の前後には空白をつける癖が問題になるとは思いませんでした.

まとめ

TypeScriptで型定義を参照する場合
  • 行頭の"/" はきっちり3つ
  • pathの直後の=の前後に空白を入れてはいけない

2014年5月28日水曜日

不快もとい深いネストを浅くするためのパターン

仕事中に見かけて,こうすればネストが浅くできてすっきりするのに,と思ったパターンをメモ.

elseの無いif

次のように関数の中身全てがelseの無いifで囲われている場合がある.
void hoge(parameters)
{
    if(condition){
        // やたらと長くてswitchやらifやら混在した処理
    }
}
これは,将来的にelseが追加される可能性があるけれども,現状はこうした方がすっきりする.
void hoge(parameters)
{
    if(!condition){
        return ;
    }
    // やたらと長くてswitchやらifやら混在した処理
}
もちろん,やたらと長い部分も関数に切り分けるなり何なりするべきだけど,とりあえず,条件が満たされなければそれ以降の処理が実行されないのだから,その時点で関数を切り上げれば良い.だいたいこういう書き方をする場合って,ポインタがnullptrの場合に落ちないようにするための安全策だったり,と念のための対処だったりするので,elseが後から追加される可能性も低い気がする.

ifとelseで重複するswitch

void hoge(parameters)
{
    if(condition){
        switch(parameter1){
        case A:
            break;
        case B:
            // 以下延々と続く
        }
    }else{
        switch(parameter1){
        case A:
            break;
        case B:
            break;
            // 以下延々と続く
        }
    }
}
この場合、処理の内容にもよるけれど、少なくとも次のようにifとswitchの関係を入れ替えた方が楽な気がする.
void hoge(parameters)
{
    switch(parameter1){
    case A:
        if(condition){
        }else{
        }
        break;
    case B:
        if(condition){
        }else{
        }
        break;
        // 以下延々と続く
    }
}
これだと、switch文へのcaseの追加は1度で済む.最初の形だと、両方に追加する必要があるから、caseが増えるにつれ、追加忘れが発生する可能性が高くなる.そもそも、そんな長い関数を作るな、と言われそうだけど.あとは、各caseの内容を関数に切り分けるのも良い.
処理の内容次第では、テーブルにデータを入れておいて、caseで必要なテーブルにアクセスする、という形にすれば更にすっきりする.
void hoge(parameters)
{
    // データを引っ張ってくるためのテーブル
    unsigned table[CASE_NUM] = { ... };

    // 実引数が想定外の場合の対応
    if(parameter1 >= CASE_NUM)
        return ;

    unsigned value = table[parameter1];
}
他にも何かあった気がするので、思い出したらメモしていこう.そのうち後輩とかに教えるのに役立つかも.

2014年4月14日月曜日

角度を扱うクラス (未完成)

角度を扱うクラスって見ないなぁ,と思って作ってみた.angle(度数法)とradian(弧度法)を表すクラスで,それぞれに代入する場合は意図的に書かないとできないようにした.角度を受け取る関数なんかで仮引数の型としてこのクラスを使うことで,度数法で渡して欲しいのか,弧度法で渡して欲しいのかがはっきりするな,と思ったり.



一度作ってから,実装がほぼ同じなのでCRTPでまとめてみたものの,二項演算子の実装があんまりすっきりしなくて,いったん放置.

しかし,何故こういう安全策が用意されないのかなぁ,と考えていて,そもそもこういう角度を扱うような状況って処理速度が云々って言っていることが多いし,const参照で渡したら間接参照になるから多少は速度が落ちるかも,とか考えているのではないかと.

2014年4月1日火曜日

ゲームプログラマとしての三年目のまとめ

ゲームプログラマ,そして社会人としての三年目も終わったのでまとめ.

今年度の仕事

試作から関わっていたプロジェクトが何とか発売を迎え,一段落.今年度の後半は次のプロジェクトへ.こちらも試作前から関わっているので,数年は関わることになりそう.

今のところ会社のライブラリを利用して何とかやっていけているけれど,そのうち一人で一通りのシステムを組んでみたいものです.

今年は,新人の面倒とかも見てました.C#やJavaがメインだった子が増えてきているのか,微妙にC++の作法が分かってなかったり.まだしばらくC++がメインなので,色々教えることも考えないといけないかもなぁ,とか思いました.

もうちょっとプログラミングについて語れる子がいれば良かったけれど,出来そうな子ほど一年目から忙しくなったりするのがちょっと悲しかったり.

目立つの大事

良くも悪くも目立つというのは大事だなぁ,って思いました.もちろん,悪い方向で目立つと悪い結果になるんですけどね.良い方向に目立ってると,例えば給料の値上げをしてもらう場合も話を通しやすかったり.

じゃあ,目立つにはどうすれば良いか,というと,やっぱり声を上げ続けることかなぁ,と.新人だったりするとつい遠慮してしまうかもしれませんが,特にプログラマの場合,経験年数と実力が比例するわけではないので,先輩の言うことだから,とか気にせず,自分がこうだと思うことを言ってしまえば良いかなって.

最後に

正直なところ,3年目は結構穏やかに終わったなぁ,という感じ.強いて挙げるとすれば,やはり今のままのやり方じゃまずいよなぁ,という実感が強まった.もうちょっとプログラマの教育だとかドキュメント作成だとかをしっかりやっていく方向にしないと,色々と厳しい気がする.

他の会社ではどうやっているのかなぁ,といったことを知るためにも,今年度は勉強会などにももっと参加して,色々な人と知り合いたいなぁ,と思う.