Skip to content
Snippets Groups Projects
Select Git revision
  • 77800ef98d24cfa3eb82ed00b74c42862ce5e04f
  • master default protected
2 results

ProgramController.cs

Blame
  • ProgramController.cs 4.54 KiB
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using UnityEngine;
    using UnityEngine.InputSystem;
    
    public class ProgramController : MonoBehaviour
    {
        public SpawnBlockEvent spawnBlockEvent;
        public Transform UserTransform;
    
        public InputActionReference saveEventAction;
        public InputActionReference loadEventAction;
    
    
        private List<GameObject> _spawnedBlocks = new();
    
        private string _savePath;
    
        private void Awake()
        {
            this._savePath = Application.persistentDataPath + "/program.save";
            saveEventAction.action.Enable();
            saveEventAction.action.performed += SaveProgram;
    
            loadEventAction.action.Enable();
            loadEventAction.action.performed += LoadProgram;
    
            // InputSystem.onDeviceChange += OnDeviceChange;
        }
    
        private void OnDestroy()
        {
            saveEventAction.action.Disable();
            saveEventAction.action.performed -= SaveProgram;
    
            loadEventAction.action.Disable();
            loadEventAction.action.performed -= LoadProgram;
    
            // InputSystem.onDeviceChange -= OnDeviceChange;
        }
    
        private void OnDeviceChange(InputDevice device, InputDeviceChange change)
        {
            switch (change)
            {
                case InputDeviceChange.Disconnected:
                    saveEventAction.action.Disable();
                    saveEventAction.action.performed -= SaveProgram;
                    break;
                case InputDeviceChange.Reconnected:
                    saveEventAction.action.Enable();
                    saveEventAction.action.performed += SaveProgram;
                    break;
            }
        }
    
        // Start is called before the first frame update
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        public void RegisterBlock(GameObject block)
        {
            _spawnedBlocks.Add(block);
        }
    
        private Save CreateSave()
        {
            Save save = new();
            save.UserTransform = new Vector3[] { this.UserTransform.position, this.UserTransform.eulerAngles };
    
            foreach (GameObject block in _spawnedBlocks)
            {
                Vector3[] blockVertices = block.GetComponent<MeshFilter>().mesh.vertices;
                Vector3[] blockData = new Vector3[2 + blockVertices.Length];
                blockData[0] = block.transform.position;
                blockData[1] = block.transform.eulerAngles;
    
                for (int i = 0; i < blockVertices.Length; i++)
                {
                    blockData[i + 2] = blockVertices[i];
                }
    
                save.Blocks.Add(blockData);
    
                GameObject[] anchors = block.GetComponent<BlockDeform>().GetAnchors();
                Vector3[] anchorsData = new Vector3[anchors.Length];
                for (int i = 0; i < anchors.Length; i++)
                {
                    anchorsData[i] = anchors[i].transform.localPosition;
                }
    
                save.BlockAnchors.Add(anchorsData);
            }
    
            return save;
        }
    
        public void SaveProgram(InputAction.CallbackContext context)
        {
            Save save = CreateSave();
            SurrogateSelector surrogateSelector = new();
            surrogateSelector.AddSurrogate(typeof(Vector3), new StreamingContext(StreamingContextStates.All), new Vector3SerializationSurrogate());
    
            BinaryFormatter binaryFormatter = new();
            binaryFormatter.SurrogateSelector = surrogateSelector;
    
            FileStream fs = File.Create(this._savePath);
            binaryFormatter.Serialize(fs, save);
            fs.Close();
        }
    
        public void LoadProgram(InputAction.CallbackContext context)
        {
            if (File.Exists(this._savePath))
            {
                if (_spawnedBlocks.Count > 0)
                {
                    foreach (GameObject block in _spawnedBlocks)
                    {
                        Destroy(block);
                    }
                    _spawnedBlocks.Clear();
                }
    
                SurrogateSelector surrogateSelector = new();
                surrogateSelector.AddSurrogate(typeof(Vector3), new StreamingContext(StreamingContextStates.All), new Vector3SerializationSurrogate());
    
                BinaryFormatter binaryFormatter = new();
                binaryFormatter.SurrogateSelector = surrogateSelector;
                FileStream fs = File.Open(this._savePath, FileMode.Open);
    
                Save save = (Save)binaryFormatter.Deserialize(fs);
                fs.Close();
    
                UserTransform.position = save.UserTransform[0];
                UserTransform.eulerAngles = save.UserTransform[1];
                spawnBlockEvent.LoadBlocks(save.Blocks, save.BlockAnchors);
            }
        }
    
    }