unity как сохранить тереин
| |
terami | Дата: Среда, 24 Мая 2017, 17:00 | Сообщение # 21 |
был не раз
Сейчас нет на сайте
| EchoIT, и вот тут начинаются страшные вещи
Код public void SaveParams(){ SavedTerrainState = targetTerrain.terrainData.GetHeights(0, 0, targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight); var xml = new XmlSerializer (typeof(Test)); var test = new Test ();
test.SavedTerrainState = SavedTerrainState; using (var stream = new FileStream ("Test.xml", FileMode.Create, FileAccess.Write)) { xml.Serialize (stream, test); } Debug.Log ("Объект сохранился");
} то игра вылетает с такой ошибкой: ArgumentException: Array was not a one-dimensional array. , да та же самая что и при повторном сохранении, но вот сама строчка больше нигде не повторяется, если перенести выше этой строки то она вылетает, если ниже то все нормально
Код test.SavedTerrainState = SavedTerrainState;
и я что-то не догоняю теперь что мне делать?
Всё мрак, спасенья нет
|
|
| |
EchoIT | Дата: Среда, 24 Мая 2017, 17:07 | Сообщение # 22 |
старожил
Сейчас нет на сайте
| terami, ну тут дело в том, что двумерные массивы нельзя сериализовать, как-то сразу и не вспомнил об этом. Можно попробовать использовать массив массивов - [][].
Долгожданный анонсик: State of War
Сообщение отредактировал EchoIT - Среда, 24 Мая 2017, 17:08 |
|
| |
terami | Дата: Среда, 24 Мая 2017, 20:36 | Сообщение # 23 |
был не раз
Сейчас нет на сайте
| EchoIT, што это такое?, то есть загнать этот массив в другой массив?
Код public float[,] SavedTerrainState { get; set; } но как?
Код public float[,][,] SavedTerrainState { get; set; } ? public float[[,]] SavedTerrainState { get; set; } ?
вот ещё кое что, но оно не работает
Код using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Xml.Serialization; using System.IO; [System.Serializable] public class Test { public float[,] Sav_mass ; public float[,] SavedTerrainState { get; set; } } public class TerraiDeformer : MonoBehaviour { #region Public members //This class member is used for Crater texture shape, you have to make sure that the access of the texture is Read/Write. You can find it in the advanced section of the import option when you select the texture. public Texture2D CraterTexture; // This class member modifies the intensity of the brush, if you don't introduce this factor, you will get harsh results, or you will not have a control over how hard your terrain is gonna be deformed public float AlphaIntensity; //Here you pass the terrain which you want to deform. public Terrain targetTerrain; #endregion
public float[,] SavedTerrainState { get; set; } // This class member is used to hold the original data of the terrain private float[,] craterShape { get; set; } //Since the height map of the terrain is 2D array, and since we are modifying square area of the terrain, we are extracting the gray-scale information from our crater texture, and keeping it to modify the terrain. // Texture info is a class I made in order to easily cache and manage the crater texture (brushes). void Start () { // Remember, we are addressing a square map here, so you can imagine that 0,0 is the top left corner of the height map, and the terrain height map width and height are the maximum end points of the square Sav_mass = SavedTerrainState; // Look at the constructor of the TextureInfo
}
void OnCollisionEnter(Collision _colObject) { // Here I'm deforming the terrain based on the position of the contact point. It could be a good idea to put a condition to make a certain object with a certain tag can modify the terrain, otherwise, anything which is colliding with the terrain will deform it. } void Update () { if(Input.GetKeyDown(KeyCode.R)) SaveParams(); if(Input.GetKeyDown(KeyCode.E)) LoadParams();
} public void SaveParams(){ SavedTerrainState = targetTerrain.terrainData.GetHeights(0, 0, targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight); var xml = new XmlSerializer (typeof(Test)); var test = new Test ();
test.Sav_mass = Sav_mass;
using (var stream = new FileStream ("Test.xml", FileMode.Create, FileAccess.Write)) { xml.Serialize (stream, test); } Debug.Log ("Объект сохранился");
} public void LoadParams(){ var xml = new XmlSerializer (typeof(Test)); var test = new Test (); using (var stream = new FileStream ("Test.xml", FileMode.Open, FileAccess.Read)) { test = xml.Deserialize (stream) as Test; }
Sav_mass = test.Sav_mass; targetTerrain.terrainData.SetHeights(0, 0, SavedTerrainState); Debug.Log ("Объект загружен"); }
}
Всё мрак, спасенья нет
Сообщение отредактировал terami - Среда, 24 Мая 2017, 20:42 |
|
| |
EchoIT | Дата: Среда, 24 Мая 2017, 21:34 | Сообщение # 24 |
старожил
Сейчас нет на сайте
| terami,
Как я и написал:
Как перегнать из одного в другой - погугли)
А тот код, что ты скинул, по-моему идентичен практически предыдущему, только работает без get/set.
Долгожданный анонсик: State of War
|
|
| |
seaman | Дата: Четверг, 25 Мая 2017, 12:21 | Сообщение # 25 |
старожил
Сейчас нет на сайте
| Я бы не стал сериализовать террейн в XML. Будет очень большой файл. Имхо лучше использовать "родное" представление карты высот - текстуру. Т.е. получить массив высот. Преобразовать его в массив Colors. Задать этот массив SetPixels текстуре. Сохранить текстуру.
|
|
| |
EchoIT | Дата: Четверг, 25 Мая 2017, 12:37 | Сообщение # 26 |
старожил
Сейчас нет на сайте
| seaman, я у себя в RTS написал простенький алгоритм сжатия и по итогу сериализованный файл с массивом высот занимает гораздо меньше, чем оригинальный террейн или текстура карты высот. Но, разумеется, с возрастанием сложности террейна, польза от алгоритма снижается.
Долгожданный анонсик: State of War
Сообщение отредактировал EchoIT - Четверг, 25 Мая 2017, 12:46 |
|
| |
terami | Дата: Суббота, 27 Мая 2017, 11:47 | Сообщение # 27 |
был не раз
Сейчас нет на сайте
| EchoIT, ну конечно же с этим возникнут проблемы, если изменить только сам массив то он конвертировать не сможет Cannot implicitly convert type `float[,]' to `float[][]' , я искал, пытался найти хоть что-то об этом вот такой поисковый запрос я забил в гугл
но ничего, мне суют вот это Unity - Scripting API: Mathf.Lerp и Unity3D.ru • из Float в int | Форум что хоть это такое?, я угадываю в нем очертания массива
а еще я искал как добавить массив в массив, но ничего такого не нашелДобавлено (27 мая 2017, 11:47) --------------------------------------------- EchoIT, я что то нашел, но все не то
Код как конвертировать массив в массив?
public float[][] arr; public float[,] SavedTerrainState { get; set; }
SavedTerrainState = arr; вот это не работает(
и это
то есть этот массив public float[,] SavedTerrainState { get; set; } нужно разделить на два:
float[][] nums = new float[2][]; nums[0] = SavedTerrainState [get]; nums[1] = SavedTerrainState [set]; вот это не работает, нужно что-то подобное? или я совсем не там?
Всё мрак, спасенья нет
Сообщение отредактировал terami - Четверг, 25 Мая 2017, 18:17 |
|
| |
EchoIT | Дата: Суббота, 27 Мая 2017, 12:11 | Сообщение # 28 |
старожил
Сейчас нет на сайте
| terami, давай начнём вот с чего. Ты знаешь, как выглядит двумерный массив?
Долгожданный анонсик: State of War
|
|
| |
terami | Дата: Суббота, 27 Мая 2017, 13:36 | Сообщение # 29 |
был не раз
Сейчас нет на сайте
| EchoIT, ? так ? Код int[,] array = { { 0, 1, 2 }, { 3, 4, 5 } };
Всё мрак, спасенья нет
|
|
| |
EchoIT | Дата: Суббота, 27 Мая 2017, 13:47 | Сообщение # 30 |
старожил
Сейчас нет на сайте
| terami, я про то, как он выглядит, если его вывести наглядно, например. Когда поймёшь, в чём разница между [,] и [][], всё встанет на свои места.
Долгожданный анонсик: State of War
|
|
| |
seaman | Дата: Суббота, 27 Мая 2017, 13:47 | Сообщение # 31 |
старожил
Сейчас нет на сайте
| Цитата EchoIT ( ) алгоритм сжатия Ну если сжимать, то конечно и XML пойдет. Хотя при желании и текстуру сжать можно...
|
|
| |
terami | Дата: Суббота, 27 Мая 2017, 14:14 | Сообщение # 32 |
был не раз
Сейчас нет на сайте
| seaman, EchoIT,
массив [,] 123 345 массив [][] имеет внутри другие массивы, которые содержат данные
или всё ещё хуже?
Всё мрак, спасенья нет
|
|
| |
EchoIT | Дата: Суббота, 27 Мая 2017, 14:30 | Сообщение # 33 |
старожил
Сейчас нет на сайте
| terami, правильно. В итоге ты берёшь массив [,], скажем, такой: 1 2 3 4 5 6 7 8 9 И записываешь его в [][], где в качестве индексов будут 1 2 3, в качестве их элементов - массивы с содержимым столбца. Для 1 это 4 и 7, для 2 это 5 и 8, для 3 это 6 и 9. Ну, это очень условно, но как-то так оно и работает, я просто сейчас не могу до своего кода добраться.
Долгожданный анонсик: State of War
|
|
| |
terami | Дата: Суббота, 27 Мая 2017, 15:00 | Сообщение # 34 |
был не раз
Сейчас нет на сайте
| EchoIT, Код float [][] nums = new float[3][]; // массив массивов где [3] количество под массивов nums[0] = new float SavedTerrainState [,]; // массив в котором содержится массив высот? так тут что-то не правильно, по идее тут должны быть данные высот не записанных в массив
float [][] nums = new float[3][]; // массив массивов где [3] количество под массивов SavedTerrainState [0] = данные ?
ох ох, что-то мне поплохело
Всё мрак, спасенья нет
|
|
| |
EchoIT | Дата: Суббота, 27 Мая 2017, 15:46 | Сообщение # 35 |
старожил
Сейчас нет на сайте
| terami, тебе нужно в nums[0] писать SavedTerrainState [0, 0 .. N - 1], т.е. массив со всеми элементами SavedTerrainState по первому индексу 0.
Долгожданный анонсик: State of War
|
|
| |
terami | Дата: Воскресенье, 28 Мая 2017, 11:11 | Сообщение # 36 |
был не раз
Сейчас нет на сайте
| EchoIT, а вот какие данные?
Код public float[,] SavedTerrainState { get; set; } не это
Код nums[0] = SavedTerrainState [targetTerrain.terrainData.GetHeights(0, 0, targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight)];
или
Код nums[0] = SavedTerrainState [targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight];// не может конвертировать из float в float[] Добавлено (28 мая 2017, 09:48) --------------------------------------------- и тут я как заорал Код using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Xml.Serialization; using System.IO; [System.Serializable] public class Test { public float[,] Sav_mass ; public float[][] arr; public float[,] SavedTerrainState { get; set; } public float[][,] nums;
} public class TerraiDeformer : MonoBehaviour {
public float[][] arr; public float[,] SavedTerrainState { get; set; } public float[,] Sav_mass ; #region Public members //This class member is used for Crater texture shape, you have to make sure that the access of the texture is Read/Write. You can find it in the advanced section of the import option when you select the texture. public Texture2D CraterTexture; // This class member modifies the intensity of the brush, if you don't introduce this factor, you will get harsh results, or you will not have a control over how hard your terrain is gonna be deformed public float AlphaIntensity; //Here you pass the terrain which you want to deform. public Terrain targetTerrain; #endregion public float[][,] nums;
// This class member is used to hold the original data of the terrain private float[,] craterShape { get; set; } //Since the height map of the terrain is 2D array, and since we are modifying square area of the terrain, we are extracting the gray-scale information from our crater texture, and keeping it to modify the terrain. // Texture info is a class I made in order to easily cache and manage the crater texture (brushes). void Start () { // Remember, we are addressing a square map here, so you can imagine that 0,0 is the top left corner of the height map, and the terrain height map width and height are the maximum end points of the square // arr = SavedTerrainState; // Look at the constructor of the TextureInfo // arr[i][j] = Sav_mass[i,j]
float[][,] nums = new float[3][,] { new float[,] { {0, 0}, {targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight} }, new float[,] { {1,2}, {3,6} }, new float[,] { {1,2}, {3,5}, {8, 13} } };
// float [][] nums = new float[1][]; // nums[0] = SavedTerrainState [ targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight];
}
void OnCollisionEnter(Collision _colObject) { // Here I'm deforming the terrain based on the position of the contact point. It could be a good idea to put a condition to make a certain object with a certain tag can modify the terrain, otherwise, anything which is colliding with the terrain will deform it. } void Update () { if(Input.GetKeyDown(KeyCode.R)) SaveParams(); if(Input.GetKeyDown(KeyCode.E)) LoadParams(); } public void SaveParams(){ SavedTerrainState = targetTerrain.terrainData.GetHeights(0, 0, targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight); var xml = new XmlSerializer (typeof(Test)); var test = new Test ();
test.nums = nums;
using (var stream = new FileStream ("Test.xml", FileMode.Create, FileAccess.Write)) { xml.Serialize (stream, test); } Debug.Log ("Объект сохранился");
} public void LoadParams(){ var xml = new XmlSerializer (typeof(Test)); var test = new Test (); using (var stream = new FileStream ("Test.xml", FileMode.Open, FileAccess.Read)) { test = xml.Deserialize (stream) as Test; }
targetTerrain.terrainData.SetHeights(0, 0, SavedTerrainState); nums = test.nums; Debug.Log ("Объект загружен"); }
}
оно работает и сохраняется в не файл, и не загружается с такой ошибкой: A null value was found where an object instance was required ребят пожалуйста помогите мене, я больше не знаю что надо сделать чтобы всё работалоДобавлено (28 мая 2017, 11:11) --------------------------------------------- вот тут ещё и оно не работает
Код void Start () {
Sav_massWidth = targetTerrain.terrainData.heightmapWidth; Sav_massHeght = targetTerrain.terrainData.heightmapHeight;
}
void OnCollisionEnter(Collision _colObject) { // Here I'm deforming the terrain based on the position of the contact point. It could be a good idea to put a condition to make a certain object with a certain tag can modify the terrain, otherwise, anything which is colliding with the terrain will deform it. } void Update () { if(Input.GetKeyDown(KeyCode.R)) SaveParams(); if(Input.GetKeyDown(KeyCode.E)) LoadParams(); } public void SaveParams(){ SavedTerrainState = targetTerrain.terrainData.GetHeights(0, 0, targetTerrain.terrainData.heightmapWidth, targetTerrain.terrainData.heightmapHeight); var xml = new XmlSerializer (typeof(Test)); var test = new Test ();
using (var stream = new FileStream ("Test.xml", FileMode.Create, FileAccess.Write)) { xml.Serialize (stream, test); } Debug.Log ("Объект сохранился");
} public void LoadParams(){ targetTerrain.terrainData.SetHeights(0, 0, SavedTerrainState); var xml = new XmlSerializer (typeof(Test)); var test = new Test (); using (var stream = new FileStream ("Test.xml", FileMode.Open, FileAccess.Read)) { test = xml.Deserialize (stream) as Test; }
SavedTerrainState = test.SavedTerrainState; Sav_massWidth = test.Sav_massWidth; Sav_massHeght = test.Sav_massHeght;
Debug.Log ("Объект загружен"); }
}
Всё мрак, спасенья нет
|
|
| |
|