Практическое использование движка Unity3d.
Задача 8: Сохранение и загрузка состояние сцены. Временной плеер.
Решим следующую задачу: необходимо реализовать «Unity3d плеер сцены». Этот плеер умеет сохранять позиции всех объектов в сцене, а после сохранения может восстановить их позиции. Это возможность может использоваться в играх, для создания эффекта «вернуться во времени», ну и вообще это очень прикольная фича :).
Программа должна выглядеть следующим образом: в приложении падают определенное количество физический объектов на плоскость. Соударяются и падают с плоскости. На экране имеется кнопка «Record», которая позволяет начать запись сцены. По ее нажатию появляется кнопка «Recording…Stop». После того как пользователь нажал на кнопку «Recording…Stop», программа останавливает запись сцены и показывает слайдер, с помощью которого можно вернуть сцену в любой записанный промежуток времени.
Решим эту задачу. Основная суть приложения – это сохранять позиции объектов в определенные промежутки времени. Поэтому для этого создадим типы данных и переменные, с помощью которых мы сможем сохранять позиции всех объектов.
///Переменная, которая будет хранить позиции этих объектов это массив из Dictionary. Каждая единица массива хранить состояние сцены в текущий момент времени:/// This is data stored for one frame of the saved data /// public class SavedState { public GameObject GO; public float Time; public Vector3 Position; public Quaternion Rotation; public Vector3 ScaleLocal; }
private List< Dictionary < GameObject, SavedState > > mSavedStates = new List< Dictionary< GameObject, SavedState > >();Теперь нужно понять, как мы будем включать и выключать физическое воздействие на объекты. У любого объекта, который работает по физическим законам в Unity3d есть компонент «Rigidbody» (см. http://docs.unity3d.com/ScriptReference/Rigidbody.html). Для того чтоб включить или выключить физическое взаимодействие физики на данный «Rigidbody», нужно использовать свойство «Rigidbody.isKinematic» (см. http://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html). Следовательно, функция включения и выключения взаимодействия физики будет выглядеть следующим образом:
///Т.к. в программе явно существует несколько состояний (обычное, запись, проигрывание) то создадим перечисление и переменную, которая будет отвечать за текущее состояние приложения. Эта переменная будет использоваться во всех основных функциях: Update, OnGUI./// Just set "Kinematic" for all game objects /// /// private void EnablePhysics(bool enable) { Rigidbody[] rigid = GameObject.FindObjectsOfType(); foreach (Rigidbody r in rigid) { r.isKinematic = !enable; } }
///И переменная:/// Possible application states /// public enum EGameState { None = 0, Recording, Reproduce }
// current game state private EGameState mGameState = EGameState.None;Для того чтоб сохранить положение любого объекта в Unity3d нужно сохранить позиции, вращение и растяжение объекта. Таким образом функция сохранения состояния будет выглядеть так:
private void SaveGosCurrentState() { if (mGameState != EGameState.Recording) { return; } GameObject[] gos = GameObject.FindObjectsOfTypeА установка определенного состояния будет выглядеть так:(); // create current time state Dictionary stateData = new Dictionary (); // add game objects to dict foreach (GameObject go in gos) { SavedState state = new SavedState() { GO = go, Position = go.transform.position, Rotation = go.transform.rotation, ScaleLocal = go.transform.localScale, Time = Time.realtimeSinceStartup }; stateData[go] = state; } // add current time state to list mSavedStates.Add(stateData); }
private void SetGosStateByDict(DictionaryДемонстрацию работы можно скачать здесь:currentStateData) { // restore time data foreach (KeyValuePair kvp in currentStateData) { SavedState savedData = kvp.Value; GameObject goToRestore = savedData.GO; // restore transformations goToRestore.transform.position = savedData.Position; goToRestore.transform.rotation = savedData.Rotation; goToRestore.transform.localScale = savedData.ScaleLocal; } }
https://dl.dropboxusercontent.com/u/20023505/Articles/Unity3d/Lesson8/Build/Build.zip
Посмотреть онлайн работу можно здесь:
https://dl.dropboxusercontent.com/u/20023505/Articles/Unity3d/Lesson8/WebPlayer/WebPlayer.html
https://dl.dropboxusercontent.com/u/20023505/Articles/Unity3d/Lesson8/WebPlayer/WebPlayer.html
Исходные коды работы, как всегда бесплатно, можно скачать здесь:
https://dl.dropboxusercontent.com/u/20023505/Articles/Unity3d/Lesson8/Sources/Sources.zip
https://github.com/den-potapenko/Unity3dArticles/tree/master/Lesson8
https://dl.dropboxusercontent.com/u/20023505/Articles/Unity3d/Lesson8/Sources/Sources.zip
https://github.com/den-potapenko/Unity3dArticles/tree/master/Lesson8
No comments:
Post a Comment