自作アセットインポートの備忘録
音ゲー作りたいけどcsvで管理するといろいろ面倒だったのがきっかけで作ってみた。
①
独自アセットクラスの実装
今回は.txtファイルを読み込みたいのでFString1つだけで良さそう。独自の形式を作りたいときはそれ用に色々変数を作ると良いと思います。
以下のコードを書いた。
.cpp
#include "UTextObject.h" UTextObject::UTextObject(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { }
.h
#pragma once #include "UTextObject.generated.h" UCLASS() class UTextObject : public UObject { GENERATED_UCLASS_BODY() private: public: UPROPERTY(EditAnywhere) FString textData; };
この時問題になったのが、generated.hがなくてインクルードで怒られるところ。
実際何で解決したのか正確にはわかっていない。
詳しくはまだわかってないので調べてます。
知っている方がいたらtwitterでこっそり教えてください。
GenerateVisualStudioFileをしたら良いっぽい?
次にFactoryクラスを実装。コレはアセットを作成できるようにしたり、インポートしたりをできるようにする感じで作ります。
.cpp
#include "UTextObjectFactory.h" #include "UTextObject.h" UTextObjectFactory::UTextObjectFactory(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { SupportedClass = UTextObject::StaticClass(); bCreateNew = false; bEditorImport = true; bText = true; Formats.Add(TEXT("txt;TextFile")); } bool UTextObjectFactory::DoesSupportClass(UClass* Class) { return (Class == UTextObject::StaticClass()); } UClass* UTextObjectFactory::ResolveSupportedClass() { return UTextObject::StaticClass(); } UObject* UTextObjectFactory::FactoryCreateNew( UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) { UTextObject* NewMyAsset = CastChecked<UTextObject>(StaticConstructObject_Internal(InClass, InParent, InName, Flags)); return NewMyAsset; }
.h
#pragma once #include "Factories/Factory.h" #include "UTextObjectFactory.generated.h" UCLASS() class UTextObjectFactory : public UFactory { GENERATED_UCLASS_BODY() virtual bool DoesSupportClass(UClass* Class) override; virtual UClass* ResolveSupportedClass() override; virtual UObject* FactoryCreateNew( UClass* _Class, UObject* _Parent, FName _Name, EObjectFlags _Flag, UObject* _Context, FFeedbackContext* _Warn) override; };
ここまでできたら一旦ビルドして確認。新規作成>その他からTextObjectが作れるようになっているはず。
もしコレをインポートのみにしたい場合はbCreatenewをfalseにすると良い。
Formatsはファイル拡張子;説明と言った感じ。
bText = trueはテキストファイルからのインポートを指定している。コレをtrueにしていない場合は
以下でFactoryCreateText()を実装しているが、そのかわりにFactoryCreateBinary()を実装する必要がある。
Factoryクラスに以下を追加
UObject* UTextObjectFactory::FactoryCreateText( UClass* _Class, UObject* _Parent, FName _Name, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BuferEnd, FFeedbackContext* Warn) { FString Values; Values = FString(Buffer); UTextObject* NewMyAsset = CastChecked<UTextObject>(StaticConstructObject_Internal(_Class, _Parent, _Name, Flags)); NewMyAsset->textData = Values; return NewMyAsset; }
ここまで作ると、ひとまずtxtファイルがインポートできるはず。
次回はReimportについて書こうかな。
第3回UE4勉強会in大阪
参加してきました。というよりも、現在勤めている会社が主催でした。
今回はたいらも勉強会で「UE4でVR入門」という内容でしゃべらせてもらいました。
いかがそのスライドになります(なんかyoutube対応したら挿入される場所がいろいろおかしいくなってしまった)
たいらの講演は、というよりも全講演なかなかいい感じの反応をもらえており、とても安心しました。
今回で弊社から登壇者が出たということで、今後もこの勉強会を開く意義?というものを感じられますね!(棒)
またツイートの方で、スライド中に出てくる参考資料などのurlを公開していますので、こちらにもはっつけておきます。
スライド中のリンク集です①
— 平良 (@DJ_HIRAYOSI) 2017年11月26日
Twitterhttps://t.co/drpvm56qQt
1日分の備忘録https://t.co/lQlIFVb5fb
FOVE届いたのでいじってみた|Qiitahttps://t.co/rrDtYX6i9N
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)https://t.co/i9Q13KZlgJ#UE4Osaka
スライド中のリンク集です②
— 平良 (@DJ_HIRAYOSI) 2017年11月26日
GPUプロファイリングhttps://t.co/6V5zSpTHFp
プロファイラツールhttps://t.co/yMY5LxEnJi
追加資料https://t.co/lTk09puuAH
アンケートhttps://t.co/SW83yMjcfW #UE4Osaka
実は今日から東京出張に来ているので、今年の更新はもしかするとこれで最後になるかもしれません。あとVR触れない。つらい。
Twitterの方はたぶん2~3日おきくらいに更新すると思います。もしかするともう少し頻度は高いかもしれません。
ということで、簡単にですが第3回UE4勉強会in大阪の報告でした。
第4回は1月予定です。次回話すかどうかといわれるとおそらく平良は話しませんが、話すネタはいろいろ考えておきたいなぁと思います。
ぷちコンの参加賞が届きました。
しかもラッキー賞当たっちゃいました。
UE4で指定フォルダからファイルの読み込み(CSV編)
作っちゃったし備忘録書く必要あるかなとも思ったがとりあえず書いとく。CSV編としているが他のファイル形式を読み込んだものを書くかと言われると多分書かない。
.h
public: UFUNCTION(BlueprintCallable, Category = "CSVReader") void LoadCSVData(FString Filename); UFUNCTION(BlueprintCallable, Category = "CSVReader") TArray<FString> GetRowDataByKey(FString Key); UFUNCTION(BlueprintCallable, Category = "CSVReader") TArray<FString> GetKey(); public: //変数 TMap<FString, TArray<FString>> RowData; TArray<FString> KeyList;
.cpp
void ACSVReader::LoadCSVData(FString Filename) { //CurrentDirectory取得 FString dir = FPaths::GameDir(); //ファイル名 FString filename = dir + Filename + ".csv"; //ファイル取得 FString csvFullData; FFileHelper::LoadFileToString(csvFullData, *filename); //列で分解 TArray<FString> row; csvFullData.ParseIntoArray(row, TEXT("\n"), true); //キーを登録 row[0].ParseIntoArray(KeyList, TEXT(","), true); for(int i = 0 ; i != KeyList.Num() ; i++) { RowData.Add(KeyList[i]); } //キー以外の各要素をRowDataにキーと関連付けて登録 TArray<FString> element; for (int i = 1; i != row.Num(); i++) { row[i].ParseIntoArray(element, TEXT(","), true); for (int j = 0; j != element.Num(); j++) { RowData[KeyList[j]].Add(element[j]); } } } TArray<FString> ACSVReader::GetRowDataByKey(FString Key) { return RowData[Key]; } TArray<FString> ACSVReader::GetKey() { return KeyList; }
どうやらFPaths::GameDir();でCurrentDirectoryが取得できるらしい。(ここだけ伝えたかった)
パッケージ化前は[各種ドライブ://~~~/MyProject/]
パッケージ化後は[各種ドライブ://~~~/exeファイルのある階層/MyProject/]
を取得する。
ちなみにブログ用に若干プログラムコードはサボってるので実装するときは各自ちゃんと作ってください。
使いみちあるかと言われると微妙になさそう。ユーザーに配布したゲームでCSV作ったらステージ自分で作れます!的な感じにしたらもしかするともしかするかもしれない。
UnityのProjectでDLLを使う備忘録
VisualStudio2015を開く
VisualC++ -> Win32コンソールアプリケーションを作成
Win32アプリケーションウィザードが開いたら次へ
アプリケーションの種類:DLL
追加のオプション:空のプロジェクトをonにして完了
.cppと.hを作る。
source.h
#pragma once #define CPULUSSOURCE_API __declspec(dllimport) extern "C"//Unityで使うため { CPULUSSOURCE_API float DllMultiPly(float a, float b, int loopNum = 100000000); }
source.cpp
#include "CPlusSource.h" float DllMultiPly(float a, float b, int loopNum) { for (int i = 0; i < loopNum; i++) { float p = a * b; } return a * b; }
ものすごい重い計算処理(仮)
ビルド前にソリューションプラットフォームをx64に変更。
ビルドしたらプロジェクトフォルダ内のx64内にDLLができている。
できたDLLをUnityProject/Assets/Plugins内に入れてUnity起動。
Scriptを作成しこんな感じで書く
script.cs
public class DllTestScript : MonoBehaviour { [DllImport("DLLTest", EntryPoint = "DllMultiply")]//今回作ったdll public static extern float CPlusOnlyDllMultiplyt( float a, float b, int loopNum = 100000000); void Start () { float tempFloatData = 0; //C++ ProcessLoadTimeStart(); tempFloatData = CPlusOnlyDllMultiplyt(8, 8); ProcessLoadTimeEnd(); Debug.Log(tempFloatData); //C# ProcessLoadTimeStart(); tempFloatData = TestCSharpLibrary.TestCSharpLibrary.SharpMultiply(100000000, 3, 5);//別で用意していたC#dllを使用 //for(int i = 0 ; i < 100000000 ; i++) //{ // float p = 3 * 5; //} //ない場合はこれを関数化して使用 ProcessLoadTimeEnd(); Debug.Log(tempFloatData); } private float CheckTimer = 0; void ProcessLoadTimeStart() { // 現在の経過時間を取得 CheckTimer = Time.realtimeSinceStartup; } void ProcessLoadTimeEnd() { // 処理完了後の経過時間から、保存していた経過時間を引く=処理時間 CheckTimer = Time.realtimeSinceStartup - CheckTimer; Debug.Log("ProcessLoadTime : " + CheckTimer.ToString("0.00000")); } // Update is called once per frame void Update () { } }
Emptyを作ってScriptをアタッチして実行。
割りと苦戦したが1回できてしまえば後はあっさりできた。
プロパティ指定子の備忘録
プロパティ指定子使いそうなものについてまとめ
UPROPERTY()で設定できるもののこと
AdvancedDisplay
Detalis(詳細)パネルの拡張ドロップダウンリストに表示される。
AssetRegistrySearchable
メンバー変数として格納するアセットクラスインスタンスからこのプロパティと値が自動でアセットレジストリに追加される。
構造体やパラメータの使用は厳禁
難しく言ってるけど要するに検索できるようにする。
BlueprintAssignable
マルチキャストデリゲートのみ使用可能。ブループリントへ割り当てるためにプロパティを公開する。
BlueprintCallable
マルチキャストデリゲートのみ使用可能。ブループリントのグラフでの呼び出しのために公開するプロパティです。
BlueprintReadOnly
プループリントでの読み取りのみ可能。
BlueprintReadWrite
ブループリントでの読み書き可能
Category
プロパティのカテゴリを指定をする。"|"を使ってネスト(入れ子)設定もできる。
UPROPERTY(Category="CategoryName|SubCategoryName")
Type VariableName;
Config
iniファイルで値を保存することができ、作成時にロードされる。編集はできない。
EditAnywhere
プロパティエディタに公開されて編集可能になる。
前記事参照oneday-memorandum.hateblo.jp
EditDefaultsOnly
プロパティウィンドウでのみ編集可能。Visible* とは互換性がない。
EditFixedSize
配列の長さの変更を制限する。
EditInline
アンリアルエディタのプロパティインスペクタ内で編集できるようになる。
EditInstanceOnly
詳細タブのみ編集可能になる。
NoClear
オブジェクト参照がNoneにならないようにする。
VisibleAnywhere
エディターでプロパティで表示する。編集は不可。
VisibleInstanceOnly
詳細タブでプロパティで表示する。編集は不可。
多分こんなもん
TGSに参加してきました。
1日目
グランツーリスモSPORTS
初心者用のブレーキ、ステアリングが自動
中級者向けのブレーキ自動が嬉しかった。
真・女神転生VR
コントローラーでタブレットを持って命令を送ると行った手法。タブレットに情報を入れるとなかなか良いのではないかとおもった。
途中地震の演出があり建物が崩れるのだが、その時に画面が揺れて気持ち悪くなったが、よく観察してみると、カメラは揺れておらず、周りの建物のみ上下に揺れていると行った演出をしていた。せめてもの酔い対策ということか。確かにカメラは揺らしてない。でも吐いた。ゲロゲロ
シリコンスタジオ
運転シュミレーター
酔い対策などは見受けられなかった。開発者と話をしたところ、シュミレーターだから酔い対策はしなかったとのこと。この話を聞いて、VRのコンテンツで何から何まで酔い対策を考える必要はないのだなと思った。新たな発見
インディーズ
自分にお金があればぜひ支援したいと思うようなゲームが非常に多かった。お金欲しい。あとはスイッチが結構あった。PSVRもそこそこ展示が増えた印象。もう少し英語話せるようになりたい。今後はスイッチに流れがそこそこきそうでした。
tobii
VR視線追従周りの技術でもがあった。
制度は良いが遅延がかなり気になった。お話を聞かせていただいたが、今後の酔い対策や処理不可の面で必ず必要になるだろうとtobii開発者と共通の認識だったので安心?した(なお話ししていただいたのはtobiiマーケティング部の方)。今後の対応が待たれるが、次のVRはスタンドアロン型のHMDが来ると予想されているので先はまだ長いか・・・待ち遠しい。
学生
ある程度のスペースがある学校には大体VR作品があり。どれも学生ながら非常によくできていた。
人気コンテンツ
MHWとCODWWⅡはすごく人気。会場15分ほどで受付終了すると言ったレベル。
またVRも、HMDをかぶるだけのVRと言うのは受付中止になるほどではなかったが、専用筐体や最新のVRウェアなどを着て参加するものはすぐに受付中止になっていた。
2日目
匂いVR
VRサクラ
チョコの匂いやスイカの匂い、香水の匂いが体験できる。中々たまらない感じがでてて非常によかった。今後この技術も発展していってほしいと思います。いけないことをしている気分になりました。これ以上は言葉で表すのは非常に難しい。そのような体験でした。
ペットと遊ぶやつ
不快な匂いは割りとそれだけで気分が悪くなった。やはり五感すべてが快適な体験が行えないとVR酔いと言うものが発生するのかと思う。このコンテンツに関しては自らはその場を動かず犬とたわむれるだけといったものなのだが、本当に匂いだけで気分が悪くなった。また新しいことを感じれたので、気分は悪くなったが満足した。
seiya
VR音ゲー。ノートが音になり、ノートを拾えなかったら音はならない。パンチするときの力が得点に加算される。結構疲れるもののVRの体験としては良いものではないかなと思われる。
ボトムズ
対戦系コンテンツ。専用コントローラーで移動などを行う。ゲームが始まると対戦相手と戦うのだが、相手が誰かわからない。2戦目にしてようやくルールが理解できた。
内容自体は非常に楽しく、コックピット系VRに専用コントローラーはかなり良い体験になることを再確認。Gyroと合わせられるような技術になると良さそう。やはりVRはアトラクション系との親和性はかなり高い。
Gyro
360度超回転するVR
VR酔いよりもアトラクション酔いが強いと感じる。映像と体にかかるGが少しだけタイミングがずれている部分があり、そこで一瞬胃液がこみ上げた。映像と体にかかるGを更に正確にすることが直近の課題だろう。しかしながら映像に合わせると没入感は群を抜くものになるだろう。アトラクションとしてぜひともはやってほしい。
閃の軌跡Ⅲ
完全に趣味。特に語ることはなく、ただただ楽しみ。
------------------------------------------------------------------------------------------------------------------------------------
全体
やはりと言うかなんというか注目はMHWだろう。これに関してはビジネスデーにも関わらずどこもかしこも人で溢れていた。全体的にスマートフォンゲームブースの人はそこまで多くなく、コンシューマ系に人がかなり多く流れていっていた。これはゲームの周期が一周したと言うのはまだ早いかもしれないが、ごくごく近い未来そうなるのではないかなと思う。
とは言うもののスマホの出店数は前年とほぼ同じくらいと言った印象。
去年に比べ、アーケードゲームは前年に比べ少ない?(というか全く見なかった)
コンシューマは各ハード少し減ってスイッチが参入してきたと言った感じ。
VRに関してはPSVRがかなり減ってviveがかなり増えた。というのも、上記で上げた専用筐体などを使ったものの影響がかなり大きいのかなと思う。VRは家庭で楽しむものというよりもアトラクション的な要素として楽しませていく方向にシフトしつつあるのか、果たしてと言った感じだった。もちろん前年に比べ、家庭で遊べるゲームも増えている。
また、PCゲームが去年に比べ、少し増えていたかなという印象、中でもPUBG(PLAYER UNKNOWN BUTTLE GROUND)はいたるところで見かけた。
こういった部分を見るとesportsやSteam配信(PCゲー)の時代にも流れになりつつあるのかもしれない。