Select Git revision
ProgramController.cs
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);
}
}
}