Сериализация и десериализация в единстве3d c # для словаря и GameObject [дубликат]

Вы не можете использовать глобальные переменные для хранения таких данных. Это не только безопасный поток, это не процесс безопасен, а WSGI-серверы на производстве порождают множество процессов. Мало того, что ваши подсчеты были бы неправильными, если бы вы использовали потоки для обработки запросов, они также будут меняться в зависимости от того, какой процесс обрабатывал запрос.

Используйте источник данных за пределами флажка для хранения глобальных данных. База данных, memcached или redis - все соответствующие области хранения, в зависимости от ваших потребностей. Если вам нужно загрузить и получить доступ к данным Python, рассмотрите multiprocessing.Manager . Вы также можете использовать сеанс для простых данных, предназначенных для каждого пользователя.


Сервер разработки - это единственный поток, по умолчанию один процесс. Вы не увидите поведение, которое вы описываете, поскольку каждый запрос будет обрабатываться синхронно. Включите потоки или процессы, и вы увидите это. app.run(threaded=True) или app.run(processes=10).


Некоторые серверы WSGI могут поддерживать gevent или другого асинхронного рабочего. Глобальные переменные по-прежнему не являются потокобезопасными, поскольку по-прежнему нет защиты от большинства условий гонки. У вас все еще может быть сценарий, когда один работник получает значение, дает, другой его модифицирует, дает, то первый работник также модифицирует его.

2
задан JoeyL 25 April 2016 в 22:27
поделиться

3 ответа

Aftr часов эксперимента, я пришел к выводу, что Unity не может сериализовать GameObject с BinaryFormatter. Unity утверждает, что это возможно в документации по API, но это не так.

Если вы хотите удалить эту ошибку без удаления _weapon GameObject, вы должны заменить ...

[SerializeField]
private GameObject _weapon;

с

[NonSerialized]
private GameObject _weapon;

Это позволит остальная часть вашего кода запускается без исключения исключения, но вы не можете десериализовать _weapon GameObject. Вы можете десериализовать другие поля.

ИЛИ

Вы можете сериализовать GameObject как xml. Это может привести к сериализации GameObject без каких-либо проблем. Он сохраняет данные в удобном для чтения формате. Если вы заботитесь о безопасности или не хотите, чтобы игроки изменяли баллы на своих устройствах, вы можете шифровать , преобразовать его в двоичный или Base-64 , прежде чем сохранять его на диск.

using UnityEngine;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
using System.Runtime.Serialization;
using System.Xml.Linq;
using System.Text;

public class Player_Manager : MonoBehaviour
{

    // The weapon the player has.
    public GameObject MainHandWeapon;

    void Start()
    {
        Save();
    }

    public void Save()
    {
        float test = 50;

        Debug.Log(Application.persistentDataPath);

        // Stream the file with a File Stream. (Note that File.Create() 'Creates' or 'Overwrites' a file.)
        FileStream file = File.Create(Application.persistentDataPath + "/PlayerData.dat");
        // Create a new Player_Data.
        Player_Data data = new Player_Data();
        //Save the data.
        data.weapon = MainHandWeapon;
        data.baseDamage = test;
        data.baseHealth = test;
        data.currentHealth = test;
        data.baseMana = test;
        data.currentMana = test;
        data.baseMoveSpeed = test;

        //Serialize to xml
        DataContractSerializer bf = new DataContractSerializer(data.GetType());
        MemoryStream streamer = new MemoryStream();

        //Serialize the file
        bf.WriteObject(streamer, data);
        streamer.Seek(0, SeekOrigin.Begin);

        //Save to disk
        file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);

        // Close the file to prevent any corruptions
        file.Close();

        string result = XElement.Parse(Encoding.ASCII.GetString(streamer.GetBuffer()).Replace("\0", "")).ToString();
        Debug.Log("Serialized Result: " + result);

    }
}


[DataContract]
class Player_Data
{
    [DataMember]
    private GameObject _weapon;

    public GameObject weapon
    {
        get { return _weapon; }
        set { _weapon = value; }
    }

    [DataMember]
    public float baseDamage;
    [DataMember]
    public float baseHealth;
    [DataMember]
    public float currentHealth;
    [DataMember]
    public float baseMana;
    [DataMember]
    public float currentMana;
    [DataMember]
    public float baseMoveSpeed;
}
7
ответ дан Community 27 August 2018 в 23:47
поделиться

В идеале у вас должен быть объект, в котором хранятся данные о оружии (атака, долговечность и т. д.) и сериализовать этот объект, что значительно упрощает ваши игры с сохранением и больше OOP, поскольку вы можете наследовать этот класс.

1
ответ дан Aleksandar 27 August 2018 в 23:47
поделиться

Unity не позволит вам сделать это, потому что Gameobject содержит все прикрепленные к нему сценарии. Например, рендеринги mesh, коллайдеры и т. Д.

Если вы хотите сказать сериализовать Tranform, вы можете обойти это, создав новую позицию Vector3, масштаб Vector3, кватернион Vector4 и затем сериализуйте это, а затем на десериализацию подают эти данные в новый Transform (например).

Но попытка сериализации фактических данных сетки, связанная с рендерером mesh, оказалась бы довольно сложной задачей. Лучше всего просто сериализовать int или что-то, что представляет собой идентификатор сетки, а затем трансформировать его в правильную ссылку на загрузку.

3
ответ дан Zze 27 August 2018 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: