【UE4】SaveとLoad時のUserIndexについて
はじめに
時々SaveとLoadに苦戦するのでよくお世話になっているほげたつさんのサイトです。
ここには
セーブデータにはスロット名とユーザーインデックスが指定できます。 スロット名はセーブデータの名前、ユーザーインデックスはその中でのIDみたいなものですね。 ドラクエの冒険の書1とか冒険の書2とかそんなイメージです。
とあります。
もちろんこちらにも。
For some platforms, master user index to identify the user doing the saving.
ただ実際に実装してみると、なにやら動作がおかしいので調べてみました。
ソースコード
ということで、Engineのソースコードを追います。UE4.13です。 ctrl+FとかでUserIndexをハイライトしておくと、見やすいかもしれません。
Runtime/Engine/Private/GameplayStatics.cpp
USaveGame* UGameplayStatics::LoadGameFromSlot(const FString& SlotName, const int32 UserIndex) { USaveGame* OutSaveGameObject = NULL; ISaveGameSystem* SaveSystem = IPlatformFeaturesModule::Get().GetSaveGameSystem(); // If we have a save system and a valid name.. if(SaveSystem && (SlotName.Len() > 0)) { // Load raw data from slot TArray<uint8> ObjectBytes; bool bSuccess = SaveSystem->LoadGame(false, *SlotName, UserIndex, ObjectBytes); if(bSuccess) { (省略)
bool UGameplayStatics::SaveGameToSlot(USaveGame* SaveGameObject, const FString& SlotName, const int32 UserIndex) { ISaveGameSystem* SaveSystem = IPlatformFeaturesModule::Get().GetSaveGameSystem(); // If we have a system and an object to save and a save name... if(SaveSystem && SaveGameObject && (SlotName.Len() > 0)) { (省略) // Stuff that data into the save system with the desired file name return SaveSystem->SaveGame(false, *SlotName, UserIndex, ObjectBytes); } return false; }
とSaveもLoadもUserIndexに関わる処理はSaveGame、LoadGameを呼び出しているのでそちらへ。
Runtime/Engine/Public/SaveGameSystem.h
virtual bool SaveGame(bool bAttemptToUseUI, const TCHAR* Name, const int32 UserIndex, const TArray<uint8>& Data) override { #if PLATFORM_HTML5_BROWSER return UE_SaveGame(TCHAR_TO_ANSI(Name),UserIndex,(char*)Data.GetData(),Data.Num()); #elif PLATFORM_HTML5_WIN32 FILE *fp; fp=fopen("c:\\test.sav", "wb"); fwrite((char*)Data.GetData(), sizeof(char), Data.Num(), fp); fclose(fp); return true; #else return FFileHelper::SaveArrayToFile(Data, *GetSaveGamePath(Name)); #endif }
virtual bool LoadGame(bool bAttemptToUseUI, const TCHAR* Name, const int32 UserIndex, TArray<uint8>& Data) override { #if PLATFORM_HTML5_BROWSER char* OutData; int Size; bool Result = UE_LoadGame(TCHAR_TO_ANSI(Name),UserIndex,&OutData,&Size); if (!Result) return false; Data.Append((uint8*)OutData,Size); ::free (OutData); return true; #elif PLATFORM_HTML5_WIN32 FILE *fp; fp=fopen("c:\\test.sav","rb"); if (!fp) return false; // obtain file size: fseek (fp, 0 , SEEK_END); int size = ftell (fp); fseek (fp, 0 , SEEK_SET); Data.AddUninitialized(size); int result = fread (Data.GetData(),1,size,fp); fclose(fp); return true; #else return FFileHelper::LoadFileToArray(Data, *GetSaveGamePath(Name)); #endif }
えーっとPlatformがHTML5のブラウザだけUserIndexを使っているように思います。
そしてこのUE_SaveGameとUE_LoadGameはこちらに。
Runtime/HTML5/HTML5JS/Private/HTML5JavaScriptFx.js
UE_SaveGame: function (name, userIndex, indata, insize) { // user index is not used. var _name = Pointer_stringify(name); var gamedata = Module.HEAPU8.subarray(indata, indata + insize); // local storage only takes strings, we need to convert string to base64 before storing. var b64encoded = base64EncArr(gamedata); $.jStorage.set(_name, b64encoded); return true; }, UE_LoadGame: function (name, userIndex, outdataptr, outsizeptr) { var _name = Pointer_stringify(name); // local storage only takes strings, we need to convert string to base64 before storing. var b64encoded = $.jStorage.get(_name); if (b64encoded === null) return false; var decodedArray = base64DecToArr(b64encoded); // copy back the decoded array. var outdata = Module._malloc(decodedArray.length); // view the allocated data as a HEAP8. var dest = Module.HEAPU8.subarray(outdata, outdata + decodedArray.length); // copy back. for (var i = 0; i < decodedArray.length; ++i) { dest[i] = decodedArray[i]; } Module.HEAP32[outsizeptr >> 2] = decodedArray.length; Module.HEAP32[outdataptr >> 2] = outdata; return true; },
いやあのこれ、UserIndex出番なくないですか…(引数として呼ばれているだけで未使用)
まとめ
現状だとUserIndexは出番がないようです。ちゃんと(?)設定していないはずのUserIndexでLoadしてもエラーが出ませんでした。
Forum等も漁りましたが、良さげな解答が見つからなかったので追ってみました。
どこか間違ってたり、新たに何か分かった時にはぜひ@shop_0761までお知らせください(更新します)