คุณจะบันทึกสถานะเกมได้อย่างไร


27

ขั้นตอนตามมาโดยโปรแกรมเมอร์เกมสำหรับการบันทึกและกลับสู่สถานะของเกมคืออะไร? ชอบไฟล์ / การแมป ฉันต้องการบันทึกไว้สำหรับเกมป้องกันหอคอยและฉันใช้เอ็นจิ้นเกม unity3D

คำตอบ:


16

โดยทั่วไปฉันไม่คิดในแง่ของภาพรวมหน่วยความจำ แต่ฉันเพียงแค่ทำรายการของค่าที่ต้องได้รับการบันทึกระหว่างเซสชันและบันทึกค่าเหล่านั้นลงในไฟล์ภายนอก

ขึ้นอยู่กับความต้องการของเกมของคุณแน่นอน แต่โดยปกติฉันจะบันทึกสถานะของระดับปัจจุบัน (เช่นที่ศัตรูทั้งหมดอยู่ที่ใดสุขภาพของพวกเขาคืออะไร) แล้วระดับที่สูงกว่าจะเหมือนกับระดับผู้เล่น เสร็จสิ้นแล้ว


3
+1 นั่นคือวิธีที่ฉันทำ ฉันเขียนสิ่งที่ฉันต้องการลงในไฟล์ไบนารี และถ้าฉันต้องการเพิ่มสิ่งใหม่ ๆ ฉันจะเพิ่มเข้าไปท้ายเพื่อไม่ให้ไฟล์บันทึกเก่าแตก
chaosTechnician

นั่นเป็นเคล็ดลับที่ดีเกี่ยวกับการไม่ทำลายไฟล์บันทึกเก่าแม้ว่าการเพิ่มข้อมูลไปยังจุดสิ้นสุดนั้นไม่เกี่ยวข้องกับวิธีที่ฉันบันทึกข้อมูล ฉันทำได้โดยการทำให้เป็นอันดับ / deserializing พจนานุกรมและลำดับนั้นไม่เกี่ยวข้องในโครงสร้างข้อมูลนั้น
jhocking

(โดยพื้นฐานแล้วโค้ดในคำตอบของ jonas โดยที่ Object ของฉันเป็นพจนานุกรม)
jhocking

10

คำตอบนี้เป็น Unity3d ที่เฉพาะเจาะจง
ใน Unity คลาสส่วนใหญ่เป็นแบบอนุกรมซึ่งหมายความว่าคุณสามารถสตรีมวัตถุ Unity ที่สมบูรณ์ไปยังดิสก์ได้ follwing UnityScript-Code เป็นวิธีการทำให้เป็นอันดับวัตถุ, บันทึกลงดิสก์โหลดอีกครั้ง (หลังจากโหลดคุณต้องโยนวัตถุ):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}

2
นอกจากใช้ C # แล้วคุณยังต้องการใช้ PlayerPrefs พวกเขาเป็นแพลตฟอร์มข้ามคุณไม่สามารถทำ IO บนเว็บ / iOS / Android unity3d.com/support/documentation/ScriptReference/… (มีตัวอย่างที่ดี!)
TJHeuvel

PlayerPrefs มีความยืดหยุ่นน้อยกว่าพวกเขาเป็นแพลตฟอร์มข้ามแน่นอนและพวกเขาสมบูรณ์แบบในการจัดเก็บค่าเดียวหรือไม่เกี่ยวข้อง แต่ใน Windows PlayerPrefs จะถูกเก็บไว้ในรีจิสเตอร์ธรรมดา
jonas

7
หากคุณเป็นอนุกรมแล้วทำไมไม่อนุกรมเป็นสตริงและเก็บไว้ใน PlayerPrefs แน่นอนว่ามันมีความยืดหยุ่นน้อยกว่า แต่มันก็เป็นทางออกเดียวสำหรับเกม crossplatform
TJHeuvel

2
PlayerPrefs เหมาะอย่างยิ่งสำหรับการจัดเก็บข้อมูลขนาดเล็กเช่นการตั้งค่า แต่สำหรับ savegames ทั้งหมดคุณควรใช้ Application.persistentDataPath docs.unity3d.com/ScriptReference/…
jhocking

2
@TJHeuvel: "คุณไม่สามารถทำ IO บนเว็บ / iOS / Android" แน่นอนที่สุดคุณสามารถทำ IO บนมือถือ
PrzemysławWrzesiński

2

สำหรับ TD ฉันอาจจะประหยัดเฉพาะระหว่างคลื่น วิธีที่คุณจะต้องคิดก็คือหอคอย ใส่จุดบันทึกอัตโนมัติบางอย่างไว้ในระดับไม่เกิน 10 นาที แต่น่าจะน้อยกว่า

แน่นอนว่าถ้าระดับของคุณสั้นพอคุณก็ไม่สามารถบันทึกอะไรได้นอกจากสถานะของแคมเปญ


1

เมื่อฉันอ้างถึงสถานะปัจจุบันของเกมฉันหมายถึงภาพรวมหน่วยความจำในขณะที่บันทึก คุณต้องสามารถสร้างข้อมูลนั้นจากข้อมูลที่คุณจะเก็บไว้ใน HDD ได้

มันเป็นวิธีที่ง่ายที่สุดเพียงแค่จัดลำดับคลาสของคุณทั้งหมดที่มีข้อมูลที่ต้องคงอยู่และถ่ายโอนข้อมูลไปยัง HDD โดยจะทำการถ่ายโอนข้อมูลหน่วยความจำ ปัญหาเกี่ยวกับสิ่งนี้คือการแก้ไขคลาสของคุณจะเปลี่ยนจำนวน / ประเภทของค่าที่เป็นอนุกรมและแบ่งการบันทึกเก่า นอกจากนี้เนื่องจากคุณบันทึกทุกอย่างมันจะเพิ่มเวลาในการโหลด มันมีประสิทธิภาพมากกว่าในการทำเครื่องหมายฟิลด์แต่ละฟิลด์ที่จำเป็นต้องใช้เพื่อสร้าง "สแนปช็อตหน่วยความจำ" ปัจจุบันด้วยระบบแอตทริบิวต์อะไรก็ตามที่ serializer / IDE ของคุณใช้ จากนั้นสร้าง "ภาพรวมหน่วยความจำ" จากข้อมูลที่บันทึกไว้

นอกจากนี้ฉันไม่เคยใช้ Unity มาก่อนดังนั้นอาจมีบางอย่างในตัวอย่างไรก็ตามนี่เป็นวิธีการทั่วไป


คุณหมายถึงฉันต้องเก็บสถานะของฉันในไฟล์?
Syed

1
@Syed ใช่ในตอนท้ายของวันจะต้องมีการเขียนลงในไฟล์บางชนิดเนื่องจากสถานะแอปจะไม่ถูกบันทึกในหน่วยความจำ ด้วย Unity โดยเฉพาะคุณสามารถใช้คลาส PlayerPrefs (ซึ่งฉันคิดว่าจริง ๆ แล้วเก็บสิ่งต่าง ๆ ในรีจิสทรีบน Windows) หากคุณต้องการหลีกเลี่ยงการอ่าน / เขียนไฟล์ทั้งหมด
Tetrad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.