いずのBlog

好きなこと書いていくブログ

Unityでノベルゲームを作りたい!#1

今回の趣旨

今回はタイトルにもある通りノベルゲームを作るというものです。

 

正確にはノベルアドベンチャーゲームです。

 

そもそもノベルアドベンチャーとは何かというと、いわゆるギャルゲーや乙女ゲームといった恋愛ゲームで使われるゲームシステムのことで下の写真みたいなのを想像してもらえればと思います。

 

f:id:izukunKK:20201101182542p:plain

この画像は僕が運営する外国人向けのメディアサイト「IROHA JAPAN」の登場キャラクターである「いろは」にきてもらいました!

japan-iroha.com

 

こういうのがノベルアドベンチャーゲームです。

 

昔は男性向けのギャルゲーが主流でしたが、今は圧倒的に女性向けの乙女ゲームが多いように思います。

 

個人的に一番好きな乙女ゲームは「アルカナ・ファミリア」です!

ストーリーの雰囲気は「家庭教師ヒットマン・リボーン」の女性版って感じですかね。

それとアニメも放送されていてOPがめっちゃかっこいい!

 

いや、誰が知ってるねん!
めっちゃ古い!
ってかなんで男が乙女ゲームやってるねん!

 

といった声が聞こえてきます(笑)

 

あのゲームは普通に面白かったんで男性でも楽しめます!

それと僕の姉が乙女ゲームファンだったんですよね。

 

そんなこんなで、ノベルアドベンチャーゲームを個人で開発する方法を考察していきたいと思います。

 

今回は雰囲気だけつかめればいいかなって思うのでDBは使わずにセーブ機能はつけません。

今後本格的にネイティブアプリとして制作するのであればクライアント側のDBも考えないとですね。。。大変だ―。

 

今回はUnityを使って作っていきます。Unityを使う理由は以下です。

・多くの無料アセットを使うことができる

・世界的に有名なゲームエンジン

・Unityについてもっと勉強したい

 

こんな感じです。

そもそもUnityはドラクエのような3Dのオープンワールドの製作に適しているといわれていて、僕がこれから作るようなノベルゲームは適していないと聞きます。

 

でも実際に調べてみるとノベルゲームのエンジンとして利用している人も多く、様々な無料で使えるアセットやスクリプトが存在しています。

なので作ること自体は可能かもということでUnityを使っていきます。

 

Unityでノベルゲームを作る方法

 

僕が調べた限りUnityでノベルゲームを作る方法で有名なものは以下になります。

 

1)自作スクリプトでTextを操作

2)ゲームエンジン「宴」

3)ゲームエンジン「ジョーカースクリプト

4)無料アセット「Fungus」

5)有料アセット「NaniNovel」

 

この辺が有力な気がしました。

自作スクリプト

この場合はC#の知識が必要なのでプログラマー向けですね。また工数も多くセーブ機能も自分で作らないといけないのであまり現実的ではないのかなって思います。

個人的に今回はノベルゲームの所感を知れればいいので敬遠します。

時間があるときに0から作ってみたい。

 

ゲームエンジン「宴」

この場合は日本語の書籍も販売されておりおすすめの方法です。

 

Unity&宴「ノベルゲーム」開発入門 (I・O BOOKS)

Unity&宴「ノベルゲーム」開発入門 (I・O BOOKS)

 

 また、コミケなどに参加する同人サークルでゲームを開発している友人はこれを使って開発していました。プログラミングコードを書かなくてもいいので誰でも開発することができます。

ある程度自由度もありそうなのでオリジナリティのあるゲームが作れるようになると思います。

使ったことがないのでうまくは語れません。いつか使ってみます。

 

ゲームエンジン「ジョーカースクリプト

この場合は上の方法と同じでUnityで使えるゲームエンジンです。同様にプログラミングコードを書くことなくゲームを開発できます。「宴」のように書籍が販売されているわけではありませんが、公式サイトでの使用方法の説明が充実しているように思います。

jokerscript.jp

 

書籍で勉強する場合は以下の本がおすすめです。

 

 

これはジョーカースクリプト単体の本ではなく2Dのキャラクターにアニメーションを付けるツールであるLive2Dを主に説明しています。しかし後半部分ではこのジョーカースクリプトに関する説明があります。

ここにもある通りジョーカースクリプトはLive2Dとの互換性もあるのでノベルゲーム中にキャラクターにまばたきをさせたり、首を振らせるといったアニメーションを付与することができます。

 

僕自身この方法でゲームを作ったことがあります。

プログラミング無しでもゲームを作れますがその代わり独特の文法を使ってテキストを書いていくのでなれるまでに時間がかかりそう。

 

無料アセット「Fungus」

これはUnityのアセットストアからダウンロードし、アセットにインポートすることで使うことができるようになります。

assetstore.unity.com

前の二つと同様にノーコーディングでノベルゲームを作ることができます。

特にRPGなどでキャラクターに話しかけると会話が始まるみたいなスクリプトを書くこともできるので完全にノーコードではありません。

FlowChartを使うことでストーリーの流れを視覚的にとらえることができるのでゲーム開発者にとってはバグの改善に役に立ちます。

他にもセーブ機能や選択肢や画面遷移などの機能が搭載されており、ノベルゲームを作るうえで困ることはないと思います。

 

しかし、日本語の情報が少ないので英語が苦手な方は少し大変化もしれません。
YouTubeとかで公式の方が実際に使っている動画を出してくれているので(英語だけど。。。)、これを見ればおおよその使い方は習得できそうです。

 

個人的にはこの方法で開発を進めようかなと思っています。

ここに書くと長くなりそうなので次回のブログにしようと思います。

 

有料アセット「NaniNovel」

最後に紹介するのはNaniNovelです。Fungusよりも便利な機能が搭載されておりより本格的なゲームを開発したいならいいかもです。

いつか使ってみようと思います。

naninovel.com

値段が150$なので日本円だと1.5万と少し高額なので学生の自分には手が出しずらいです(笑)

 

結論

とりあえずFungusを使って作っていきたいと思います!

きつかったら「ジョーカースクリプト」に切り替えると思います。

 

次回はFungusをつかったゲーム開発についてブログにします。

 

ここまで読んでくれてありがとうございます。

 

もし間違っていたり、質問がある方は僕のツイッターの方にDMしてくれれば助かります。必ず返信します。

 

C++でニュートン法を実装して非線形方程式の解を求めたい!

このブログの対象者

数値計算を1ミリも知らない理系学生

数値計算に興味がある社会人

・何かでC++を使わないといけない人

今回の趣旨

今回は非線形方程式の解法をC++で実装してみようといったものです。

なんでC++やねん!PythonとかFortranでええやろ!という声が聞こえてきます笑

 

たしかに最近の科学技術関連の計算はPythonが人気ですよね。
数値計算ならFortranがパフォーマンス上優秀とは聞きます。。。

 

でも僕の通っている大学ではなぜかC++を使う文化があるんですよねー。
早くシラバスを変更してほしい!!

 

そんなこんなでC++を使ってきた僕が数値計算のいろはをC++で紹介していきます!!
ちなみに僕は素粒子理論の研究室に入っていて数値計算を使った研究をしてます。

 

そもそもC++の情報ってCやC#に比べて少ないように思います。
なのでC++を使ってレポート課題をやらなければいけない理系学部生にとって有意義なものになったら最高かなって思います!

ニュートン法の簡単な説明

正式にはNewton-Raphson法といって方程式の解を求める時に便利な数値計算法の一つです。

あくまで微分を含まない形の方程式を求める手法ですので微分方程式の解は求められません。

そのような微分方程式を説きたい人はオイラー法とかルンゲクッタ法で調べるとよかと思います。

この辺もいつかブログにしたいです。(But 時間がない。。。)

 

 解を求めるというのは具体的にどういうことか?

$x^2 + 3x + 2 = 0$

という方程式の解を求めたい場合を考えます。

これは中学数学で簡単に解が求まりますよね。

 

でも今回はプログラミングで求めてみたい!!という趣旨なので因数分解はしません!!
というか因数分解なんかできないような非線形方程式を扱います!

 

たとえば

 

$$sinhx + 3x -2 =0$$

 

なんかは簡単には解けなさそう。。。ってなりますよね。

 

ニュートン法はこのようなときも役に立つのですよー。

 

さっそく始めましょう!

まずは下の図をみてください。

newton-raphsonの資料

newton-raphson法の流れ

とりあえずこんな感じのグラフを考えてみます。

$f(x)=0$の解がほしい場合、

僕たちが考えるべきなのはオレンジ色の関数とx軸の交点の座標なんです。

 

まず始めに任意の初期値$x_0$を定めます。

その$x_0$の時の関数の接線を考えます。

その接線とx軸の交点を$x_1$とします。

こんな感じで$x_0 \to x_1 \to x_2$で続けていきます。

 

なんかこれ繰り返したら解が求められそうじゃね?というのがニュートン法です。

 

でも、これって何回も繰り返しても本当の解って定まらなくね?
結局は近似解しか求まらない?
って思ったそこのあなた!。。。その通りです(><)

 

数値計算においてぴったり解が求まることなんて滅多にないんですよね笑

 

なんなら弱点もたくさんあったりします。
有名な弱点を2つ紹介します。。。

極値の近くで接線飛ばされちゃったパターン

これは初期値の値が関数の極値の近くにある場合です。

ご存知の通り極値は傾きが0で、その接線はx軸に平行になります。

 

なのでx軸に交わらない、または交わっても遠方になってしまうんですよね。

いい感じに極値をまたいでるパターン

極値近傍問題

極値近傍問題

 こんな感じに接線が無限に繰り返しちゃう場合があるんですよ。

8の字で永遠に繰り返して解が求まりそうになさそうですねー。

 

これらの問題をニュートン法の初期値問題と言います。

解決策として減速法というのがあります。

 

 

接線の方程式

newton-raphsonの資料

newton-raphsonの資料

プログラムを書いていく上で重要な接線の方程式はこんな感じです。

$$f(x) = f^\prime (x_0) (x - x_0) + f(x_0)$$

 

ここから$x = x_1$、$f(x) = 0$として$x_0$の次のx座標である$x_1$を求めます。

 

$$x_1 = x_0 - \frac{f(x_0)}{ f^\prime (x_0)}$$

 

これを一般化すると

$$x_{n + 1} = x_n - \frac{f(x_n)}{ f^\prime (x_n)}$$

となりますね。これが前後関係です。

 

ここまで大丈夫でしょうか?

とりあえずここまでで下準備は完了です。

次からプログラムを書いていきます!!

C++でプログラムを書いてみる

今回は

$$sinhx + 3x -2 =0$$

の解を求めようと思います。

とりあえずの初期値を$x_0 = 1$でやってみます。
(これは完全に適当です。)

 

無理っぽかったら他の初期値にしてみたり、減速法を使います。 

 

 

#include <iostream>
#include<math.h>
#include<string>
using namespace std;
int main()
{
    double x;
    double x0;//initial data
    double x1;//next data
    double delta = 0.00001;
int i = 0;//繰り返した回数 auto f = [](double x) { return sinh(x) + 3*x - 2;//f(x) }; auto g = [](double x) { return coshx + 3;//g(x):微分した関数 }; x0 = 1;
while (i < 100) {//繰り返し回数の上限 x1 = x0 - f(x0)/g(x0); cout << "x=" << x1 << '\n'; if (fabs(x1 - x0) < delta) {//前後の差分がdelta以下なら終了 break;
} x0 = x1;//x1を初期値に代入 i++;//カウント } return 0; }

 こんな感じのプログラムを書いてみました。

初期値$x_0$からスタートしていき$x_0 \to x_1 \to x_2$といったようにx軸の値が変化していきます。

 

じゃあ、その終着点はどうなるん?といった話をします。

これはxの数列が$x_0 \to x_1 \to x_2$となるときに数列の前後の差分が0.00001以下になったときに繰り返しを終わるようにプログラムを作っているんですよね。

0.00001のようなところはより小さい数のほうが精度は高く出ます。
このへんは自分の好きに変えても大丈夫です。

でも単精度の有効数字8桁までには納めた方が良さそうです。へい!

 

これを実行するとコンソール上には以下のような数字が出力されました。

x=0.521206
x=0.494932
x=0.494888
x=0.494888

 

5回目で求まりましたねー。これはかなりいいです。

最終的に解はx=0.494888って教えてくれました。

 

妥当性を検証してみる。

$$sinhx + 3x -2 = 0$$

の解として$x = 0.494888$をコンピュータ君が教えてくれたので、これを逆に代入してみて本当に0になるのかを確かめてみます。

 

実際に代入すると

$$f(0.494888) = 0.0000017 \simeq 2.0 * 10^{-6}$$

 

となりました。精度的には申し分ない気がします-。やったぜ~!

 

おわりに

ここまで読んでくれてありがとうございます。

もし、間違えているところがあったり、質問などがあるかたはツイッターのDMなどで気楽に教えてくださいーー

 

では!お疲れ様です!

 

[https://twitter.com/izukunKK:embed]