ニヒリズムにプログラミングなVRMMO世界の下を歩く
サテライト・ア・キュー!!システム(笑)(衛星的唯一に収束する機構(設定(笑))
「いまさら物語の世界観の解説をしようか」
ゲームの世界でプログラミングコードを使う感じの物語だっ!
タイトルの通りで、備忘録のつもりで書きながらも、でも読み返して楽しいを理想に、ちゃんと物語調にしたいと思う(笑)
以下世界観の説明 兼 あらすじみたいなモノ
世界観は量子コンピューターが実用化されたくらい、多分50年後くらい
主人公は私、貴方です、性別はないです
世界住人は基本的に生体を電脳化されていて、実世界は義体を使用する感じ
強いAIに管理・支配される多数の国家、資本主義でなく情報主義、より多くの、より多様な情報を生み出すのが至上価値観
ピラミッド型の多層世界になっていて、上層に行くごとに10倍の情報処理演算能力が求められる
知生体はCC~SSS++で能力判定がされる
世界の謎は解けていて、この世界は観測者という超越的な存在が管理している、既に全世界的に知られている公然の神秘
それによってか、核などによる世界の終焉、全世界的な崩壊の危機、それらの心配は完全になくなっていたり?
観測者は現状の世界を肯定しているように見受けられる、、、
そんな設定の世界です......ちなみに、私たちが今(ここのこと↑↓←→貴方です)生きている世界がピラミッドの頂点で、全員が観測者である世界です
下層の世界に行くと基本的には記憶がリセットされる、世界によって例外もあります、他にも観測端末を送り込んで情報を送信したり因果操作などなど
これら設定は特に物語内で語られることはない(だろう(笑))、のでスルー推奨です、省略しても良かったかもしれませんね(笑)w
ニヒリズムにプログラミングなVRMMO世界の下を歩く
今日も今日とで、フルダイブのVRMMOの世界に飛び込む。
私は、この自由度の比類なき高さを誇るゲームが好きである、なので毎日のようにプレイする。
町の外れで。
珍しい魔物を見つけた、プレイヤーが制作した奴である。
「ぷうーーぷうーーー♪」
このゲームは基本的に全て強いAIが管理し、あらゆるゲームバランスをリアルタイムで調整している、
で、このようなプレイヤーが勝手にオーダーメイドしたモノがゲームバランスの崩壊なく作られて、実際に投入されてる。
ぶっ壊れは修正依頼が出され、対価に見合わない店売り商品はダメとか、エロ系はダメとか、なんとなく世界観に合わないのはダメとか色々だ。
...........
さて、簡単に捕まえた、見た目が良いだけで気に入ったが、弱い奴だ。
return list[Random.Range(0, list.Count)];
場面に応じたボイスをランダムで1つ取得して戻すコードである、私は中空でタイピングして、テイムし再召喚した魔物に鳴き声を設定する。
その他にも見る、デフォルトじゃない、オリジナルの、このような特殊な魔物は内部のコードの構造まで見ないと色々と危険なのだ。
だが、どうやらヘンテコなコードはない、そりゃそうだ破綻してたら、そもそもが中央管理Aiに駄目だしされる、
個性と見なされなければスルーか微自動修正か、プレイヤーが気に入らないタイプなら作り直せとか、あるから
さて、自分的に少し気に入らない、特には処理の関係で”重くなる”処理関係の修正。
修正前
[Header("鳴き声のプレハブ")]
public GameObject eoPrefab;
// 鳴き声のプレファブのクローン、魔物情報の生成位置に生成
GameObject eo = Instantiate(eoPrefab, eoSetTran, false);
修正後
[Header("鳴き声のプレファブ")]
public Eo eoPrefab; // ここを 変更。 GameObject型からEo型に変更する。プレハブは同じようにアサインできる
// 鳴き声プレファブのクローンを、魔物の生成位置に生成
Eo eo = Instantiate(eoPrefab, eoSetTran, false); // 変更。 生成された魔物を代入する型をGameObject型からEo型に変更する
よくあるミスというか手抜きというか、最初からクラスになっていれば所謂ゲットコンポネントしなくて済み軽い。
勿論こんなフルダイブのゲームなのに重くなるわけないのだが、プレイヤースキルの範疇として評価されるゲームシステムとか、そういう理由によるのだろう、たぶん(笑)
// アクション
Action();
// 会話中は移動のキー入力受付を行わない
if (isTalking) {
return;
}
public void MTalk(Vector3 playerPos) {
// 会話を行っている状態に
isTalking = true;
// TODO プレイヤーの位置を確認,ウインドウを出す位置決定
// TODO 会話のウインドウを表示
Debug.Log("会話ウインドウを開く");
}
/// <summary>
/// 会話終了
/// </summary>
public void StopTalk() {
// 会話をしていない状態に
isTalking = false;
// TODO 会話のウインドウを閉じる
Debug.Log("会話ウインドウを閉じる");
私は燦燦と照り付ける太陽など気にしないように、いつもマイホームで作業するように色々と設定する。
中空を漂う複数の浮遊体、三つのグラフィックユーザーインターフェース、所謂GUIを見ながら、手元のホログラフィックのキーボードを叩く。
// ボタンの重複タップ防止
btnSkill.interactable = false;
さらに魔物の顔を見ると、舌が出しっぱなし、恐るべき間抜けさ、一定の間隔で舌を出し入れさせよう。
LoopType.Yoyo。
この場合は、A から B , B から A という形式でループする。
「セフィロト起動」
アシスタントAI、私には必要ないが、この世界ではAIの相手をしてやるだけで色々なアイテムが手に入る。
この世界のAIは強化学習を重視しているのだろう、どんなプレイヤーにも必ず専属で最初から憑いてくる、誤字じゃなくね。
「 また out キーワードによる宣言があります。 」
outキーワード宣言、それだけだと用途・用法的に色々あるが。
こを行うと、out を付けた引数で指定した変数は、メソッド内で必ず結果が入ることが保証。
そのため、処理結果の戻り値が true の場合は、必ずこの out の後に宣言した変数内に型が代入。
「 そのオブジェクトにアタッチされている NPlayerCharacter クラスが取得された場合 」
チュートリアルモードでランダムに話させている。
if (hit.collider.TryGetComponent(out NPlayerCharacter npc)) {
「 今回はこのような処理として利用しています。hit 変数の持つ collider から NPC のオブジェクトへとアクセス、
NPC のオブジェクトに対して TryGetComponent メソッドを実行しているのです。」
聞き流しながら。
// ループを行い、スキルが押されるまでスケールを変化させ、アニメを実行する。それをtw変数に代入しておく
tw = imgSkillP.transform.DOScale(new Vector3(1f, 1f, 1f), 0.2f).SetEase(Ease.InCirc).SetLoops(-1, LoopType.Yoyo);
上記の処理では、imgSkillP.transform.DOScaleに対し、ループ処理。(SetEaseもSetLoopsと同じ、単体では動かないメソッド)
第1引数はループを行う数。
int型で設定。
今回のように -1 を指定で、それは無限ループ。(ループが終了しないということ)
「 このような場合は明示的に処理を停止させないと無限にループを繰り返します。」
「なに? アンタには、なにか意見は無いの?」
適当に尋ねてみる、まあ特に無いのだろうと当たりを付けながら。
「 はい、特にはありません、最適な設定かと。
そして、 第2引数では、ループさせるタイプをLoopTypeのenum型から選択します。
今回のような、LoopType.Yoyo の場合は、A => B B => A という形式で、ループを繰り返します。
文字通り、ヨーヨーと同じ動きです。
他にも様々なLoopTypeがあります、お調べいただく事を推奨します 」
ちなみに、このAIは思考を完全に読んでいたりするんだよなぁーー割とビビる。
さきほど私は、メソッドの引数を第一引数から思索していたのだが、それが終わった前提で第二引数から説明を始めたりしている所以だな。
[System.Serializable]
public class ItemInventry {
public ItemName itemName; // アイテムの名前
public int count; // 所持数
public int number; // 所持している通し番号
カタカタ、カタカタ、ホログラフィックだが、まるでキーボードを叩いてる時のような効果音、これが無いと私はいけない。
/// <summary>
/// ItemInventryクラスコンストラクタ
/// </summary>
/// <param name="name">名前</param>
/// <param name="value">アイテム所持数</param>
/// <param name="num">所持した際の通し番</param>
public ItemInventry(ItemName name, int value, int num) { // 戻り値はない
itemName = name;
count = value;
number = num;
}
ちなみに、こういう風に適当に時間を使って色々と設定しているだけで、テイム魔物は強化される。
凝れば凝るほどってわけじゃないが、美しいコードを書けばAIが気分で評価する感じだろうか?
itemInventryList.Add(new ItemInventry((ItemName)Enum.Parse(typeof(ItemName), stringArray[0]), int.Parse(stringArray[1]), int.Parse(stringArray[2])));j
「ねえ、ちょっと、このコードの解説をしてよ」
「 はい、メソッド書式は [(キャストしたいenumの型)Enum.Parse(typeof(キャストしたいenumの型), キャストする文字列] です。
利用するためには using System; の宣言が必要になります。」「ふ~ん」
if (Input.GetButtonDown("Ac")) {
// (action=Ac)AclayerMasks変数に代入されている複数の文字列のLayerを判定対象
「これは、NPCレイヤーのオブジェクトだけでなく、宝箱などの汎用指定のレイヤーオブジェクトにも反応・対応するようになっております」
RaycastHit2D hit = Physics2D.Raycast(rb.position, lookDirection, 1f, LayerMask.GetMask(aclayerMasks));
// Sceneビューにて Ray可視化
Debug.DrawRay(rb.position, lookDirection, Color.blue, 1.0f);
これによって魔物の向いている視線を可視光線化している、プレイヤーのみに見えるモノ。
// Rayによってhit変数にコライダーを持つオブジェクトの情報が取得できている場合<=これから今回からは、NPC、または汎用指定オブジェクト両方のレイヤーオブジェクトを取得するようになる。
if (hit.collider != null) {
// そのオブジェクトにアタッチされているNPlayerCharacterクラスが取得できた場合
if (hit.collider.TryGetComponent(out NPlayerCharacter npc)) {
そうだ、魔物も話せるようにしておく。
// 取得した NPlayerCharacterクラスを持つオブジェクトとプレイヤーが話してない場合
if (!npc.isTalking) {
// NPC との会話イベントを発生させる
npc.PlayTalk(transform.position);
// 魔物を会話イベント中の状態にする
isTalking = true;
私はアシスタントAIと話し中を解除する、すると魔物はセフィロト(AIの名前だ)を見る。
くーくー とか言って擦り寄った魔物、無暗にヒラヒラな銀のドレスが汚れもせずに大きく靡き、奴は綺麗な笑顔で慈愛の籠ってそうな視線を足元に向けただけ。
// 取得した NPlayerCharacterクラスを持つオブジェクトが会話中である場合
} else {
// NPC との会話イベントを終了する
npc.StopTalk();
// Player を会話イベントをしていない状態にする
isTalking = false;
}
}
私はAIセフィロスとの会話中に戻す、すると魔物は途端に飽きたかのように後ろを向いて、気分が変わったかのように草むらを歩く。
// そのオブジェクトにアタッチされている汎用指定クラスが取得できた場合
else if (hit.collider.TryGetComponent(out sBox Box))
{
// その物が調べ済ではない場合
if (!sBox.isOpen) {
// 調べイベント用のウインドウを開く
sBox.OpensBox(transform.position, this);
...疲れてきた、、というより飽きてきた。
とりあえず、今のお前の作り込みは、このくらいで。
勿論コイツだけの為じゃない、テイム魔物プリセットとして登録して、様々にカスタマイズできるようにする一貫であるが。




