게임 상태를 어떻게 저장합니까?


27

게임 상태를 저장하고 다시 시작하기위한 게임 프로그래머의 절차는 무엇입니까? 파일 / 매핑과 같은 타워 방어 게임을 위해 저장하고 unity3D 게임 엔진을 사용하고 있습니다.

답변:


16

나는 일반적으로 메모리 스냅 샷의 관점에서 생각하지 않지만 세션간에 저장해야 할 값의 목록을 만들고 해당 값을 외부 파일에 저장합니다.

이것은 물론 특정 게임의 요구에 달려 있지만 일반적으로 나는 현재 레벨의 상태 (예 : 모든 적의 위치, 건강 상태 등)를 저장 한 다음 플레이어의 레벨과 같은 상위 레벨 항목을 저장합니다 이미 완료되었습니다.


3
+1 그게 내가하는 방법입니다. 필요한 것을 바이너리 파일에 씁니다. 그리고 새로운 것을 추가 해야하는 경우 끝에 저장하여 오래된 저장 파일을 손상시키지 않습니다.
— chaosTechnician

데이터를 저장하는 방법과 관련이 없지만 데이터를 끝에 추가하는 것은 오래된 저장 파일을 손상시키지 않는 좋은 팁입니다. 사전을 직렬화 / 역 직렬화하여 수행하며 순서는 해당 데이터 구조와 관련이 없습니다.
— jhocking

(기본적으로, 내 객체 사전을 존재와 조나스 '대답 코드)
— jhocking

10

이 답변은 Unity3d 전용 입니다.
Unity에서 대부분의 클래스는 직렬화 가능하므로 완전한 Unity 객체를 디스크로 스트리밍 할 수 있습니다. 다음 UnityScript 코드는 오브젝트를 직렬화하고 디스크에 저장하여 다시로드합니다 (로드 후 오브젝트를 캐스트해야 함).

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를 사용하고 싶을 것입니다. 그들은 크로스 플랫폼이므로 Web / iOS / Android에서 IO를 수행 할 수 없습니다. unity3d.com/support/documentation/ScriptReference/… (좋은 샘플이지만!)
— TJHeuvel

PlayerPrefs는 유연성이 떨어지고, 실제로 크로스 플랫폼이며 단일 또는 관련없는 값을 저장하기에 완벽합니다. 그러나 Windows PlayerPrefs는 레지스트리에 일반 텍스트로 저장됩니다.
— jonas

7
이미 직렬화하고 있다면 String으로 직렬화하여 PlayerPrefs에 저장하지 마십시오. 물론 유연성은 떨어지지 만 크로스 플랫폼 게임을위한 유일한 솔루션입니다.
— TJHeuvel

2
PlayerPrefs는 설정과 같은 작은 데이터를 저장하는 데 유용
— jhocking

2
@TJHeuvel : "웹 / iOS / Android에서 IO를 수행 할 수 없습니다"모바일에서 IO를 수행 할 수있는 가장 확실한 방법
— Przemysław Wrzesiński

2

TD의 경우 아마도 파도 사이에 독점적으로 저장할 것입니다. 그렇게하면 타워 만 생각하면됩니다. 자동 저장 포인트를 레벨에 10 분 이내로 설정하십시오.

물론 레벨이 충분하지 않으면 캠페인 상태 만 저장하면됩니다.


1

게임의 현재 상태를 참조 할 때 저장하는 순간 메모리 스냅 샷을 참조합니다. HDD에 저장하려는 데이터에서 다시 만들 수 있어야합니다.

지속적이어야하는 데이터가있는 모든 클래스를 직렬화하고 HDD에 덤프하여 메모리 덤프를 수행하는 것이 가장 쉬운 방법입니다. 문제는 클래스를 변경하면 직렬화 된 값의 수 / 유형이 변경되고 이전 저장이 중단된다는 것입니다. 또한 모든 것을 저장하기 때문에 로딩 시간이 길어집니다. 시리얼 라이저 / IDE가 사용하는 속성 시스템을 사용하여 현재 "메모리 스냅 샷"을 다시 작성하는 데 실제로 필요한 개별 필드를 표시하는 것이 더 효율적입니다. 그런 다음 저장된 데이터에서 "메모리 스냅 샷"을 다시 작성하십시오.

또한 Unity를 사용해 본 적이 없으므로 내장 된 것이있을 수 있습니다. 그러나 이것이 일반적인 접근 방식입니다.


u 상태를 파일에 저장해야한다는 의미입니까?
— Syed

1
@Syed 예, 하루가 끝나면 앱 상태가 메모리에 저장되지 않기 때문에 일종의 파일에 작성해야합니다. Unity를 사용하면 전체 파일 읽기 / 쓰기를 피하려면 PlayerPrefs 클래스 (실제로는 Windows의 레지스트리에 항목을 저장한다고 생각합니다)를 사용할 수 있습니다.
— Tetrad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.