Enjoy Engineer Life

C#,Unity,C++,UE4などの技術ブログや雑記を徒然なるままに書いていきます。

【企画】ゲームのテーマとストーリーを考えてみるお話

最初に

本記事は以下の書籍を参考に知見と感想を自分なりにまとめたものとなります。



引き続き、ゲームの企画について考えてみます。今回はゲームのテーマとストーリーのお話。相変わらず僕は、

「テーマ?ストーリー?何を書けばいいんだ?何もわからん」

という状態なわけです。なのでテーマから順番に考えてみることにします。

テーマを定める

テーマは以下の2つのタイプに分類できます。

  • 「最強」「純愛」「家族愛」などの、ゲームに一定のイメージや方向性を導き出すための一言タイプ
  • 「この世の命が、蘇る(大神)」、「どうあがいても絶望(SIREN)」のような、キャッチフレーズタイプ

キャッチフレーズタイプには更に、上記に挙げたものの他にも疑問形で投げかけるような言い回しもあります。

このような形にするとキャッチコピーを見た人は、「どんな答えが待っているのだろう」と、ついつい思案してしまいます。
キャッチフレーズは以下のまとめサイトが参考になるかもしれません。

秀逸・有名なゲームのキャッチコピーまとめ一覧【300件】 - ラノベ見聞録

ストーリーでテーマを伝える

テーマを決めたら、次はそのテーマをプレイヤーに「物語る」ための「ストーリー」が必要となります。
まずは、ゲームの目的とテーマをリンクさせて見ましょう。

まずはゲームの目的とテーマをリンクさせる

先ほどのキャッチコピー例で言うと、大神なら「この世の命が、蘇る」と言うキャッチコピーと「怪物ヤマタノオロチを倒し、ナカツクニと言う国の安寧を取り戻す」と言う目的をリンクさせて「このゲームは、とある国の真の平和を取り戻すために怪物ヤマタノオロチを倒す旅にでて、その旅の中で手に入れた力を使い、各地のタタリ場を浄化し、植物を蘇らせるゲーム」となります。ここで大事なのはテーマが目的の意味を補強しているところとなります。

このように、ゲームの目的とテーマをリンクさせることによってストーリーが思いつきやすくなります。もしも、ストーリーが思いつかないのであれば、テーマの方をもっと膨らませてみる必要があります。

次にテーマからストーリーを導き出す

テーマから連鎖的に発想を広げてストーリーを引き出していきましょう。

引き続き、「大神」の例だと、「この世の命が、蘇る」から、「何故命が失われていたのか」「どのようにして蘇らせるのか」「何故命を蘇らせようとするのか」を考えることができます。ここで詰まってしまった時には資料を漁ってみましょう。

  • ネタやアイディアのストック(ネタ帳とか)を見返す
  • 本やゲーム、映画や新聞などを見る(自分が目標としている雰囲気にあったゲームの参考資料とかも良き)
  • すでに設定済みの「キャラクター」や「世界観」を見返す


テーマはシナリオ内のセリフでは書かない

これはそのままの意味で、キャラクターたちがテーマをそのままセリフとして喋ると、プレイヤーはしらけてしまいます。テーマは口にして言うのではなく、ゲームを進めるうちにプレイヤーが自然と感じとってくれるものでないといけないのです。では、テーマはどのように書いていくべきでしょうか。

手法は二つとなります。

  • キャラクターの選択、行動によって表現する
  • ストーリーの展開によって表現する

後者はわかりやすいですが、前者の「キャラクターの選択、行動で表現する」場合は、テーマに絡めた選択肢を用意してプレイヤーにテーマを感じさせつつ考えさえることができます。

最後に

とりあえずポイントだけを書き出してみました。これに沿って僕が企画してるゲーム制作の方も進めていこうと思います。

【読書メモ】Deep Learningを学ぶ〜データの可視化に便利なMatplotlibの使い方〜Part 5

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねてまとめた記事となります。ただし本の内容をそのまま書き写ししているわけではなく、ある程度自身で調べたものや感想が混じっています。ご了承ください。

f:id:rossamu:20190103000547p:plain ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

今回はグラフの描画やデータの可視化が簡単に行えるMatplotlibという外部ライブラリの紹介と使い方になります。

Matplotlibのインポート

Pythonでは外部ライブラリをインポートする際に import と打ち込む必要があります。今回はMatplotlibのpyplotというモジュールをpltという名前でインポートするコマンドを打ち込みます。ちなみにPythonのモジュールとは、「関数」や「クラス」を集めた拡張子「.py」のファイルを指します。クラスのようにインスタンスを作る必要がないので、モジュール内の関数をどこからでも呼び出して使用することができます。

import matplotlib.pyplot as plt


グラフの描画を行ってみる

インポートができたら早速グラフの描画機能を試してみましょう。

>>> x = np.arange(0, 7, 0.1) # 0から7まで0.1刻みで数値を生成する
>>> print(x)
[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.  1.1 1.2 1.3 1.4 1.5 1.6 1.7
 1.8 1.9 2.  2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.  3.1 3.2 3.3 3.4 3.5
 3.6 3.7 3.8 3.9 4.  4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.  5.1 5.2 5.3
 5.4 5.5 5.6 5.7 5.8 5.9 6.  6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9]

>>> y = np.sin(x)
>>> plt.plot(x, y) # グラフの描画
[<matplotlib.lines.Line2D object at 0x127eed2b0>]

>>> plt.show() # グラフの表示


show()を実行する事で、以下のようなグラフが表示がされます。
f:id:rossamu:20190108004103p:plain
次にcos関数も追加してみます。

>>> y2 = np.cos(x)

>>> plt.plot(x, y, label="sin") # labelにはグラフの名前を設定
[<matplotlib.lines.Line2D object at 0x128fffac8>]

>>> plt.plot(x, y2, linestyle = "--", label = "cos")  # linestyleにはグラフ描画用の線を指定。今回は破線。
[<matplotlib.lines.Line2D object at 0x127f24978>]

>>> plt.xlabel("x") # x軸にわかりやすいように名前を設定
Text(0.5, 0, 'x')

>>> plt.ylabel("y") # y軸にも
Text(0, 0.5, 'y')

>>> plt.title('Sin and Cos graph') # グラフのタイトルを設定
Text(0.5, 1.0, 'Sin and Cos graph')

>>> plt.legend() # ラベルをグラフに反映
<matplotlib.legend.Legend object at 0x128fef470>

>>> plt.show() # グラフの表示


上記を実行する事で以下のようなグラフが表示されます。
f:id:rossamu:20190108005617p:plain

画像を表示させる

pyplotには画像を表示させるための機能も備わっています。早速試してみたいところですが、その前に表示させる用の画像を用意しておきましょう。……用意はできましたか?私は今回使用する画像を、この読書メモ用のディレクトリを用意して、そこに格納しました。では次に現在Pythonが実行されているカレントディレクトリを確認してみましょう。

>>> import os # ディレクトリ操作を行うために必要なモジュールらしい
>>> os.getcwd() # カレントディレクトリの取得
'/Users/(ユーザー名)'


残念ながら現在のカレントディレクトリには画像はありません。ここからカレントディレクトリを、この読書メモ用のディレクトリに変更してみます。

>>> os.chdir("/Users/(ユーザー名)/Deep Learning/") # カレントディレクトリの変更
>>> os.getcwd()
'/Users/(ユーザー名)/Deep Learning'


無事カレントディレクトリを変更できました。それではいよいよ、画像を読み込んで表示させてみたいと思います。

>>> from matplotlib.image import imread # モジュールのインポート

>>> img = imread('salad.jpg') # 画像の読み込み

>>> plt.imshow(img) # 画像の表示
<matplotlib.image.AxesImage object at 0x12cd144e0>

>>> plt.show()


以下のように画像が表示されました。あら美味しそう。
f:id:rossamu:20190108012624p:plain

最後に

画像を表示させるのにちょっと苦戦しましたが、無事達成できて良かったです。次からはパーセプトロンアルゴリズムについて触れていくようです。楽しみですね。

【読書メモ】Deep Learningを学ぶ〜NumPyの使い方〜Part 4

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねてまとめた記事となります。ただし本の内容をそのまま書き写ししているわけではなく、ある程度自身で調べたものや感想が混じっています。ご了承ください。

f:id:rossamu:20190103000547p:plain ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

今回はPythonで高度な計算を扱う際に便利な外部ライブラリ「NumPy」の使い方を見ていきます。ディープラーニングの実装においても、このNumPyの配列クラス(numpy.array)にあるメソッドを使用します。

NumPyのインポート

Pythonでは外部ライブラリをインポートする際に import と打ち込む必要があります。今回はNumPyをnpという名前でインポートするコマンドを打ち込みます。NumPyをインポートする際にはnpというエイリアスを付けるのが慣例のようです。

import numpy as np


NumPy配列

NumPyではN次元配列を作ることも簡単です。その場合はNumPyのnp.array()というメソッドを使用し、(numpy.ndarray)を作成します。配列の要素数が同じであれば、算術計算を行うことも可能です。

>>> array = np.array([2.0,4.0,6.0])  # 一次元配列(ベクトル)
>>> print(array)
[ 2.  4.  6.]

>>> type(array)
<type 'numpy.ndarray'>

>>> array = np.array([1.0, 2.0 ,3.0]) # array上書き
>>> array + array
array([ 2.,  4.,  6.])

>>> array2 = np.array([3.0, 6.0, 9.0])
>>> array2 - array
array([ 2.,  4.,  6.])

>>> array * array2
array([  3.,  12.,  27.])

>>> array / array2
array([ 0.33333333,  0.33333333,  0.33333333])

>>> array / 2.0 # 配列と単一の数値で算術計算を行えるブロードキャストと呼ばれる機能
array([ 0.5,  1. ,  1.5])

>>> dArray = np.array([[1, 3, 5], [0, 2, 4]]) # 二次元配列(行列)
>>> print(dArray)
[[1 3 5]
 [0 2 4]]

>>> dArray.shape # 行列dArrayの形状
(2, 3)

>>> dArray + dArray
array([[ 2,  6, 10],
       [ 0,  4,  8]])

>>> dArray * dArray
array([[ 1,  9, 25],
       [ 0,  4, 16]])

>>> dArray[1] # 1行目
array([0, 2, 4])

>>> dArray[1][1] # 1行目の1番目の要素
2

>>> for row in dArray: # for文を使った各要素へのアクセス
...     print(row)
...
[1 3 5]
[0 2 4]

>>> array = dArray.flatten() # 二次元配列のdArrayを一次元配列へ変換
>>> print(array)
[1 3 5 0 2 4]

>>> array > 3 # 各要素が3より大きいかどうか
array([False, False,  True, False, False,  True], dtype=bool)

>>> array[array>3] # 3より大きい要素を取り出し
array([5, 4])


Pythonの処理速度

Pythonのような動的言語C/C++と比べると処理が遅いと言われているようです。なので、Pythonでパフォーマンスが必要な場合には、処理の中身をC/C++で実装し、PythonC/C++のプログラムを呼び出すようにします。NumPyに関しても主な機能はC++で実装されています。

最後に

NumPyの詳細な使い方は以下の記事が有用そうです。


また、NumPyに関しての本も出ているので、そちらも良さげ。

www.amazon.co.jp


次はMatplotlibの説明となります。

【読書メモ】Deep Learningを学ぶ〜Pythonスクリプトファイルにクラスを作ってみる〜Part 3

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねてまとめた記事となります。ただし本の内容をそのまま書き写ししているわけではなく、ある程度自身で調べたものや感想が混じっています。ご了承ください。

f:id:rossamu:20190103000547p:plain ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

今回はPythonスクリプトファイルを作成します。Pythonインタプリタで対話的に実行ができますが、処理をまとめて行おうとすると不便となります。ここでPythonの処理を記述したファイルを用意し、それを実行する事で一発でいくつもの処理をまとめて実行することができます。

Pythonファイルの作り方

好きなエディタで、xxx.py というファイルを作成してください。今回僕はVSCodeでファイルを作成し、 hello.py と命名しておきます。プログラム部分には以下のような一行だけのコードを記述しておきます。

print("hello world!")


f:id:rossamu:20190106043243p:plain


ファイルを実行するには、対象ファイルがあるディレクトリまでcdで移動し、python hello.pyと打ち込むだけです。

Pythonでクラスを作る

せっかくなので、ここでユーザー定義型であるクラスを定義し、まとまった処理を記述してみようと思います。

Pythonでは以下のように、classキーワードを使ってクラスを定義します。

class クラス名:
    def __init__(self, 引数, ....):    # コンストラクタ

    def function(self, 引数, ....):    # メソッド定義


Pythonではメソッドの第一引数に自分自身のインスタンスを表すselfを明示的に書く必要があるらしいです。とりあえず、簡単なクラスを作成してみましょう。

class Human:
    def __init__(self, name):
        self.name = name
        print("Start")

    def hello(self):
        print("Hello! My name is " + self.name + ".")

human = Human("Chloe")
human.hello()


これで、ファイルを実行した時に、Humanクラスのインスタンスが生成され、引数としてとったnameでインスタンス変数であるself.nameを初期化し、hello()を実行します。ちなみにインスタンス変数とは、個々のインスタンスに格納される変数のことです。つまりそのインスタンスでのみ使用する変数のことをです。これはクラス変数とは違ってクラスオブジェクトからは参照することができません。

最後に

次はNumPyの使い方になりそうです。

【読書メモ】ゲームAIを学ぶ〜知能があると錯覚させる事が何故可能かを説明する3つの科学的根拠〜 1.2 Why the Illusion Works

 

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねて要約したり、まとめた記事となります。ただし本の内容をそのまま書き写ししたり翻訳しているわけではなく、自身で調べたものや感想が大幅に混じっています。あと英語力が足りないため意味合いも違うかもしれません。参考程度に見てもらえればと思います。あと間違ってたら教えてもらえると嬉しいです。

f:id:rossamu:20190103020035p:plain

https://www.amazon.co.jp/Game-AI-Pro-Collected-Professionals/dp/1498742580

 

この本は英書のため、ちょっとずつ読んでいこうと思っています。気長にお付き合い頂けると嬉しいです。 

1.2 Why the Illusion Works

ゲームキャラに本物の知性がある!とプレイヤーを騙す事が科学的に可能である理由が、この章で述べられているようです。

 

ここでは「プレイヤーが錯覚から受ける影響」に対して働きかける、以下の3つの事を紹介しています。

 

 

  1. プレイヤーはゲームキャラクターに対して、「リアルな人間レベルの知性がかすかにある」と信じたがっている。
  2. 人は、機械とか生物とか、人間の特徴や感情がない物を擬人化したがっている。
  3. 「期待」はプレイヤーの心の中で、容易に実現可能。

 

では、1から順に見ていきましょう。

 

1.2.1 Players Want to Believe

プレイヤー達は実際、錯覚させられる事にノリノリです。むしろ喜んで参加しています。

 

彼らは、偽物であるゲームキャラクター達が人間のような特性を持っていると信じようとします。そのためなのか、プレイヤーは信じられないほど寛大な心を持っています(ゲーム内の人物が明らかな間違いを犯さない限りですが)。

 

プレイヤー達は単に「錯覚を共有したり、充分に錯覚させられるための正しいヒントと助言」を必要としています。

↑この部分だけわかりそうでわからない状態になっています。ゲームにおけるヒントシステムや、AIにおける行動ルーチンのことを指しているのかなーとか考えてます。

 

1.2.2 Eagerly Ready to Anthropomorpize

人は、物質や生物について話す時に、まるでそれらが人間であるかのように話します。

 

例えば、あの車は気性が荒いとか、最近摘んできた花が悲しみ始めたように見える、とか。

確かに私たちも普段から物に対して、まるでそれが人であるかのような表現方法を使いますね。それどころか、食べ物を擬人化したり艦隊を擬人化したりと、日本は擬人化大国な気がします。あ、話が逸れました。

 

こういった「物の擬人化」はごく自然に起こるように思えます。

 

神経科学者によって導き出された一つの理論では、私たちが人間について考えた時と、人間以外の物について考えた時の脳の使用部分は類似しており、それがどうやら関連しているのではないか、ということです。つまりこれは、擬人化は私たちが人々について考える時と同じようなプロセスを利用した結果であることを示唆しています。

 

これはおそらく私たちの脳に結び付けられている一種の誤帰属でしょう。ちなみに恋愛テクニックとしてよくあげられる「吊り橋効果」も誤帰属に関連した実験の一つです。

 

もう一つの説では、人々が「自分が理解できない行動」を理解しようとする時に、人間の特性をそこに当てはめるというもの。これが先ほどの、「花が彼枯れ始めている」ことを「花が悲しみ始めたように見える」と例えることかと思われます。

 

したがって、ゲーム内の人間のような物が何らかの行動を示した時に、私達はまず人間のような特性を最初に当てはめます。

 

これをゲームAIに活かすことで、実際の人間の知能とAIとの交絡は非常に強化されます。

 

ここで私たちはゲーム開発者として、キャラクターが人間と同様に見えるように、人型のアバターやアニメーション、動き、ボイスを実装します。

 

擬人化は「錯覚」を促進させる、有難い効果なのです。

 

1.2.3 The Power of Expectations

「期待」は、私達がどのように感じるかを強力にコントロールします。

 

例えば、貴方がワインをとても高価なものであると信じているならば、貴方はワインがより美味しいと思うだけでなく、実際の楽しさがより多くなることでしょう。

 

CaltechStanfordの研究者達は、人々に45ドルのワインと5ドルのワインを人々に贈りました。ただし実際の中身のワインは両方とも同じものです。脳撮像を使用して、彼らはあることを発見しました。それは、5ドルのワインを飲んでいる時に対して、高価だと信じ込んでいる45ドルのワインを飲んでいる時の方が、参加者の脳はより喜びを感じているということです。

 

同様に、プラシーボ効果もまた、人間にとって本当の現象であり、「期待」のメカニズムで作用する可能性があります。

 

プラシーボは、患者を欺く事を目的としており、病状に対して医学的には無効の治療法です。しかし、この無効な治療法を人に施すと、その人はしばしば良くなっているように感じたり、実際に改善されることがあります。これはプラシーボ効果、またはプラシーボ反応と呼ばれます。

 

脳撮像技術は、プラシーボが無視できないほど重要な生物学的変化を、実際に脳にもたらす事を明らかにしています。

 

このプラシーボ効果は患者の認識と期待に起因すると考えられています。

 

間違いなく、「期待」は私たちの体験に強い影響を及ぼす可能性があります。これは、知能を錯覚させる事を促進するのに、大きな影響を与える可能性がある事を強調しています。

最後に

さて、次回は錯覚を強化させるための6つの手法的な部分を読んでいこうと思います。流石に長いな、前半で3つ、後半で3つにしようかな。

【読書メモ】Deep Learningを学ぶ〜Python基礎文法編〜Part 2

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねてまとめた記事となります。ただし本の内容をそのまま書き写ししているわけではなく、ある程度自身で調べたものや感想が混じっています。ご了承ください。

f:id:rossamu:20190103000547p:plain ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

基礎文法


算術計算

>>> 5 *5
25


データ型の確認

>>>type(3.14)
<class `float`>


変数の作成とprint出力

>>> i = 10
>>> print(i + 5)
15


コメントアウト

>>> i = 10   #初期化


配列(リスト)操作

>>> array = [0, 1, 2, 3, 4, 5]   #配列作成
>>> print(array)
[0, 1, 2, 3, 4, 5]
>>> len(array)   # 配列の長さ取得
6
>>> array[4]
4
>>> array[0] = 100   # 値を代入
>>> print(array)
[100, 1, 2, 3, 4, 5]
>>> array[1:3]   # 1番目から3番目未満を取得
[1, 2]
>>> array[3:]   # 3番目以降取得
[3, 4, 5]
>>> array[:3]   # 3番目未満を取得
[100, 1, 2]
>>> array[:-2]   # 最初から最後の要素の二つ前まで取得
[100, 1, 2, 3]


dictionary操作

>>> mother = {'age':42}   # Dictionaryを作成
>>> mother['age']   # 要素にアクセス
42
>>> mother['age'] = 30   # 離婚後再婚したので年齢上書き
>>> mother['age']   # 要素にアクセス
30
>>> mother['height'] = 160   # 新しい要素追加
>>> print(mother)
{'age': 30, 'height': 160}


bool型操作

>>> isHuman = True
>>> isGirl = False
>>> not isGirl
True
>>> isHuman and isGirl
False
>>> isHuman or isGirl
True


if文

>>> if isHuman:
...     print("私は人間です")
... else:
...     print("われわれは宇宙人だ")
... 
私は人間です

Pythonでは括弧を使って塊を表すのではなく、改行で文と文を区切り、インデントでブロック(文のあつまり)を明示するインデント記法となっています。空白文字4つを使うことが一般的です。

for文

私は人間です
>>> for i in [1, 2, 4, 8]:
...     print(i)
... 
1
2
4
8


関数

>>> def cry():
...     print("にゃーん")
... 
>>> cry()
にゃーん


引数付き関数

>>> def cry(str):
...     print(str)
... 
>>> cry("にゃーん")
にゃーん


Pythonインタプリタの終了方法

LinuxMacの場合は Ctrl-D 、 Winなら Ctrl-Z を押下してEnterです。

【読書メモ】ゲームAIを学ぶ〜知能があると錯覚させる方法がなぜ必要か〜 1.1 Introduction

 

最初に

本記事は以下の本から得た知見を自分用のメモも兼ねて要約したり、まとめた記事となります。ただし本の内容をそのまま書き写ししたり翻訳しているわけではなく、自身で調べたものや感想が大幅に混じっています。あと英語力が足りないため意味合いも違うかもしれません。参考程度に見てもらえればと思います。あと間違ってたら教えてもらえると嬉しいです。

f:id:rossamu:20190103020035p:plain

https://www.amazon.co.jp/Game-AI-Pro-Collected-Professionals/dp/1498742580

 

この本は英書のため、ちょっとずつ読んでいこうと思っています。気長にお付き合い頂けると嬉しいです。 

1.1 Introduction

「人間的振る舞いを作るために努力してるけど、実際にはぎこちなくて、しかも酷く不安定なものしか作れないよね。

 

そんな知性を作り直すよりも、知性があると錯覚させることに注力するべきだよ!そう言う細工とかすれば僕たちは多分、プレイヤーに「そこには本物の知性がある!」と思わせることができる。

 

実際、そういったトリックを使わなかったとして、ゲーム世界において期待されている役割をキャラクターが振舞わなかったとしたら、本物の人間的振る舞いを作ったとしても、それは無能であり非人間的な知性と感じさせてしまう。

 

だからこのチャプターではプレイヤーに本物の知性があると感じさせるのが科学的に可能な理由と、プレイヤーの目に「このキャラには知性がある」と錯覚させ続けるための具体的な方法を6つ紹介するよ!」

 

みたいな前置きをしています。ここから本格的な説明が始まるみたいです。ワクワクしますね。明日は1.2 Why the Illusion Worksを読み進めたいと思います。