Вы не можете использовать глобальные переменные для хранения таких данных. Это не только безопасный поток, это не процесс безопасен, а WSGI-серверы на производстве порождают множество процессов. Мало того, что ваши подсчеты были бы неправильными, если бы вы использовали потоки для обработки запросов, они также будут меняться в зависимости от того, какой процесс обрабатывал запрос.
Используйте источник данных за пределами флажка для хранения глобальных данных. База данных, memcached или redis - все соответствующие области хранения, в зависимости от ваших потребностей. Если вам нужно загрузить и получить доступ к данным Python, рассмотрите multiprocessing.Manager
. Вы также можете использовать сеанс для простых данных, предназначенных для каждого пользователя.
Сервер разработки - это единственный поток, по умолчанию один процесс. Вы не увидите поведение, которое вы описываете, поскольку каждый запрос будет обрабатываться синхронно. Включите потоки или процессы, и вы увидите это. app.run(threaded=True)
или app.run(processes=10)
.
Некоторые серверы WSGI могут поддерживать gevent или другого асинхронного рабочего. Глобальные переменные по-прежнему не являются потокобезопасными, поскольку по-прежнему нет защиты от большинства условий гонки. У вас все еще может быть сценарий, когда один работник получает значение, дает, другой его модифицирует, дает, то первый работник также модифицирует его.
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;
}
В идеале у вас должен быть объект, в котором хранятся данные о оружии (атака, долговечность и т. д.) и сериализовать этот объект, что значительно упрощает ваши игры с сохранением и больше OOP, поскольку вы можете наследовать этот класс.
Unity не позволит вам сделать это, потому что Gameobject содержит все прикрепленные к нему сценарии. Например, рендеринги mesh, коллайдеры и т. Д.
Если вы хотите сказать сериализовать Tranform, вы можете обойти это, создав новую позицию Vector3, масштаб Vector3, кватернион Vector4 и затем сериализуйте это, а затем на десериализацию подают эти данные в новый Transform (например).
Но попытка сериализации фактических данных сетки, связанная с рендерером mesh, оказалась бы довольно сложной задачей. Лучше всего просто сериализовать int или что-то, что представляет собой идентификатор сетки, а затем трансформировать его в правильную ссылку на загрузку.