Snake-Eyes Posted Thursday at 12:18 PM Share Posted Thursday at 12:18 PM Здравствуйте! Как мне правильно скопировать сложную структуру из свойств в созданную структуру в скрипте? Что-то мозг совсем отказывается работать, выручайте пожалуйста! :) P.S. XML вообще не знаю, если что то не так делаю, подскажите пожалуйста. Спасибо! FootstepCollections.prop FootstepsSystem.cs Link to comment
fox Posted Thursday at 04:01 PM Share Posted Thursday at 04:01 PM Здравствуйте, @Snake-Eyes! Не совсем понятно, для чего Вам писать .prop - файл на xml вручную и работать с ним из компонента... Обычной практикой здесь было бы просто определить нужную структурку в C#-компоненте, добавить соответствующий параметр и затем его использовать (в конечном итоге "под капотом" при компиляции компонента соответствующий prop-файл будет автоматически сгенерирован). Затем просто накинуть компонент на ноду, указать нужное количество файлов, масок и.т.п. И дергать из кода нужные Вам элементы массива структур. using System.Collections; using System.Collections.Generic; using Unigine; [Component(PropertyGuid = "GUID_вашего_компонента")] public class FootstepsSystem : Component { [ShowInEditor] private SoundSource soundSource; //... private ShapeCapsule shape; private LandscapeFetch landscapeFetch = new(); // объявляем структуру public struct FootstepsData { public int[] LayerMapMasks; public List<AssetLink> FootstepSounds; public AssetLink JumpSound; public AssetLink LandSound; } // Параметр, представляющий собой массив определенных выше структур [ShowInEditor] private List<FootstepsData> footstepDatas = null; void Init() { //... // создаем SoundSource, используя файл шагов с нужным индексом soundSource = new SoundSource(footstepDatas[0].FootstepSounds[0].Path); // ... // можно поменять звуковой файл, который будет проигрываться (например, прыжок) soundSource.SampleName = footstepDatas[0].JumpSound.Path; // ... } void Update() { } } Еще момент: вместо string-полей для путей до файлов ваших ассетов удобнее пользоваться типом AssetLink, по сути получится то же самое, только в редакторе вместо того, чтобы прописывать путь вручную при настройке, можно будет просто дропнуть в поле ассет. В коде у параметра AssetLink просто берете Path и получаете свой путь. Вот так это будет выглядеть в редакторе: Надеюсь, это поможет! Если я неверно понял задачу, объясните пожалуйста, что именно Вы хотите сделать. Спасибо! Link to comment
Snake-Eyes Posted Thursday at 04:52 PM Author Share Posted Thursday at 04:52 PM 37 minutes ago, fox said: Не совсем понятно, для чего Вам писать .prop - файл на xml вручную и работать с ним из компонента... Дело в том что мне нужно где-то хранить заполненные данные, и когда нужно просто их откуда-то "тянуть". Тут есть несколько вариантов, либо делать node reference вешать компонент и в этом компоненте хранить данные. 2 способ Json но он явно не для этого... 3. Props'ы, я так понял они работают как аналог SciptableObject(SO) в юнити? (грубо говоря). В общем нужен подход что бы не заполнять данные по сто раз(в случае чего), а где то их хранить. К примеру давайте представим что у меня есть 16 звуков шагов, которые работают на определенной маске. Понятно что если допустим сделать лист, и как - то переименовать то все заполненные данные просто сбросятся, и нужно заново это 16 дорожек заполнять. Я прикреплю 3 скрипта когда "игрался" с landscapeFetch. В общем исходя из этого я сделал вывод что надо что-то типо SO как в юнити для удобства. Может быть я ошибаюсь и есть более "гибкие" решения в Unigine? LandscapeIntersection.cs Footsteps.cs FootstepsData.cs Link to comment
fox Posted Friday at 06:44 PM Share Posted Friday at 06:44 PM На самом деле, если хочется хранить где-то данные в файлах и "тянуть", то можно использовать и Json , и Xml классы, собственно для этого они и предназначены, и используются внутри движком для парсинга файлов проперти и графов материалов, например. Можно вообще хранить данные в текстовых или бинарных файлах и парсить потом вручную как угодно. Примеры использования классов можно найти в документации в статьях раздела API или в сэмплах SDK: Класс Json Класс Xml (Примеры в SDK Browser: Samples->C# API -> Systems ->Xml) Если прямо хочется "тянуть" из проперти в компонент - тоже можно! Вот, к примеру, настроенное проперти для Вашей структурки из примера <?xml version="1.0" encoding="utf-8"?> <property version="2.19.0.1" name="steps_prop" manual="1" editable="1"> <!--Объявление структурки--> <struct name="FootstepsData"> <parameter name="LayerMapMasks" type="array" array_type="int"/> <parameter name="FootstepSounds" type="array" array_type="file"/> <parameter name="JumpSound" type="file"/> <parameter name="LandSound" type="file"/> </struct> <parameter name="soundSource" type="node" filter="SoundSource"/> <!--Параметр-Массив, откуда будем брать данные--> <parameter name="footstepDatas" type="array" array_type="FootstepsData"> <value> <parameter name="LayerMapMasks" type="array" array_type="int"> <value>1</value> <value>2</value> </parameter> <parameter name="FootstepSounds" type="array" array_type="file"> <value>step1.ogg</value> <value>step2.ogg</value> </parameter> <parameter name="JumpSound" type="file">jump.ogg</parameter> <parameter name="LandSound" type="file">land.ogg</parameter> </value> <value> <parameter name="LayerMapMasks" type="array" array_type="int"> <value>1</value> <value>2</value> <value>3</value> </parameter> <parameter name="FootstepSounds" type="array" array_type="file"> <value>concrete.ogg</value> <value>grass.ogg</value> <value>snow.ogg</value> </parameter> <parameter name="JumpSound" type="file">jump.ogg</parameter> <parameter name="LandSound" type="file">land.ogg</parameter> </value> </parameter> </property> А вот пример кода компонента с методом, который заберет данные из проперти и положит в Ваш массив структур (код без проверок, просто в качестве быстрой иллюстрации). public class FootstepsSystem : Component { // ... [ShowInEditor] private Property DataStorage=null; // <-- сюда можно накинуть нужное преднастроенное проперти в редакторе, // либо просто из кода загрузить (как удобнее) // объявляем структуру, соответствующую структуре в проперти private struct FootstepsData { public int[] LayerMapMasks; public List<AssetLink> FootstepSounds; public AssetLink JumpSound; public AssetLink LandSound; } // массив определенных выше структур, в который будем "тянуть" private List<FootstepsData> footstepDatas = new List<FootstepsData>(); // пример метода, "тянущего" данные массива структур из соответствующего параметра проперти // и заполняющего массив, который мы будем использовать private List<FootstepsData> getFootstepData(PropertyParameter fsd_param) { // инициализируем массив для использования в приложении и перебираем все элементы параметра проперти List<FootstepsData> footstepData = new List<FootstepsData>(); for (int i = 0; i < fsd_param.ArraySize; i++) { FootstepsData fsd = new FootstepsData(); // берем элемент списка PropertyParameter elem = fsd_param.GetChild(i); // берем первого потомка (маски) по индексу, // а можно по имени искать (как в prop-файле объявлено), через fsd_param.FindChild("LayerMapMasks") PropertyParameter masks = elem.GetChild(0); // "тянем" все маски, что есть в этом элементе fsd.LayerMapMasks = new int[masks.ArraySize]; for (int j=0; j < masks.ArraySize; j++) { fsd.LayerMapMasks[j] = masks.GetChild(j).ValueInt; } // берем второго потомка (sound-файлы) по индексу PropertyParameter sound_files = elem.GetChild(1); // "тянем" весь список звуковых файлов, что есть в этом элементе fsd.FootstepSounds = new List<AssetLink>(); for (int j=0; j < sound_files.ArraySize; j++) { fsd.FootstepSounds.Add(new AssetLink(sound_files.GetChild(j).ValueFile)); } // "забираем" так же по индексу звуковые файлы для прыжка и приземления fsd.JumpSound = new AssetLink(elem.GetChild(2).ValueFile); fsd.LandSound = new AssetLink(elem.GetChild(3).ValueFile); // добавляем заполненный элемент в наш массив, который используем в приложении footstepData.Add(fsd); } return footstepData; } // ... void Init() { // берем у проперти рутовый параметр PropertyParameter root_parameter = DataStorage.ParameterPtr; // берем параметр с нужным нам массивом структур и "тянем" все, что нам надо footstepDatas = getFootstepData(root_parameter.GetChild(root_parameter.FindChild("footstepDatas"))); // смотрим, что получилось foreach( FootstepsData elem in footstepDatas) { Log.Message("-- MASKS: \n"); foreach( int mask in elem.LayerMapMasks) Log.Message("----: {0} \n", mask); Log.Message("-- SOUNDS: \n"); foreach( AssetLink sfile in elem.FootstepSounds) Log.Message("----: {0} \n", sfile.Path); Log.Message("-- JumpSound: {0} \n", elem.JumpSound.Path); Log.Message("-- LandSound: {0} \n", elem.LandSound.Path); } //... } // ... } Надеюсь, это поможет! Спасибо! Link to comment
Recommended Posts