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


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.