ユニティでのゲームの進行状況を保存します


あなたがゲームの進行状況、ユーザー設定、またはゲームプレイ中に変更されたオブジェクトを保存したいときはいつでも、あなたの貯蓄制度について考える必要があります。 PlayerPrefsとシリアル化:このチュートリアルでは、私はユニティで物事を保存するには、2つの最も一般的な方法を説明しようとします。

ソースコードを使用したプロジェクトは、Githubの上で見つけることができます

 


PlayerPrefs
この方法は、Androidプラットフォームの「共有設定」に触発されました。非常に使いやすいですが、あなたにも非常に限られています。あなたが保存することが許可されている唯一の種類は次のとおりです (float, int, string)。
使用法は次のようになります。

私はあなたにそれをよりパフォーマンスすることができます、1トリックをお見せしましょう。

列挙型のフラグ
それでは、あなたのレベルで、プレーヤーはいくつかのアイテムを収集することになっていることを想像してみましょう。 ItemTypeは、このコレクターアイテムのタイプを定義する列挙型になります。

あなたはおそらく気づいたように、列挙型のすべての位置に整数値を割り当てた、それはあなたがそれからバイナリ値を取得する場合、あなたが取得する今、常に2の累乗です。

Decimal Binary
1 0000 0001
2 0000 0010
4 0000 0100
8 0000 1000
16 0001 0000
32 0010 0000
64 0100 0000
128 1000 0000

これは、単に整数の連続するビットのブール値を平らに設定されています。
あなたがC言語で#整数は32ビット長(符号1ビット)であることを知っている場合は、最下位ビットが1であり、最上位ビットは1073741824です。それはあなただけの1つの整数を使用して、31要素を格納できることを意味します!

では、あなたのコレクションに項目を追加するメソッドを書いてみましょう。


シリアライゼーション

シリアル化オブジェクトを格納するか、メモリ、データベース、またはファイルにそれを送信するためにバイトストリームにオブジェクトを変換するプロセスです。その主な目的は、必要なときにそれを再作成できるようにするためにオブジェクトの状態を保存することです。逆のプロセスをデシリアライズといいます。

C#で使用可能なシリアル化は3種類があります。
– バイナリ
– XML
– JSON

私は、次のクラスといくつかのテストをしました。

これら2種類の違いです

JSON serialization output

これは JSON ファイルであります

 

XML serialization output

これは XML ファイルであります


性能試験

私は、次のクラスといくつかのテストをしました。

それぞれの読み取り/書き込みのための時間を確認するためにSystem.Diagnostics.Stopwatchを使用しています。10、1000、100 000, 1 000 000オブジェクトのリストを作成し、それをシリアル化してファイルに保存しました。オブジェクトの膨大な量のバイナリシリアル化は非常に遅かったです。あなたは、以下の比較を見ることができます。

10の要素 XML バイナリ JSON
サイズ 1,274 bytes 805 bytes 462 bytes
ライト 13 ms 24 ms 2 ms
ロード 4 ms 8 ms 0.4 ms

 

1000の要素 XML バイナリ JSON
サイズ 113 KB 32 KB 51 KB
ライト 36 ms 27 ms 4 ms
ロード 4 ms 17 ms 2 ms

 

100 000の要素 XML バイナリ JSON
サイズ 11.9 MB 4 MB 5.7 MB
ライト 2016 ms 591 ms 277 ms
ロード 3986 ms 50 518 ms 297 ms

 

1 000 000の要素 XML バイナリ JSON
サイズ 121.7 MB 40 MB 59 MB
ライト 18 964 ms 7 827 ms 3 399 ms
ロード 38 152 ms 長過ぎます 3 090 ms

あなたが見ることができるようにJSONは、最速の読み取り/書き込み時間を持っています。バイナリは、最小のファイルサイズだけでなく、最長の読み取り時間を持っていました。

それはユニティで使用できない価値が言及シリアル化技術にもですが、あなたは、いくつかの追加のライブラリを含むことによって、それらを使用することができます。FlatBuffers ProtoBuffers


どうもありがとう!私はあなたが私のチュートリアルを楽しんだことを望みます。ご質問があれば、以下のコメントを残してください ^_^

Share:

2 Comments

Add yours
  1. 1
    FWCorey

    BinaryFormatter is not really an ideal method for binary serialization. Custom binary serialization where each stored class has a GetBytes() method and a public MyClass(byte[] bytes) constructor can outperform all of these by orders of magnitude with extremely small file sizes. It’s a more advanced technique and requires a bit more planning, but it has the advantage of providing data that can be used with any C# Stream.

    In one project I’ve worked on a scene with 12000 logical tiles, that each had several attribute components and 8000 objects, also with varied attributes, placed on those tiles was serialized and uploaded to a server in less than 300ms or downloaded and deserialized in less than 600ms.

    Maybe expand the article to include a brief overview and tips for new programmers trying their hand at those techniques. They are no harder than using PlayerPrefs after all and only limited for a newbie to the types supported by BitConverter.

  2. 2
    Vasyl

    Thank you very much for this great atricle! I walked through this when I was creating save system for my current project. I wish I read it before 🙂 But I want to notice that you have a little of redundant code in here. You shouldn’t call Close() and Dispose() methods manually. At the end of the using block the Dispose method is automatically called which will take care to free unmanaged resources. As for the Close() method it calls Dispose().

+ Leave a Comment