2014년 1월 28일 화요일

unity3D, 다른 방법으로 저장하기

유니티 오브젝트로 저장하는 방법이 있는데요.

이 방법은 생각보다 많이 까다로울 수 있기때문에 오브젝트가 갖는 값을 유추해 볼 수 있는 클래스를 새로 생성한 후 이 클래스의 값을 저장하는 방법을 사용합니다. 

예를 들어, RPC 호출을 통해서 여러개의 AnimationStates를 전달하고자 할때, AnimationStates를 대신할 수 있는 클래스를 만들고 이 값을 전달하는 것이죠.

아래의 예제는 어떤 클래스라도 문자열로 변환할 수 있게 해주는 방법을 보여줍니다. 
이것을 이용해서 모든 파라미터 값을 RPC를 통해 보낼 수 있습니다. 
==============================================================================

using UnityEngine;
using System.Collections;
using System.Collections.Generic;   // 리스트를 쓰기 위해 추가합니다.

// BinaryFormatter를 사용하기 위해서는 반드시 아래의 네임스페이스를 추가해줘야 해요.
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class csTest : MonoBehaviour 
{
    // 이렇게 클래스를 만들고
    [Serializable]           // 저장하기 위해서 있어야 합니다.
    public class ScoreEntry
    {
        public string name;
        public int score;
    }

    // 만든 클래스를 리스트에 담아서 관리하면 마치 테이블처럼 사용할 수 있습니다. 
    public List<ScoreEntry> highScore = new List<ScoreEntry>();

    [RPC]
    void ReceiveHighScores(byte[] highScores)
    {
        var binaryFormatter     = new BinaryFormatter();
        var memoryStream        = new MemoryStream(highScores);

        // 받은 데이터를 바이트 배열로 변환합니다.
        var otherPlayerScores   = (List<ScoreEntry>)binaryFormatter.Deserialize(memoryStream);
    }

    void UpdateScores(byte[] highScores)
    {
        var binaryFormatter     = new BinaryFormatter();
        var memoryStream        = new MemoryStream();

        // highScores를 바이트 배열로 변환해서 저장합니다.
        binaryFormatter.Serialize(memoryStream, highScores);

        // 그리고 다른 유저에게 전달해주는거죠.
        networkView.RPC("ReceiveHighScores", RPCMode.Others, memoryStream.GetBuffer());
    }
}

==============================================================================
RPC 역시 바이트 배열을 보낼 수 있습니다. 
이 값은 BinaryFormatter를 이용해서 우리가 원하는 값으로 바로 변환할 수 있도록 도와줍니다. 
문자열로부터 변환하는 시간을 줄일 수 있어서  더 좋다고 할 수 있습니다.  

웹으로 전달할때는 WWWForm을 이용합니다. 

또는 Convert.ToBase64String()을 이용해서 할 수도 있습니다.
사용하는 서버에 따라 적절하게 하면 될 것 같네요.

파일로 저장하는 법은 Application.persistentDataPath를 이용해서 하되, MemoryStream 대신 FileStream을 사용하면 됩니다. 
==============================================================================

using UnityEngine;
using System.Collections;
using System.Collections.Generic;   // 리스트를 쓰기 위해 추가합니다.

// BinaryFormatter를 사용하기 위해서는 반드시 아래의 네임스페이스를 추가해줘야 해요.
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class csTest : MonoBehaviour 
{
    // 이렇게 클래스를 만들고
    [Serializable]           // 저장하기 위해서 있어야 합니다.
    public class ScoreEntry
    {
        public string name;
        public int score;
    }

    // 만든 클래스를 리스트에 담아서 관리하면 마치 테이블처럼 사용할 수 있습니다. 
    public List<ScoreEntry> highScore = new List<ScoreEntry>();

    void SaveScores()
    {
        var binaryFomatter  = new BinaryFormatter();

        // 저장할 파일의 위치를 정해주고 만들어줍시다.
        var fileStream      = File.Create(Application.persistentDataPath + "/highScores.dat");

        binaryFomatter.Serialize(fileStream, highScore);

        // 작업이 끝나면 닫아주는 것을 잊지 마세요
        fileStream.Close();
    }

    void Start()
    {
        // 시작할때 저장한 파일을 불러옵니다.

        // 데이터가 비어있지 않다면
        if (File.Exists(Application.persistentDataPath + "/highScores.dat"))
        {
            var binaryFormatter     = new BinaryFormatter();

            // 불러올 파일 경로와 이름이 틀리지 않도록 주의하시구요.
            var fileStream          = File.Open(Application.persistentDataPath + "/highScores.dat", FileMode.Open);

            highScore       = (List<ScoreEntry>)binaryFormatter.Deserialize(fileStream);

            // 작업이 끝나면 닫아주는 것을 잊지 마세요
            fileStream.Close();
        }
    }
}

==============================================================================







댓글 없음:

댓글 쓰기