ぐっちーの駄弁り部屋

個人的に制作しているものの進捗や日常について不定期投稿

2020年を振り返ってみる

皆さんこんにちはグッチーです。
今年ももう終わりですね。大学生活も残すところ3ヶ月ほどになってしまいました。
今年は何かと個人的イベント的なものが盛り沢山で今まで以上にあっという間に過ぎ去ってしまった感がありますね〜
去年もやったんですが簡単に今年の出来事を振り返っていこうと思います。

1月〜6月

え、最初の見出しで半年分まとまってるの?と思ったかたいると思います。
そうなんです。正直この頃の記憶は就活してた記憶しかないのです。
私自身もそんなことないやろとカレンダーを確認したところ「〇〇社面接」みたいなスケジュールしか入ってませんでしたwww
コロナが流行ってたこともありオフラインのイベントは根こそぎ中止になったりオンラインイベントも就活の疲れからあまり参加するモチベーションを保てなかったんだと思います。3月頃くらいから初めて内定をいただくまでは精神的にも参ってしまっていたくらい闇の深い半年でした。
一応拙い文章ではありますが就活記みたいなのを記事にしているのでよかったら覗いてくれると嬉しいです。

gucchi.amebaownd.com

そんな中でもチマチマ個人制作はしてたので2つほど形になりました。

ColorAdventure

一つ目は某イカちゃんゲームのようなアドベンチャーゲームです。 gucchi.amebaownd.com

ゲームの概要としては一見何もない真っ白な世界なんですがプレイヤーはインク弾を放つことができてそれで色をつけることで壁の輪郭が見えるようになり迷路を攻略できるようになるというものです。
動的にテクスチャペイントをする方法とか作ってて勉強になることも多く形になったのも割と満足しているものになります。

UniSlide

二つ目はUnityをプレゼンツールにしてみたってやつです。

gucchi.amebaownd.com

Unityユーザーが何か作ったものをプレゼンするときに実際のものを見せることが多いと思いますが動画だけだと伝わりづらいし、かといってUnityとプレゼンツールを行き来するのも面倒と思って開発したものになります。
機能的には全然拙いんですが最低限プレゼンの編集とプレゼン用カメラとシーン用カメラの切替、プレゼン資料を送る機能は実装しました。
これはエディタ拡張を乱用したものになっていてエディタ拡張自体を使ったことなかったのでこれも作ってて楽しかったです
エディタ拡張については私の所属しているA-PxLのブログにて記事にしたのでそちらもご覧ください

aizu-vr.hatenablog.com

実のところ今年の目標を毎月何か作って記事にするとしていたのですが成果物が2つしかない時点で分かる通り達成できてません
来年は達成度が高くなるような目標を立てていきたいですねえ

7月〜10月

この辺りの時期は学校も夏休みに入り(単位は取り終わってるので元々夏休みみたいなものだったんですが)まとまった時間が取れるようになったので今まで勉強してなかった分野の勉強をしてたり卒業論文(私の場合は開発)もあるのでそちらに取り組んだりしてました。
前者は今までUnityに頼って開発してたので頼らないゲーム開発に興味がありそれの勉強をしてました。C++自体の勉強も兼ねてゲーム開発で大切な部分を勉強してました。これの勉強についてはこの期間で終わっているわけではないですね
卒論についてはリダイレクテッド・ウォーキングという手法を実現するソフトウェアを開発しました。どこまで公開していいものなのかわからないので現状非公開にしていますがVR空間での無限歩行については個人的に興味深いテーマで研究室の先生に提案してやらせてもらっているテーマです。
この辺りの時期から何か学ぶことに対して今まで以上の意欲を持って取り組むようになった気がしますwwww

11月

11月はまず知り合いのShirotsuさん主催のゲーム技術限定LTに参加してきました。
この時はジオメトリシェーダーを使った召喚エフェクトを作ったよーって感じの内容で話させていただいて参加された方々から多くの反響をいただきうれしかったです。この時話した内容については記事にする予定はありませんが発表スライドとYoutubeアーカイブを貼っておきますね。

docs.google.com


Online Game-Tech LT 2020

このLT会は学生だけでなく一般の方も参加していたので実際現場で使われている技術なんかも聞くことができて非常に有意義な時間を過ごすことができました。

あとは前月の勉強の続きをしたり今も開発中のゲームのプロトタイプを作ってたりしました

はてなブログの方に戻ってきたのも11月でしたね

12月

今月はほとんど個人ゲーム開発に精を出していた気がします。年末が近かったり新生活が近づいていたりして何かと手続き関連でバタバタしていたのでさすが「師走」って感じで何かと忙しかったです。
精を出していたゲーム開発というのが遊ぶひとがそれぞれ持っているVRM形式のアバターを読み込んで戦うアクションゲームを現在製作中です。動的にモデル読み込んだら面白いだろうなという思考の元その機能から作り始めたゲームなんですが、ある程度完成した時点で「キャラ読み込んでどんなシナリオを進めるようにしよう」とゲーム本編の流れを全く考えていなかったことに気づき今そのアイデアを練っている感じなのです。
一応クリスマスの日にプレイヤーの操作部分までできたのをTwitterの方に進捗として投稿しました。

あとはシナリオの他に敵を追加してマップを作ってタイトル&ゲームクリア画面作ってって感じですかね
卒論の提出もじわじわ近づいてきているので文章の添削とかを行っている感じです。

2021年

来年は社会人1年目になる年なので覚えることがいっぱいだったり新生活だったりで個人的な開発とかできる時間があるか怪しいのでブログの記事とかは覚えたことを書いていくようにして半備忘録みたいにしようかと思います。
学生に比べて大変だという話はいやというほど聞かされているのである意味卒業するのが嫌なのですが新しい技術に触れられると考えるとある意味楽しみでもあります。 あとはやっと都会に進出できるので生活も楽しみですwww
そんなこんなで大学入学当時のような新しい体験ができそうな年になりそうなので楽しみではありますがコロナも心配ではあるので体調管理には気を配っていきたいですね

最後に

今年も多くの人に関わらせていただいて、助けていただいた1年でした。来年も素敵な一年にしていきたいです。
それでは今日はこの辺で(`・ω・´)
今年一年ありがとうございました!!来年もよろしくお願いいたします!!

Unityで作成したアプリでVRMファイルをランタイムに読み込む方法

皆さんこんにちはグッチーです。
今回はVRSNSで最近良く使われるようになってきたVRMファイルをWindowsのファイルダイアログから動的にロードする方法についてまとめていきたいと思います。
なんか面白いゲームを作りたいと考えていたときに「自分の持ってるVRMファイルで遊べるゲームとか面白そうじゃないか」と思ったのがことの発端で記事を探していた結果組み合わせてうまくいったので記事した感じです。

環境

今回実現した環境は以下の通りになります。

  • Windows10
  • Unity2019.3.13f1

Windows Formsを使用しているのでMacでは動作しないかと思いますのでご容赦ください。

手順

実装の手順としては大きく分けて2つのパートがあり

  1. ファイルダイアログを開いて使用したいファイルのパスを入手
  2. そのパスをもとにUniVRMを用いてVRMファイルを読み込み

となっています。記述するコード自体はそこまで難解なものではありませんでしたがDLLのコピーなど少し手間がかかる工程もあるのでそのあたりも細かく説明していきたいと思います。

その1:ファイルダイアログの表示

ファイルダイアログとはUnityやWebサービスなどを使っているときに「ファイルを開く」のような項目を選択すると表示されるウインドウのことです。UnityEditor内で動作させてファイルを検索したりするのであればファイルダイアログを表示させる必要はないのですがビルドしてexeファイルとしてから使用したいのであれば必要になります。
今回はビルドしたゲームからVRMファイルを読み込みたいと思っているのでこれを表示させる必要があります。
Windows向けに作られたアプリケーションにはOpenFileDialogを使ってこれを実現することができます。

OpenFileDialogを使ったコード

ではダイアログを開くためのコードを書いていきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Windows.Forms;

public class OpenFile : MonoBehaviour
{
    public string ItemLoad() {
        OpenFileDialog ofd = new OpenFileDialog();
        //ダイアログが開いたときに開くディレクトリのパス
        ofd.InitialDirectory = "E:/vroid/MyAvater";
        //選択できるファイル形式のフィルタ
        ofd.Filter = "VRM files(*.vrm)|*.vrm|All files(*.*)|*.*";
        //ダイアログ上部に表示するタイトル
        ofd.Title = "VRMファイルを選択してね";
        //ダイアログの表示
        ofd.ShowDialog();
        //選択したファイルのパス
        string filePath = ofd.FileName;
        return filePath;
    }
}

OpenFileDialogのインスタンスを作成して各種項目を設定してからダイアログを表示させます。OpenFIleDialogの設定項目などについてはMS社のリファレンスを参照してください

docs.microsoft.com

選択したファイルの情報はインスタンスが持ってくれているので参照します。
この関数をファイルの読み込みをしたいタイミングで呼び出してあげればいい状態です。(この実装ではこの関数でファイル自体を読み込んでいるわけではないです。)

DLLのコピー

上に書いたようなコードをそのまま使おうとすると「System.Windows.Formなんて見つからないが?」とUnityさんに怒られてしまいます。これを解消するためにDLLを用意します。
使用するDLLはUnityをインストールしたディレクトリの中にあります。詳しいパスとしてはE:\Unity_Editor\2019.3.13f1\Editor\Data\MonoBleedingEdge\lib\mono\unityjitにあるSystem.Windows.Form.dllをAsset\Pluginにコピーしてください。
11/29 追記
私の環境ではE:\Unity_Editorというディレクトリ以下にUnityhubからUnityをインストールしているので上のようなパスになっています。それぞれ自分の環境でUnityをインストールしたディレクトリ以下を探してDLLをこぴーするようにしてください
mono以下の他のディレクトリに同じ名前のファイルが存在していますがAPI Compatibility Levelを.NET 4.xとしている場合はこれを使えば良さそうです。

その2:VRMの読み込み

次にVRMファイルの読み込みを行います。VRMの読み込みにはUniVRMを使用しますのでダウンロードをしておいてください。

github.com

ダウンロードしたUniVRMをUnityへインポートしたらVRM読み込みのためのコードを書きます。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using VRM;

public class ImportVRMFile : MonoBehaviour {
    public GameObject player;
    
    public async Task Import(string filePath) {
        //ファイルダイアログから取得したパスを使ってVRMファイルをByte配列に読み込み
        var bytes = File.ReadAllBytes(filePath);
        //VRMImporterContextがVRMとしての読み込み関連を行ってくれます
        var context = new VRMImporterContext();
        //GLB形式でJsonの読み込みとParse
        context.ParseGlb(bytes);
        //metaデータを取得(引数のtrueはサムネの読み込み用です)
        var meta = context.ReadMeta(true);
        
        //非同期で読み込み
        await context.LoadAsyncTask();
        //読み込み完了するとcontext.Rootに読み込んだVRMモデルのGameObjectが入っているので取得
        var root = context.Root;
        
        player = GameObject.FindWithTag("Player");
        //適当にプレイヤーオブジェクト以下に配置
        root.transform.SetParent(player.transform, false);
        //メッシュの描画
        context.ShowMeshes();
    }
}

それぞれコードの説明はコメントのとおりです。最後のShowMeshes()が実行されるまではメッシュが描画されないので描画する前に適当な場所に配置するなどして上げると良さそうです。

おまけ:デモ用のUI周りのコード

このあと載せるデモ動画で使っているUI周りのコードです。ボタンを押したらロードされるだけの機能です。

using UnityEngine;
using UnityEngine.UI;
using System;

public class UIManager : MonoBehaviour {
        
    public void OnLoadButton() {
        OpenFile of = new OpenFile();
        string filename = of.ItemLoad();
        ImportVRMFile importVrmFile = new ImportVRMFile();
        importVrmFile.Import(filename);
    }        
}

この記事書いてて「なんで俺はImportVRMFile側からOpenFileを呼んでないんだろう」と不思議で仕方がありませんでした(前日寝る前に思いついてテスト用に作ったコードを載せているのでご容赦いただきたい…)
実際にゲームに組み込むときはしっかりと呼び出しの関係を整理していきたいと思っています。

できたもの

結果的にできたものがこちらになります。

録画の都合上フルスクリーンでUnityEditor上で動かしているように見えなくもないですがビルドしたものを実行しています。

最後に

こんな感じでランタイムにVRMファイルを取得して来ることができました。あとはこれを組み込んだゲームを作って遊んだユーザーが使いたいVRMファイルで遊べるようにしてい着たいと思います。
もちろんファイルの読み込みは別のファイルでも可能ですしOpenFileDialog単体での読み込みもできるみたいですので興味のある方はやってみてください。
それでは今日はこのへんで( ー`дー´)キリッ

参考記事

qiita.com

qiita.com

勉強のために写経したかっただけなのに…

皆さんこんにちはグッチーです。
最近めっきり寒くなってきましたね。件の感染症もまた流行り始めたので体調管理には気をつけねば…

さて今日はここ数日引っかかってた問題について解決した(はず)なのでそれについて話していきたいなと思います。
どちらかと言うと個人的な備忘録的なものに近いです。

何があったのか

まずは何があったのかお話したいと思います。先週の金曜くらいまで卒論関連でバタバタしてたんですが一応落ち着いたので積読の解消をしようと思いまして「ゲームプログラマになる前に覚えておきたい技術」という本を読んでいたんです。
この本はVisualStudioとC++を使ってゲームを作りながら2D/3Dグラフィックの基礎や衝突判定などUnityでゲーム作るときにはUnityがやってくれている部分について学ぶことができる本で結構有名な本です。
私はC++自体初心者で開発なんかはもってのほかなんですが興味自体はあったので少しずつ勉強している最中だったのです。まとまった時間が取れそうだったので今回この本をガッツリ進めようと読み始めたわけです。
C++を書いた経験自体が少ないので書き方やらも併せて勉強しようと思ってサンプルコードを写経してたわけなんですが2章に差し掛かったあたりで全く同じコードを書いてるのにコードがちゃんと動かないという壁にぶち当たりました。
その章から著者の方が用意してくださったライブラリを使っていたのでそれの参照が間違っているのかと思いそのあたりを調べながら差し替えてもだめでした。(VisualStudioの使い方にもなれていないのでここの差し替えですら時間がかかりました)
ネットで原因を調べているとバージョンが合っていないのが原因らしいことがわかりました。
この本自体発行が2008年と相当前で今売られているものも第1版のものなのでプロジェクトは当時のVisualStudio2005と2008で動くように作られています。
なのでそれをしっかり治す必要があったというのが今回ぶつかった問題です。次の章で治すまでに私がしたことを書きたいと思います。

ライブラリ関連ファイルのビルド

私の今回の環境はWindows10、VisualStudio2019です。2015、2017あたりのバージョンについては他の方が記事にされていますが方法としては同じだと思います。
問題となっているのはサンプルコードの中にあるGameLibというライブラリでこれを自分のVisualStudio用にビルドし直す必要があります。ビルドし直す方法は以下のサイトを参考に進めていけば大丈夫です。

log.moremorefor.net

流れとしては2012用のサンプルコードが出版社から提供されている(それでも古い)のでそれのGameLibを必要に応じてビルドし直すという形です
私のようにからのプロジェクトを作成して写経している方についてはビルドし直したライブラリを読み込んでくれるように、

するのを忘れないでください。
環境変数を使って指定すればいいような感じがするのですが私の場合何故か読み込んでくれなかったので絶対パスをそのまま打ち込みました。

ランタイムライブラリの設定

もしかしたら私だけなのかもしれませんが前項で書いたことを済ませていざビルドしたところおびただしい数のエラーを吐きました。
エラーの内容はこんな感じ(違うファイルに対して同じのがたくさん出てました)
LNK2038 'RuntimeLibrary' の不一致が検出されました。値 'MTd_StaticDebug' が MDd_DynamicDebug の値 'main.obj' と一致しません。 VisualStudioのエラーにはもちろん詳しくないのでエラー文をGoogle先生にパスしたところリンクしようとしたライブラリのランタイムライブラリとプログラムがリンクしているランタイムライブラリのスペックが違うことで起こるエラーらしいです。
解決方法としてはプロジェクトのプロパティから

  • プロパティ>C/C++>コード生成>ランタイムライブラリ の項目をマルチスレッドデバッグ(/MTD)に変更

すればOKです。

おわりに

本の内容に理解ができず苦戦する前に実行環境の整備に四苦八苦していました。
写経する勉強法をしている人がわりといるイメージなんですが実際どうなんでしょう?みなさんのプログラミング勉強法を教えていただけると幸いです。
他にも自分のように本編に入る前に苦戦している人の助けになれば嬉しいです。
それでは今日はこのへんで( ー`дー´)キリッ

参考記事

log.moremorefor.net

teratail.com

docs.microsoft.com

はてなブログに戻ってきました

どうも皆さんこんばんはグッチーです

今日ははてなブログからこんにちはということでタイトルにもある通りブログをはてなブログに戻そうかと思います。
理由は割と単純で技術関連の投稿がしやすい点にあります。
はてなブログmarkdown形式で記事がかけるのでソースコード載せたりするのが楽なんですよねwww
ポートフォリオサイトを兼ねてAmebaOwndの方へ移動したんですが、ブログを書くのであればこちらのほうが使い勝手がいいのでブログはこちらに書いて制作物はAmebaOwndに載せるといった形にしようかなと思います。
前の記事は全部消してしまったので一覧が寂しい状態ですがこれから増やしていきたいですね
ぶっちゃけた話ここ最近記事は書いてないし制作物も投稿できていないわけなんですが…(卒論が忙しいのです…)
これからは1エンジニアの雑多な記事置き場がこちらでなにか趣味で作ったら紹介を向こうのサイトに載せてってできたらと思います。
知り合いの人からアウトプットは増やしたほうが自分のためになると教わったので可能な限り記事の投稿をしていきたいなと思う所存でございます。
てなわけで今回はここまで次の記事でお会いしましょう( ー`дー´)キリッ