お茶漬けびより

"あなたに教わったことを、噛んでいるのですよ" 五等分の花嫁 7巻 「最後の試験が五月の場合」より

Amazon Prime Music の曲紹介

はじめに

Amazon Prime Music で聴ける曲で、気に入った曲を紹介していく記事。
別々の記事にすると面倒そうなので、計画としてはこの記事に追記していく形。 いつまでも聴けるとは限らないので、その点ご注意。 あと主にOSTです。自分、歌(日本語)は疲れるのであまり聴きません。

OST:オリジナルサウンドトラック

#1.GRAVITY DAZE/重力的眩暈:上層への帰還において、彼女の内宇宙に生じた摂動 OST

タイトル長い。これは、ずっと前から聴ける曲なので、今後も聴ける気がする。
SCE(現SIE)のゲーム。ゲームは癖があるけど、このOSTは本当に最高。Prime Music にはまったきっかけ。万有引力の発見GRAVITY DAZE/重力的眩暈は必聴。
あ、自分はこのゲーム好きです。2 はまだ終わってないけど(2017/03/04 現在)。 Prime で聴けるけどサントラ欲しい。

#2.仮面の勇者~心の迷宮RPGOST

また良曲を見つけてしまった。これだから Prime Music は止められない。
ゲーム自体はやったことないのだけど、Android アプリのゲームらしい。
聴いたらピンと来るかもしれないけど、作曲者は、景山将太(かげやま しょうた)さん。主にポケモンを作曲している人らしい。というのも自分は、スマブラの印象が強かった。
一部しか聴けないし、短いからループが鬱陶しいかもしれないけど、一度は聴いてみて。

仮面の勇者?心の迷宮RPG? オリジナルサウンドトラック

仮面の勇者?心の迷宮RPG? オリジナルサウンドトラック

C++ のエラー処理

本に書いてあったエラー処理の話がためになりそうだったので、ここにまとめておこうかと思います。

参考にした本は、以下の2冊です。

C++のためのAPIデザイン

C++のためのAPIデザイン

 

4.7.4 「エラーの処理方法」を参考にしました。

ゲームエンジン・アーキテクチャ 第2版

ゲームエンジン・アーキテクチャ 第2版

 

 ゲームエンジンアーキテクチャは、3.3 「エラーの補足と処理」を参考にしました。

また、自分が持っている本は第1版です。 

 

では、まとめていきます。

 

まず、C++のためのAPIデザインの内容です。

エラーが発生した場合に対処する方法は、主に3つです。

  • エラーコードを返す
  • 例外を投げる
  • プログラムを停止する

では、一つずつ見ていきます。

エラーコードを返す

これは、エラー内容を値に置き換えることで対処する方法です。単純でありながら非常に便利です。今回はC++なのでエラーの対処法の一つになりますが、純粋なCの場合だと唯一の方法になります。

また、関数自体が何か値を返したいときにどちらか片方しか返せません。この場合は、エラーコードを返し、引数に値を入れることで対処します。

boost::tuple を使うと複数の結果を返すことが出来るようです。

例外を投げる

これはC++の例外処理を使います。関数が投げてきたオブジェクトを受け取り、対処します。例外を使うとエラー処理と通常の処理を別に切り分けることが出来るので、コードが読みやすくなります。また、シンプルなエラーコードよりも多くの情報を持たせることができます。さらに、大抵のデバッガは例外が発生するとそこで処理が止まってくれる(ブレーク)ので、デバッグが行いやすくなります。しかし、想定外の例外が発生するとプログラムが停止する恐れがあります。また通常は一部でも例外を使用する場合、そのアプリ全体で例外処理を正しく行うようにする必要があります。

エラーが発生した場合は、すぐに関数の処理を停止し、直前に割り当てられていたリソースを解放することが最善です。ただし、NULLなどの例外の値は返さないようにしましょう。関数を呼び出した側がさらにその例外の値をチェックする必要があるからです。この場合は、空のリストを返すようにするといいかもしれません。

エラー時に情報はなるべく多く、エラーの原因を早く突き止められるような情報を載せましょう。

 

次にゲームエンジンアーキテクチャの内容です。

エラーには、大きく分けて二つあります。ユーザエラーとプログラマエラーです。

ユーザエラーは、ソフトウェアを使うユーザが引き起こすエラーで、プログラマエラーはコード自体のバグです。ただし、ユーザにはさらに2種類に分けることができます。

一つは、ゲームをプレイしているユーザで、もう一つは、ゲームを制作しているユーザが引き起こすエラーです。

まとめると

ユーザエラー
  • プレイヤーエラー(ソフトウェア使用者)
  • 開発者エラー

プログラマエラー

大きく分けて2つ。細かく分けて3つのエラーの種類があります。

このユーザエラーとプログラマエラー、2つのタイプによってエラーの対処法は変わります。

ユーザエラーの場合、ゲームをプレイしていたりゲーム制作の作業をしているのでゲームや作業を止めるようなことはあってはいけません。処理を継続しながらも、ユーザの役に立つ情報を提供することが大事です。

逆にプログラマエラーの場合は、処理を止める必要があります。そして、デバッグを行うために必要な情報を提供します。

では、さらに細かく見ていきます。

プレイヤーエラー

ゲームをプレイしているときのエラーです。当然ゲームが止まるようなことはあってはいけません。そのような重度なエラーでなくとも、例えば、アイテムが0のときにアイテムを使用すると、そのアイテムは使用されずにプレイヤーに今は使うことが出来ないということを知らせる。これもプレイヤーエラーになるでしょう。

開発者エラー

これは、アーティストやアニメーターなどに起こるエラーです。例えばアセット(や画像)のようなデータを読みこませるときに、そのアセット自身が原因で起こるエラーです。このような問題のあるデータをエラーに気づかずまたは無視されていると、そのデータが入ったまま製品として出されることになります。かといって、問題があるから停止をさせると開発者の手が止まり、作業が進まなくなってしまいます。

なのでこの場合は、エラーであることを開発者に分かりやすく伝えながらも処理を継続させます。

プログラマーエラー

プログラマーエラーの場合は、本来あってはならないのですぐに処理を止めます。こうすることで、プログラマーは嫌でもバグを取り除くことになります。

 

では、エラーの検出、実装方法は何があるのでしょうか。

これはC++のためのAPIデザインにもあったエラーコードと例外。そして、アサートです。アサートは、式をチェックする命令行のことで、これを正しく使用することでプログラマはこれに引っかかると、引っかかった原因を取り除く必要があります。なので、上記の3つのエラーの中では、プログラマーエラーに使われるでしょう。またアサートは通常マクロで定義されるので、製品として出すときは取り除くことが出来ます。

以上、雑なまとめになりますが終わります。

今回のことで分かったのは、エラーの種類には複数あり、その種類によって対処の仕方は全然変わってくるということです。プログラマーのエラーには主にアサートを使い、開発者エラーの場合は、例外処理で処理を継続しつつエラーの情報を提供し、プレイヤーエラーのときは、エラーコードを使用して対処するという感じでしょうか。

そうすると統一性がなくぐちゃぐちゃになりそうですが……。アサートの使い道は分かりやすいですが、エラーコードと例外をどう使い分ければいいかがまだ分かりませんので、エラー処理の対処は、とにかく試行錯誤していくしかなさそうです……。

 

 

UE4 の Blueprint インタフェースについて

Blueprint(以下BP)のインタフェース(インターフェース)について調べました。

概要

BP のインタフェースは、見た目はBPクラスですが中身は少し違います。インタフェースには出来ることと、出来ないことがあります。
出来ること
  • 関数の作成
  • 関数の入出力の追加
  • 純粋(const)化*1
出来ないこと

詳細

インタフェースでは、関数の外枠だけを作り、中身は作りません。その中身は、インタフェースを実装したBPクラスに任せてしまいます。外枠を決めることで、このインタフェースを実装したBPクラスたちは、共通の関数を持つことが出来ます。つまり、同じインタフェースを実装したクラスたちの共通の関数を呼び出すだけで、それぞれ異なる動作を行わせることが出来ます。
インタフェースでは関数の外枠を作るわけですが、その外枠とは、具体的には関数の名前や入力、出力する値、純粋化するかどうかを決めます。逆にこれらは、インタフェースを実装したBPクラス側では編集できません。外枠を変えることが出来ると共通の関数を持つことにならないからです。
説明としては以上です。インタフェース自体は効率化を進めるための機能だと思うので、知らなくてもゲームは作れます。なので、あまりUE4に慣れていない間はあまり気にする必要はないでしょう。
 
作成した関数は、BPクラス側のインターフェースに表示される関数と表示されない関数があります。この違いは何でしょうか?
いろいろ試して分かったことは、BPクラスのインターフェースに表示される関数は、
  • 出力される値(アウトプット)がある
  • 純粋関数である(Const にチェックをしている)
この二つの内一つでも当てはまるものは、BPクラス側のインターフェースとして表示されます。
表示されない関数たちはどこにいったかというと、イベントグラフ上でノード検索を行い(右クリック)、関数の名前を入力すると「イベント○○(関数名)」と表示されます。これをクリックすることでインタフェースの関数をイベントとして追加できます。あとはBPクラス側で実装をすることで関数の中身を作ることができます。

作成、実装

実際の作成や実装の手順は、公式が書いてくれているのでそちらに任せます。
 
 
 

アクターを移動させる Blueprint

移動系のBleuprint(BP)を調べたのでまとめます。
といっても基本的な内容なので、大したものではないのですが。
 
アクターを移動させるためのBPはいろいろあると思います。
今回は、以下を調べました。
  • SetActorLocation
  • SetActorRelativeLocation
  • AddActorWorldOffset
  • AddActorLocalOffset
ここでは、SetActorLocation と SetActorRelativeLocation のことをまとめて、Location 系と呼び、AddActorWorldOffset と AddActorLocalOffset のことをまとめて、Offset 系と呼ぶことにします。 

Location 系

・SetActorLocation 

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
New Location(Vector
世界座標の位置を指定。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)

指定した位置に瞬間移動するようになる

 
Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structureとして返す
Return Value
移動に成功したとき True を返す。Sweep が無効のときは必ず True になる(はず)

詳細
New Location で指定した世界座標(ワールド座標、絶対座標)の位置に物体を動かします。Sweep を有効にすると現在位置から New Location の直線状に物体があるとその物体の手前で止まります。
Sweep についてはいくつか注意する点があります。
  • Sweep の機能は、ターゲットとぶつかる対象の両方が、Collison のオブジェクト応答でブロックしているとき機能する。
  • ターゲットは、ルートコンポーネントコリジョンの設定(オブジェクト応答)をしないと機能しない。
  • 注意ではないが、「オーバーラップイベントを発行させる」は有効にしなくてよい。
2つ目のルートコンポーネントコリジョンの設定をする話は、Sweep の仕様というよりもコリジョンの問題っぽい?*1
Teleport は、ルートコンポーネントについている別のコンポーネント側に移動速度を反映させないようにするようです*2

・SetActorRelativeLocation

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
New Relative Location(Vector
アウトライナ上で親子関係のある、親を中心(0, 0, 0)とした座標位置を指定。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
 
Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structure として返す
詳細
機能としてはほとんど同じですが、移動するときの基準となる座標が違います。
SetActorLocation のときは世界座標でしたが、SetActorRelativeLocation の場合は、親の位置を中心(0, 0, 0)とした相対座標(ローカル座標)になります。ここでいう親というのは、アウトライナ上の親子関係のことです。親子関係は、アクタを別のアクタにドラッグすること(アタッチ)で作れます。この場合、ドラッグ側のアクタがドラッグ先のアクタの子になります*3

Offset 系 

・AddActorWorldOffset

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
Delta Location(Vector
ターゲットの現在位置から Delta Location だけ世界座標を軸に移動する。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)
指定した位置に瞬間移動するようになる。

Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structure として返す


・AddActorLocalOffset

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
Delta Location(Vector
ターゲットの現在位置から Delta Location だけ相対座標を軸に移動する。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)
指定した位置に瞬間移動するようになる。

Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかるとHit Result Structure として返す
詳細
二つをまとめて紹介したほうが、分かりやすいと思ったので同時に説明します。
まずこの二つの名前には Offset というのが付いていますが、Offset とは何でしょうか?
上記の内容が分かりやすかったので、載せておきます。これによると Offset は基準の位置からのズレということです。つまり Offset 系は、ターゲットの位置を基準とした位置から Delta Location の分だけズラすということでしょう。ということは、これを使えばわざわざ Location 系を使うときに、(現在位置+移動量)の値を New Location にする必要はなさそうです。 
では、 Local と World の違いは何でしょうか。これは憶測ですが基準となる軸のことを指していると思っています。つまり、Local の場合はローカル座標(相対座標)を軸とした移動で、World は世界座標を軸とした移動になるということです。
例えば、以下の図のようなローカル座標があるとします。

f:id:pickles-ochazuke:20170104032751j:plain

このローカル座標は、ターゲット自身の座標です。この状態で AddActorLocalOffset の Delta Location に(0, 10, 0)の Vector を設定すると、Y軸方向に 10 進みます。これは下図のように前方に進んでいるように見えます。

f:id:pickles-ochazuke:20170104032849j:plain

では、この Local 座標の Z 軸を 90 度回転します。すると下図のようになりました。

f:id:pickles-ochazuke:20170104032917j:plain

この状態で先ほどと同じように移動させてみましょう。Y 軸方向に 10 進みます。これは、下図のようになります。

f:id:pickles-ochazuke:20170104032938j:plain

つまり、 AddActorLocalOffset はターゲットが回転すると、その影響を受けて移動をするということです。
逆に AddActorWorldOffset はターゲットが回転をしても影響ありません。ローカル座標ではなく世界座標を軸に移動しているからです。もちろん世界座標が回転をすれば、AddActorWorldOffset は影響を受けます。この場合 AddActorLocalOffset は影響を受けないはずです(憶測です……)。
また、ターゲットが親子関係を持っている場合、AddActorLocalOffset はターゲット自身の軸と親の軸、両方の軸を見ている(合わせている?)ようです。ややこしいのですが、例えば親が Z 軸右に 90 度回転していて、ターゲット自身も Z 軸右に 90 度回転している場合、二つの回転を合わせた Z 軸 180 度回転した軸を基準に移動するようになります。
 
以上、Offset 系の説明でした。長々と説明しましたが、説明を読むよりも実際にBPを組んでみたほうが実感が湧くと思います。自分もこの記事を書きながら実行をするなかでいくつか疑問点が出て、実際に試して疑問を解消したので手で動かすことをオススメします(ただ手を動かすのではなく、考えて動かすこと)。
 
最後に、とても参考になった記事
以上です。初めての BP の記事を書いたので間違っているところがあるかもしれません。もし間違いに気付いた方がいらっしゃれば、コメントで指摘していただけると嬉しいです。

プログラミングするときに使うショートカットキー集

個人的によく使うショートカットキーをまとめてみました。
随時更新
 
環境は、ノートパソコンの一画面を想定
以下のショートカットキーを載せています。
Widnows10
ノートで開発するとき画面が一画面かつ小さいので作業がしづらいです。
なので、Windows10から追加された仮想デスクトップを使っています。
 
仮想デスクトップ間の移動
Windowsキー + Ctrl + (← or →)
アプリケーションの切り替え
Alt + Tab
 
 
 
 
 
 
 
 
 
Visual Studio 2017 RC
Visual Stduio のショートカットキーは、最近調べ始めたのでところどころマウス使っています。
&& は、「その後に続けて」という意味で使っています
 
タブ切り替え
Ctrl + Tab
Ctrl + K && Ctrl + C
Ctrl + K && Ctrl + U
矩形選択
Shift + Alt
文字検索
Ctrl + F
文字置換
Ctrl + H
入力補間
Ctrl + Space
ビルド
Ctrl + Shift + B
デバッグなしで開始
Ctrl + F5
デバッグの開始
F5
 
 
 
Google Search
あまりショートカット気にしなかったのですが、使ってみると便利でした。
 
 検索バーに移動
/(全角でも可。ただし検索バーに「・」が表示される)
検索結果に移動
Tab
検索結果の移動
(↑キー, ↓キー) or ( j, k )
 
 
 
Microsoft Edge
最近使い始めました。とくに不満なく使えています。
 
タブを開く
Ctrl + T
タブを閉じる
Ctrl + W
戻る
Ctrl + ← or Backspace
進む
Ctrl + →
アドレスバーに移動
Ctrl + L