I don't get any errors but my script doesn't load or possibly save my array...
here's the first script
[System.Serializable]
public class PlayerData
{
public float health;
public float thirst;
public float hunger;
public float oxygen;
public float[] position;
public int[] inventoryIDs;
public PlayerData (Health healthO, SaveLoad saveload)
{
//Save int items
health = healthO.health;
thirst = healthO.thirst;
hunger = healthO.hunger;
oxygen = healthO.oxygen;
//set and save location array
position = new float[3];
position[0] = healthO.transform.position.x;
position[1] = healthO.transform.position.y;
position[2] = healthO.transform.position.z;
//set and save inventory IDs
inventoryIDs = new int[50];
for(int i = 0; i < 50; i++)
{
inventoryIDs[i] = saveload.IDs[i];
}
}
}
here's the next
public class SaveLoad : MonoBehaviour
{
public GameObject player;
public int[] IDs;
public GameObject[] objects;
Inventory inventory;
Health health;
void Start()
{
IDs = new int[50];
objects = new GameObject[50];
inventory = player.GetComponent<Inventory>();
health = player.GetComponent<Health>();
}
void Update()
{
//Add IDs
for (int i = 0; i < 50; i++)
{
IDs[i] = inventory.slot[i].GetComponent<Slot>().ID;
}
//debug save load test
if (Input.GetKeyDown(KeyCode.Z))
{
SaveP();
}
if (Input.GetKeyDown(KeyCode.X))
{
LoadP();
}
}
public void SaveP()
{
SaveSystem.SavePlayer(health, this);
}
public void LoadP()
{
PlayerData data = SaveSystem.LoadPlayer();
//load stats
health.thirst = data.thirst;
health.hunger = data.hunger;
health.health = data.health;
health.oxygen = data.oxygen;
//Load position
Vector3 position;
position.x = data.position[0];
position.y = data.position[1];
position.z = data.position[2];
player.transform.position = position;
//load IDs
for (int i = 0; i < 50; i++)
{
IDs[i] = data.inventoryIDs[i];
}
//Load Items
for (int i = 0; i < 50; i++)
{
if(objects[IDs[i]] != null)
{
GameObject itemObject = (GameObject)Instantiate(objects[IDs[i]], new Vector3(0, 0, 0), Quaternion.identity);
Item item = itemObject.GetComponent<Item>();
inventory.AddItem(itemObject, item.ID, item.type, item.name, item.description, item.icon);
} else
{
return;
}
}
}
}
Here's the last script
public static class SaveSystem
{
public static string fileName = "FileSave.bin";
public static void SavePlayer(Health health, SaveLoad SL)
{
//Create formatter
BinaryFormatter bf = new BinaryFormatter();
// Create file stream
FileStream file = File.Create(GetFullPath());
//Save data
PlayerData data = new PlayerData(health, SL);
bf.Serialize(file, data);
//Close stream
file.Close();
}
public static PlayerData LoadPlayer()
{
if (SaveExists())
{
try
{
//Create formatter
BinaryFormatter bf = new BinaryFormatter();
//Create file stream
FileStream file = File.Open(GetFullPath(), FileMode.Open);
//Load data
PlayerData pd = (PlayerData)bf.Deserialize(file);
//close stream
file.Close();
//return data
return pd;
}
catch (SerializationException)
{
Debug.Log("Failed to load file at: " + GetFullPath());
}
}
return null;
}
private static bool SaveExists()
{
return File.Exists(GetFullPath());
}
private static string GetFullPath()
{
return Application.persistentDataPath + "/" + fileName;
}
}
there are all connected with the save load script loading and saving the variables into the player and items to the inventory sots. the inventory IDs array isn't saving or loading
Related
I'm trying to save the 3D array witch has position data of the blocks with Unity and I can't find out how to save it.
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
}
This is the block class which I stored the information about block.
public Block[,,] WorldBlock = new Block[100, 10, 100];
This is the array I want to save and it has 100000 blocks in it.
There are many ways how to approach this.
One way would e.g. be Newtonsoft JSON (comes as a package via the PackageManager and even pre-installed in latest Unity versions)
using Newtonsoft.Json;
....
public Block[,,] WorldBlock = new Block[100, 10, 100];
private string filePath => Path.Combine(Application.persistentDataPath, "example.json");
private void Save()
{
var json = JsonConvert.SerializeObject(WorldBlock);
File.WriteAllText(filePath, json);
}
private void Load()
{
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
WorldBlock = JsonConvert.DeserializeObject<Block[,,]>(json);
}
var block = WorldBlock[1, 2, 3];
Debug.Log($"{block.position} - {block.blockType} - {block.facing}");
}
Or - since JSON wastes a lot of character space for your use case - you could also implement you own binary serialization e.g. usingBinaryReader and BinaryWriter
in something like e.g.
[Serializable]
public class Block
{
public Vector3 position;
public short blockType;
public byte facing;
public Block(Vector3 pos, short t, byte f)
{
position = pos;
blockType = t;
facing = f;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(position.x);
writer.Write(position.y);
writer.Write(position.z);
writer.Write(blockType);
writer.Write(facing);
}
public void Deserialize(BinaryReader reader)
{
position. x = reader.ReadSingle();
position. y = reader.ReadSingle();
position. z = reader.ReadSingle();
blockType = reader.ReadInt16();
facing = reader.ReadByte();
}
}
and then do
private void Save()
{
using (var stream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (var writer = new BinaryWriter(stream))
{
// first store the size of each dimension
for (var i = 0; i < WorldBlock.Rank; i++)
{
writer.Write(WorldBlock.GetLength(i));
}
// then serialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = WorldBlock[i, j, k];
block.Serialize(writer);
}
}
}
}
}
}
private void Load()
{
if (File.Exists(filePath))
{
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(stream))
{
// first get th size of each dimension
var x = reader.ReadInt32();
var y = reader.ReadInt32();
var z = reader.ReadInt32();
WorldBlock = new Block[x, y, z];
// then deserialize all blocks
for (var i = 0; i < WorldBlock.GetLength(0); i++)
{
for (var j = 0; j < WorldBlock.GetLength(1); j++)
{
for (var k = 0; k < WorldBlock.GetLength(2); k++)
{
var block = new Block();
block.Deserialize(reader);
WorldBlock[i, j, k] = block;
}
}
}
}
}
}
var exampleBlock = WorldBlock[1, 2, 3];
Debug.Log($"{exampleBlock.position} - {exampleBlock.blockType} - {exampleBlock.facing}");
}
i have build a level menu with levels, i also created and empty array (GameObject[ ] lvlBut; )to store the level icons instantiated, but only 10 level icons are displayed on the screen where as i have 50 levels. for some reason its only taking 10 levels and i don’t t know where i have gone wrong. any suggestions?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.UI;
using TMPro;
public class LevelSelector : MonoBehaviour{
public GameObject levelHolder;
public GameObject levelIcon;
public GameObject thisCanvas;
public int numberOfLevels = 50;
public Vector2 iconSpacing;
private Rect panelDimensions;
private Rect iconDimensions;
private int amountPerPage;
private int currentLevelCount;
int levelsUnlocked;
GameObject[] lvlBut;
void Start()
{
panelDimensions = levelHolder.GetComponent<RectTransform>().rect;
iconDimensions = levelIcon.GetComponent<RectTransform>().rect;
int maxInARow = Mathf.FloorToInt((panelDimensions.width + iconSpacing.x) / (iconDimensions.width + iconSpacing.x));
int maxInACol = Mathf.FloorToInt((panelDimensions.height + iconSpacing.y) / (iconDimensions.height + iconSpacing.y));
amountPerPage = maxInARow * maxInACol;
int totalPages = Mathf.CeilToInt((float)numberOfLevels / amountPerPage);
LoadPanels(totalPages);
}
void LoadPanels(int numberOfPanels)
{
GameObject panelClone = Instantiate(levelHolder) as GameObject;
PageSwiper swiper = levelHolder.AddComponent<PageSwiper>();
swiper.totalPages = numberOfPanels;
for (int i = 1; i <= numberOfPanels; i++)
{
GameObject panel = Instantiate(panelClone) as GameObject;
panel.transform.SetParent(thisCanvas.transform, false);
panel.transform.SetParent(levelHolder.transform);
panel.name = "Page-" + i;
panel.GetComponent<RectTransform>().localPosition = new Vector2(panelDimensions.width * (i - 1), 0);
SetUpGrid(panel);
int numberOfIcons = i == numberOfPanels ? numberOfLevels - currentLevelCount : amountPerPage;
LoadIcons(numberOfIcons, panel);
}
Destroy(panelClone);
}
void SetUpGrid(GameObject panel)
{
GridLayoutGroup grid = panel.AddComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(iconDimensions.width, iconDimensions.height);
grid.childAlignment = TextAnchor.MiddleCenter;
grid.spacing = iconSpacing;
}
void LoadIcons(int numberOfIcons, GameObject parentObject)
{
for (int i = 1; i <= numberOfIcons; i++)
{
currentLevelCount++;
GameObject icon = Instantiate(levelIcon) as GameObject;
icon.transform.SetParent(thisCanvas.transform, false);
icon.transform.SetParent(parentObject.transform);
icon.name = "Level " + i;
icon.GetComponentInChildren<TextMeshProUGUI>().SetText(currentLevelCount.ToString());
}
lvlBut = GameObject.FindGameObjectsWithTag("LevelButton");
levelsUnlocked = PlayerPrefs.GetInt("levelsUnlocked", 1);
for (int i = 0; i < lvlBut.Length; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = false;
}
for (int i = 0; i < levelsUnlocked; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = true;
}
}
}
Response body displays null value for Success
POJO :
public class Employee {
public String name;
public int salary;
public int age;
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Employee[name=" + name + ",salary=" + salary + ",age=" + age + "]";
}
JSON Reader Class :
public class ReadJsonFile < T > {
public < T > List < T > getjsondata(String filepath, Class < T > typeofT) {
//filepath= "src/test/resource/testdataresource/addplacerequest.json";
Gson gson = new Gson();;
BufferedReader bufferReader = null;
try {
bufferReader = new BufferedReader(new FileReader(filepath));
//Type ListType = new TypeToken<ArrayList<Addbook>>(){}.getType();
Type ListType = TypeToken.getParameterized(ArrayList.class, typeofT).getType(); //
//gson.toJson(ReadJsonFile,ListType);
//return new Gson().fromJson(bufferReader, ListType);
List < T > arraylist = gson.fromJson(bufferReader, ListType);
return (arraylist);
} catch (FileNotFoundException e) {
throw new RuntimeException("Json file not found at path : " + filepath);
} finally {
try {
if (bufferReader != null) bufferReader.close();
} catch (IOException ignore) {}
}
}
}
Class to Read Pojo and Json Reader :
public class TestDataBuild {
public static List < Employee > employee() {
ReadJsonFile < Employee > readJson = new ReadJsonFile < Addbook > ();
List < Addbook > employee = readJson.getjsondata("src/test/resource/testDataResource/addplacerequest.json", Employee.class);
//Retrieve data from JsonObject and create Employee bean
for (int i = 0; i < employee.size(); i++) {
//System.out.println(addbook.get(i).name);
addbook.get(i).setName(employee.get(i).name);
addbook.get(i).setAge(employee.get(i).age);
addbook.get(i).setSalary(employee.get(i).salary);
}
return Employee;
}
}
class ImageList implements ListModel<Image> {
private int selection;
private Image[] images;
private EventDispatcher listeners = new EventDispatcher();
public ImageList() {
this.images = new EncodedImage[imageURLs.length];
}
public Image getItemAt(final int index) {
if (images[index] == null) {
images[index] = placeholderForTable;
Util.downloadUrlToStorageInBackground(imageURLs[index], "list" + index, (e) -> {
try {
images[index] = EncodedImage.create(Storage.getInstance().createInputStream("list" + index));
listeners.fireDataChangeEvent(index, DataChangedListener.CHANGED);
} catch (IOException err) {
err.printStackTrace();
}
});
}
return images[index];
}
public int getSize() {
return imageURLs.length;
}
public int getSelectedIndex() {
return selection;
}
public void setSelectedIndex(int index) {
selection = index;
}
public void addDataChangedListener(DataChangedListener l) {
listeners.addListener(l);
}
public void removeDataChangedListener(DataChangedListener l) {
listeners.removeListener(l);
}
public void addSelectionListener(SelectionListener l) {
}
public void removeSelectionListener(SelectionListener l) {
}
public void addItem(Image item) {
}
public void removeItem(int index) {
}
}
protected void postMenuForm(Form f) {
BusinessForumImagesConnection bfic = new BusinessForumImagesConnection();
bfic.businessForumImagesConnectionMethod(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
if (bfic.response != null) {
for (int i = 0; i < imgLoop; i++) {
HashMap hm = (HashMap) bfic.response.get(i);
String imgUrl = (String) hm.get("imgUrl");
imageURLs[i] = imgUrl;
}
}
}
});
if (imageURLs != null) {
ImageList imodel = new ImageList();
ImageViewer iv = new ImageViewer(imodel.getItemAt(0));
iv.setImageList(imodel);
Container adsContainer = BoxLayout.encloseY(adsLabel, iv);
slideIndex = 0;
Runnable r = new Runnable() {
public void run() {
if (slideIndex < imodel.getSize()) {
nextImage = (Image) imodel.getItemAt(slideIndex);
if (nextImage != null) {
iv.setImage(nextImage);
}
slideIndex++;
} else {
slideIndex = 0;
}
}
};
if (uITimer == null) {
uITimer = new UITimer(r);
}
if (uITimer != null) {
uITimer.schedule(5000, true, f); //5 seconds
}
f.add(BorderLayout.SOUTH, adsContainer);
adsContainer.setLeadComponent(adsLabel);
adsLabel.addActionListener((e) -> {
showForm("BusinessForum", null);
});
}
}
I had used URLImage.createToStorage before but imageViewer didnt work properly so I have used ImageList model. But everytime the form is opened, it jst redownloads the imgs and overrides them in storage, that makes the app slower. How can I make sure if the image is already downloaded, it doesnt download it again and jst shows them in imgViewer? thankyou
The download method will always download regardless...
You need to check if the Storage file exists and if so load that.
See the WebServices/Dogs demo in the new kitchen sink: http://www.codenameone.com/blog/kitchensink-ii.html
An LZH archive is embedded within a file. The file was read into a byte[], and the LZH part is identified as a smaller byte[].
How can the embedded LZH bytes be decompressed into another byte[] using .NET Framework 4.6 (C#)? I have only see http://www.infoq.com/news/2008/06/7-Zip-from-.NET which doesn't exactly do what I need.
Thanks.
the code snippet that follows is taken from the sample program from this article
http://www.codeproject.com/Articles/27148/C-NET-Interface-for-Zip-Archive-DLLs
There are no significant changes: instead of reading and writing files, it reads and write byte arrays. Changes are marked by comments
Run with sevenzip.exe e "C:\temp\gwo0.11-sample-win32.lzh" 3 for example
https://dl.dropboxusercontent.com/u/71459360/7z.zip
using System;
using System.Collections.Generic;
using System.Text;
using Nomad.Archive.SevenZip;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
namespace SevenZip
{
class Program
{
private static void ShowHelp()
{
Console.WriteLine("SevenZip");
Console.WriteLine("SevenZip l {ArchiveName}");
Console.WriteLine("SevenZip e {ArchiveName} {FileNumber}");
}
static void Main(string[] args)
{
if (args.Length < 2)
{
ShowHelp();
return;
}
try
{
string ArchiveName;
uint FileNumber = 0xFFFFFFFF;
bool Extract;
switch (args[0])
{
case "l":
ArchiveName = args[1];
Extract = false;
break;
case "e":
ArchiveName = args[1];
Extract = true;
if ((args.Length < 3) || !uint.TryParse(args[2], out FileNumber))
{
ShowHelp();
return;
}
break;
default:
ShowHelp();
return;
}
using (SevenZipFormat Format = new SevenZipFormat(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll")))
{
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Lzh));
if (Archive == null)
{
ShowHelp();
return;
}
try
{
//the byte array is provided by you. here it's coming from a file
byte[] data;
using (var stream = File.OpenRead(ArchiveName))
{
data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
}
using (InStreamWrapper ArchiveStream = new InStreamWrapper(new MemoryStream(data))) //modified here
{
ulong CheckPos = 32 * 1024;
if (Archive.Open(ArchiveStream, ref CheckPos, null) != 0)
ShowHelp();
Console.Write("Archive: ");
Console.WriteLine(ArchiveName);
if (Extract)
{
PropVariant Name = new PropVariant();
Archive.GetProperty(FileNumber, ItemPropId.kpidPath, ref Name);
string FileName = (string) Name.GetObject();
Console.Write("Extracting: ");
Console.Write(FileName);
Console.Write(' ');
MemoryStream ms = new MemoryStream();
Archive.Extract(new uint[] { FileNumber }, 1, 0, new ArchiveMemoryCallback(FileNumber, ms)); //modified here
byte[] output = ms.ToArray(); //here you have the output byte array
output.ToString();
}
else
{
Console.WriteLine("List:");
uint Count = Archive.GetNumberOfItems();
for (uint I = 0; I < Count; I++)
{
PropVariant Name = new PropVariant();
Archive.GetProperty(I, ItemPropId.kpidPath, ref Name);
Console.Write(I);
Console.Write(' ');
Console.WriteLine(Name.GetObject());
}
}
}
}
finally
{
Marshal.ReleaseComObject(Archive);
}
}
}
catch (Exception e)
{
Console.Write("Error: ");
Console.WriteLine(e.Message);
}
}
}
class ArchiveCallback : IArchiveExtractCallback
{
private uint FileNumber;
private string FileName;
private OutStreamWrapper FileStream;
public ArchiveCallback(uint fileNumber, string fileName)
{
this.FileNumber = fileNumber;
this.FileName = fileName;
}
#region IArchiveExtractCallback Members
public void SetTotal(ulong total)
{
}
public void SetCompleted(ref ulong completeValue)
{
}
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
{
if ((index == FileNumber) && (askExtractMode == AskMode.kExtract))
{
string FileDir = Path.GetDirectoryName(FileName);
if (!string.IsNullOrEmpty(FileDir))
Directory.CreateDirectory(FileDir);
FileStream = new OutStreamWrapper(File.Create(FileName));
outStream = FileStream;
}
else
outStream = null;
return 0;
}
public void PrepareOperation(AskMode askExtractMode)
{
}
public void SetOperationResult(OperationResult resultEOperationResult)
{
FileStream.Dispose();
Console.WriteLine(resultEOperationResult);
}
#endregion
}
//new
class ArchiveMemoryCallback : IArchiveExtractCallback
{
private uint FileNumber;
private Stream stream;
private OutStreamWrapper FileStream;
public ArchiveMemoryCallback(uint fileNumber, Stream stream)
{
this.FileNumber = fileNumber;
this.stream = stream;
}
#region IArchiveExtractCallback Members
public void SetTotal(ulong total)
{
}
public void SetCompleted(ref ulong completeValue)
{
}
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
{
if ((index == FileNumber) && (askExtractMode == AskMode.kExtract))
{
FileStream = new OutStreamWrapper(stream);
outStream = FileStream;
}
else
outStream = null;
return 0;
}
public void PrepareOperation(AskMode askExtractMode)
{
}
public void SetOperationResult(OperationResult resultEOperationResult)
{
FileStream.Dispose();
Console.WriteLine(resultEOperationResult);
}
#endregion
}
}