Page 1 of 2
Save custom playmaker array
Posted: Wed Dec 08, 2021 2:53 pm
by Fitbie
Hi. I need to save my inventory system. It is made with a regular Playmaker array, its type is a scriptable object. So in order to save I just need to save this array. I know about playmaker global variable saver from Tony Lee but I can't save arrays there and I know about template saver but unfortunately I can't find it out
Can anyone tell me what to do? Or help with the save script? Thank you!
Re: Save custom playmaker array
Posted: Wed Dec 08, 2021 5:08 pm
by Tony Li
Hi,
If you're using the
Save System, you could write a custom saver.
Alternatively, you can use a
Sync XXX Array PlayMaker action to copy a PlayMaker array to a Dialogue System variable or vice versa.
For example, if you have a bool array, you can use Sync Bool Array to copy your bool array to a Dialogue System variable before saving the game.
After you load a game, use Sync Bool Array to copy the Dialogue System variable back to your bool array.
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 7:00 pm
by Fitbie
Hi! I add this lines to your "Playmaker Global Variable Saver"(Items - my array with inventory items) and it works:
Code: Select all
public FsmArray Inventory;
var itemsArray = FsmVariables.GlobalVariables.FindFsmArray("Items");
if (data.Inventory != null) itemsArray.Values = data.Inventory.Values;
But there's little problem; in unity it works completely, but when i build game and try use save/load in game it doesnt work
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 7:11 pm
by Tony Li
Do other savers work in a build? In other words, is the issue with this specific saver, or with the overall setup of the save system in your project?
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 7:35 pm
by Fitbie
Yes, other savers work fine, besides all global variables are saved correctly. The problem is in my code, could you please correct me if it is possible? In unity it saves great, but in build doesnt work
Here is my code, I put my lines in bold:
using System;
using System.Collections.Generic;
using UnityEngine;
using HutongGames.PlayMaker;
namespace PixelCrushers
{
/// <summary>
/// Saves all global bool, int, float, and string variable values.
/// </summary>
[AddComponentMenu("Pixel Crushers/Third Party/PlayMaker Support/PlayMaker Global Variable Saver")]
public class PlayMakerGlobalVariableSaver : Saver
{
[Serializable]
public class Data
{
public List<string> boolNames = new List<string>();
public List<bool> boolValues = new List<bool>();
public List<string> intNames = new List<string>();
public List<int> intValues = new List<int>();
public List<string> floatNames = new List<string>();
public List<float> floatValues = new List<float>();
public List<string> stringNames = new List<string>();
public List<string> stringValues = new List<string>();
public FsmArray Inventory;
}
public override string RecordData()
{
var data = new Data();
foreach (var boolVar in FsmVariables.GlobalVariables.BoolVariables)
{
data.boolNames.Add(boolVar.Name);
data.boolValues.Add(boolVar.Value);
}
foreach (var intVar in FsmVariables.GlobalVariables.IntVariables)
{
data.intNames.Add(intVar.Name);
data.intValues.Add(intVar.Value);
}
foreach (var floatVar in FsmVariables.GlobalVariables.FloatVariables)
{
data.floatNames.Add(floatVar.Name);
data.floatValues.Add(floatVar.Value);
}
foreach (var stringVar in FsmVariables.GlobalVariables.StringVariables)
{
data.stringNames.Add(stringVar.Name);
data.stringValues.Add(stringVar.Value);
}
data.Inventory = FsmVariables.GlobalVariables.FindFsmArray("Items");
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
if (string.IsOrEmpty(s)) return;
var data = SaveSystem.Deserialize<Data>(s);
if (data == ) return;
for (int i = 0; i < data.boolNames.Count; i++)
{
var boolVar = FsmVariables.GlobalVariables.FindFsmBool(data.boolNames);
if (boolVar != ) boolVar.Value = data.boolValues;
}
for (int i = 0; i < data.intNames.Count; i++)
{
var intVar = FsmVariables.GlobalVariables.FindFsmInt(data.intNames);
if (intVar != ) intVar.Value = data.intValues;
}
for (int i = 0; i < data.floatNames.Count; i++)
{
var floatVar = FsmVariables.GlobalVariables.FindFsmFloat(data.floatNames);
if (floatVar != ) floatVar.Value = data.floatValues;
}
for (int i = 0; i < data.stringNames.Count; i++)
{
var stringVar = FsmVariables.GlobalVariables.FindFsmString(data.stringNames);
if (stringVar != ) stringVar.Value = data.stringValues;
}
var itemsArray = FsmVariables.GlobalVariables.FindFsmArray("Items");
if (data.Inventory != ) itemsArray.Values = data.Inventory.Values;
}
}
}
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 8:54 pm
by Tony Li
Hi,
I'm afraid that won't work. FsmArray is not a serializable type. Try this:
FsmArraySaver.cs
Code: Select all
using System;
using System.Collections.Generic;
using UnityEngine;
using HutongGames.PlayMaker;
namespace PixelCrushers
{
/// <summary>
/// Saves a global FsmArray.
/// </summary>
[AddComponentMenu("Pixel Crushers/Third Party/PlayMaker Support/FsmArray Saver")]
public class FsmArraySaver : Saver
{
public string fsmArrayName;
[Serializable]
public class Data
{
public List<bool> boolValues = new List<bool>();
public List<int> intValues = new List<int>();
public List<float> floatValues = new List<float>();
public List<string> stringValues = new List<string>();
}
public override string RecordData()
{
var data = new Data();
var fsmArray = FsmVariables.GlobalVariables.FindFsmArray(fsmArrayName);
if (fsmArray == null) return string.Empty;
if (fsmArray.boolValues != null) data.boolValues.AddRange(fsmArray.boolValues);
if (fsmArray.intValues != null) data.intValues.AddRange(fsmArray.intValues);
if (fsmArray.floatValues != null) data.floatValues.AddRange(fsmArray.floatValues);
if (fsmArray.stringValues != null) data.stringValues.AddRange(fsmArray.stringValues);
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
var fsmArray = FsmVariables.GlobalVariables.FindFsmArray(fsmArrayName);
if (fsmArray == null) return;
if (string.IsNullOrEmpty(s)) return;
var data = SaveSystem.Deserialize<Data>(s);
if (data == null) return;
fsmArray.boolValues = data.boolValues.ToArray();
fsmArray.intValues = data.intValues.ToArray();
fsmArray.floatValues = data.floatValues.ToArray();
fsmArray.stringValues = data.stringValues.ToArray();
}
}
}
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 9:58 pm
by Fitbie
Thanks for your efforts, I really feel bad asking, but my items in my inventory are scriptable objects called "InvItem", I need to save an array with them. I tried adding lines
Code: Select all
public List<InvItem> invItemsValues = new List<InvItem>();
if (fsmArray.invItemsValues != null) data.invItemsValues.AddRange(fsmArray.invItemsValues);
but got an error because InvItem doesn't belong to the FsmVariables class (in Playmaker I added them as Variable Type Definition). I tried to put them in there, but this script is closed for editing.
What should I do. Sorry for the inconvenience.
Re: Save custom playmaker array
Posted: Thu Dec 09, 2021 10:16 pm
by Tony Li
Can you save an array of their names? References to ScriptableObject assets aren't serializable.
Re: Save custom playmaker array
Posted: Sat Dec 11, 2021 2:10 am
by Fitbie
Hi
Sad, I'll try to think of something, but I don't know how to realize it yet
Re: Save custom playmaker array
Posted: Sat Dec 11, 2021 3:20 am
by Fitbie
It was so easy
Playmaker action browser > PlayerPrefs > Save Variable > Load Variable
This action save any variable, also Scriptable Object Array
I build and run game and it works correctly. I don't know, maybe will be some bugs in future, but at rhe moment it works