Вот написал небольшой код сохранения на C# под Unity 5 хочу спросить на сколько он правилен то есть такой подход.
Код с перемеными
Код
using UnityEngine; using System.Collections;
namespace GlobalsSave { public static class Info { public static string expansion = ".med"; public static string CamName = "MainCamera3dFPS";
}
[System.Serializable] public class ObjectSaveInfo { public string NameObject; //Позицыя персонажа public float PlayerPosX; public float PlayerPosY; public float PlayerPosZ;
//Поворот перснонажа public float PlayerRotX; public float PlayerRotY; public float PlayerRotZ; public float PlayerRotW;
/* //Позицыя камеры public float CamPosX; public float CamPosY; public float CamPosZ; //Поворот камеры public float CamRotX; public float CamRotY; public float CamRotZ; public float CamRotW; */
} }
Сам код загрузки и созранения
Код
using UnityEngine; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine.UI; using GlobalsSave;
//namespace ClassSave public class ClassSave : MonoBehaviour { //Главный клас сохранения public class ClassSaves { //пременая имени обекта сохранения static string nameFileSave; //обрашение к вспомогательному скрипту с хранением переменых сохранения static ObjectSaveInfo save = new ObjectSaveInfo();
//функцыя сохраняет имя обекта через Transform и выводит лог если нада public static void SaveObject(Transform _Object, bool SaveDebug) { //предаем имя обекта nameFileSave = _Object.transform.name + Info.expansion;
save.NameObject = _Object.transform.name;
//функцыя проверки и создания файла с сохранением FailCon (SaveDebug); }
//функцыя сохраняет имя обекта через GameObject и выводит лог если нада public static void SaveObject(GameObject _Object, bool SaveDebug) { //предаем имя обекта nameFileSave = _Object.transform.name + Info.expansion;
save.NameObject = _Object.transform.name;
//функцыя проверки и создания файла с сохранением FailCon (SaveDebug); }
//сохраняем имя обекта через поле вода public static void SaveObject(string _Name, bool SaveDebug) { //предаем имя обекта nameFileSave = _Name + Info.expansion;
save.NameObject = _Name;
//функцыя проверки и создания файла с сохранением FailCon (SaveDebug); }
//проверяем есть ли фаил и если нет создаем его public static void FailCon(bool _SaveDebug) { //проверка есть ли фаил if (!Directory.Exists(Application.dataPath + "/Saves")) Directory.CreateDirectory(Application.dataPath + "/Saves"); //если нету дериктории создаем ее FileStream fs = new FileStream(Application.dataPath + "/Saves/" + nameFileSave, FileMode.Create); ///создаем фаил
BinaryFormatter formator = new BinaryFormatter(); formator.Serialize(fs, save); fs.Close();
//отображаемдебаг в консоле если он истина if (_SaveDebug == true) { Debug.Log(nameFileSave); Debug.Log("Ok"); } } }
public class ClasLoad { static string nameFileLoad;
BinaryFormatter formatter = new BinaryFormatter(); using (FileStream fs = new FileStream("test.dat", FileMode.OpenOrCreate)) { formatter.Serialize(бла бла); }
Бинарная сериализация работает в пределах инфраструктуры CLI, возникнут проблемы при переносе на другие платформы. Если не хочешь зависить от платформы использую JSON и XML сериализацию И да GameObject, Transform и прочие классы юнити нельзя сериализовать стандартными методами
можете взглянуть на него и сказать что тут не правильно написано вроде все работает но сто пудов чето не так писал сам
Код
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class Test : MonoBehaviour {
public GameObject gMob; public Transform basisTower; //основа башни public Transform tower; //сама башня которая будет поворачиваться
public List<Collider> colMobs; //список мобов попавшых в зону башни
public float hels;
public float speedRotationTower; //скорос поворота public float distanceAttacks; //дистанция атаки public float angleRotationTower; //поворот башни
//приватные пременые [SerializeField] float dirDistancAttack; //переменая для хранения дистанцыи [SerializeField] float dirAngle; //переменая для хранения угла [SerializeField] bool attacks; //флаг для атаки(нада атаковать или нет) Quaternion rotBasis; //начальный угол поворота башни Quaternion rotTowerMob; //угол поворота моба public
void AngleEndDistanc() { if (colMobs != null) for (int i = 0; i < colMobs.Count; i++) { dirAngle = Vector3.Angle(basisTower.forward, colMobs[i].transform.position); dirDistancAttack = Vector3.Distance(basisTower.position, colMobs[i].transform.position); if (attacks == false && gMob == null) { if (dirDistancAttack <= distanceAttacks && dirAngle <= angleRotationTower) { attacks = true; gMob = GameObject.Find(colMobs[i].transform.name); } else { attacks = false; gMob = null; } }
} }
void OnTriggerEnter(Collider other) { Debug.Log("ok trigget"); if (other.tag == "Mobs") { int index = colMobs.FindIndex(x => x.gameObject == other.gameObject); if (index == -1) colMobs.Add(other); } }
void OnTriggerExit(Collider other) { if (other.tag == "Mobs") { int index = colMobs.FindIndex(x => x.gameObject == other.gameObject); if (index != -1) colMobs.RemoveAt(index); } } }
И да вот такая ошибка
MissingReferenceException: The object of type 'BoxCollider' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. TowerRotations+<OnTriggerEnter>c__AnonStorey2.<>m__4 (UnityEngine.Collider x) (at Assets/Scripts/C#/TowerRotations.cs:74) System.Collections.Generic.List`1[UnityEngine.Collider].GetIndex (Int32 startIndex, Int32 count, System.Predicate`1 match) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:313) System.Collections.Generic.List`1[UnityEngine.Collider].FindIndex (System.Predicate`1 match) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:294) TowerRotations.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/C#/TowerRotations.cs:74)
Помогите пожалуйста
Сообщение отредактировал x_Medwed - Вторник, 25 Августа 2015, 21:18
Ну во первых не вздумай ставить решарпер. Это тебе только навредит. А во вторых - сериализация плохой вариант в любом проявлении. Открой MemoryStream и через BinaryWriter запиши в него все что надо, и сохрани просто в файл, можешь зашифровать после этого по желанию).
А во вторых - сериализация плохой вариант в любом проявлении
А как в микросервисной архитектуре да и вообще в почти любой другой передавать данные по сети? разработчики protobuf'a (из гугла, которые пишут свой механизм "быстрой и компактной" сериализации) удивились бы этому заявлению Разработка программного обеспечения для ОС Windows и Android, клиент-серверные, облачные приложения, работа с БД и многое другое - https://www.weblancer.net/users/zhuravelsv/
А как в микросервисной архитектуре да и вообще в почти любой другой передавать данные по сети? разработчики protobuf'a (из гугла, которые пишут свой механизм "быстрой и компактной" сериализации) удивились бы этому заявлению
Сериализация - хорошо. Но начинающий программист должен соблюдать несколько правил для нее:
1. Декорируйте атрибутом [Serializable] типы, реализующие интерфейс ISerializable; 2. Убедитесь, что все сериализуемые члены декорированы атрибутом [Serializable] и корректно сериализуются; 3. Реализуя интерфейс ISerializable, не забудьте реализовать конструктор сериализации (Ctor(SerializationInfo, StreamingContext)); 4. В запечатанных типах установите модификатор доступа private для конструктора сериализации, в незапечатанных — protected; 5. В незапечатанных типах, реализующий интерфейс ISerializable, сделайте метод GetObjectData виртуальным; 6. Проверьте, что в методе GetObjectData сериализуются все необходимые члены, включая члены базового типа, если он есть.
Поэтому начинающим я советую просто взять MemoryStream и записать в определенном порядке все что ему нужно передать по сети, а с другой стороны в том же порядке прочитать. Все... На этом их гемор закончится. Я не говорю, что сериализация - это плохо. Просто эта морока для хотя бы мидлов уже...