I am wondering if I could apply the code used to save inventory items to other scriptable objects?
public static InventoryItem GetFromID(string itemID)
{
if (itemLookupCache == null)
{
itemLookupCache = new Dictionary<string, InventoryItem>();
var itemList = Resources.LoadAll<InventoryItem>("");
foreach (var item in itemList)
{
if (itemLookupCache.ContainsKey(item.itemID))
{
Debug.LogError(string.Format("Looks like there's a duplicate GameDevTV.UI.InventorySystem ID for objects: {0} and {1}", itemLookupCache[item.itemID], item));
continue;
}
itemLookupCache[item.itemID] = item;
}
}
if (itemID == null || !itemLookupCache.ContainsKey(itemID)) return null;
return itemLookupCache[itemID];
}
I am trying to apply the same ID to my own scriptable object, but GetFromCropID keeps returning null.
[CreateAssetMenu(fileName = "Growables", menuName = "Plant Seeds/Make New Seed", order = 0)]
public class PlantConfig : ScriptableObject, ISerializationCallbackReceiver
{
[SerializeField] string cropID = null;
[SerializeField] int daysUntilSeedling = 1;
[SerializeField] int daysUntilSprout = 2;
[SerializeField] int daysUntilBudding = 3;
[SerializeField] int daysUntilHarvest = 4;
[SerializeField] GameObject seededPrefab = null;
[SerializeField] GameObject seedlingPrefab = null;
[SerializeField] GameObject sproutPrefab = null;
[SerializeField] GameObject buddingPrefab = null;
[SerializeField] GameObject harvestPrefab = null;
[SerializeField] InventoryItem harvestableItem = null;
// for saving
static Dictionary<string, PlantConfig> cropLookupCache;
public int DaysUntilSeedling()
{
return daysUntilSeedling;
}
public int DaysUntilSprout()
{
return daysUntilSprout;
}
public int DaysUntilBudding()
{
return daysUntilBudding;
}
public int DaysUntilHarvest()
{
return daysUntilHarvest;
}
public GameObject SpawnSeeds()
{
return seededPrefab;
}
public GameObject SpawnSeedling()
{
return seedlingPrefab;
}
public GameObject SpawnSprout()
{
return sproutPrefab;
}
public GameObject SpawnBudding()
{
return buddingPrefab;
}
public GameObject SpawnHearvestable()
{
return harvestPrefab;
}
public InventoryItem SpawnHarvestedPickup()
{
return harvestableItem;
}
public string GetCropID()
{
return cropID;
}
public static PlantConfig GetFromCropID(string cropID)
{
if (cropLookupCache == null)
{
cropLookupCache = new Dictionary<string, PlantConfig>();
var cropList = Resources.LoadAll<PlantConfig>("");
foreach (var crop in cropList)
{
if (cropLookupCache.ContainsKey(crop.cropID))
{
Debug.LogError(string.Format("Looks like there's a duplicate PlantConfig ID for objects: {0} and {1}", cropLookupCache[crop.cropID], crop));
continue;
}
cropLookupCache[crop.cropID] = crop;
}
}
if (cropID == null || !cropLookupCache.ContainsKey(cropID)) return null;
return cropLookupCache[cropID];
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
if (string.IsNullOrWhiteSpace(cropID))
{
cropID = System.Guid.NewGuid().ToString();
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
// Require by the ISerializationCallbackReceiver but we don't need
// to do anything with it.
}
}
Here is the class that should save/load the crop ID:
[System.Serializable]
public class FarmPlot : MonoBehaviour, ISaveable
{
public bool isTilled = false;
public bool isPlanted = false;
public bool isWatered = false;
[SerializeField] Material untilledSoilTexture = null;
[SerializeField] Material tilledSoilTexture = null;
[SerializeField] Material wateredSoilTexture = null;
GameObject player = null;
GameObject plantPrefab = null;
PlantConfig plant;
public bool isHarvestable = false;
public FarmPlotRecord farmPlotRecord;
public string cropID;
int daysSincePlanted = 0;
private void Awake()
{
player = GameObject.FindGameObjectWithTag("Player");
}
private void UpdateFarmPlot()
{
if (isTilled)
{
gameObject.GetComponent<MeshRenderer>().material = tilledSoilTexture;
}
if (isTilled && isWatered)
{
gameObject.GetComponent<MeshRenderer>().material = wateredSoilTexture;
}
if (isPlanted)
{
//if (GetComponentInChildren<CropGrower>() == null)
//{
// isPlanted = false;
var newPlantPrefab = Instantiate(plant.SpawnSeeds(), transform.position, Quaternion.identity);
newPlantPrefab.transform.parent = gameObject.transform;
}
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
HandleRaycast();
}
}
public void HandleRaycast()
{
RaycastHit hit;
if (Physics.Raycast(GetMouseRay(), out hit))
{
var farmTool = player.GetComponent<Equipment>().GetItemInSlot(EquipLocation.Weapon) as WeaponConfig;
//print(farmTool);
if (farmTool == null) return;
if (hit.collider.gameObject.tag == "Farm")
{
FarmPlot soil = hit.collider.gameObject.GetComponent<FarmPlot>();
TillFarmPlot(soil, farmTool);
WaterFarmPlot(soil, farmTool);
PlantinFarmPlot(soil, farmTool);
}
}
}
public void TillFarmPlot(FarmPlot soil, WeaponConfig farmTool)
{
if (soil.isTilled) return;
if (!soil.isTilled && farmTool.GetTool() == "Hoe")
{
soil.isTilled = true;
soil.GetComponent<MeshRenderer>().material = tilledSoilTexture;
}
}
public void WaterFarmPlot(FarmPlot soil, WeaponConfig farmTool)
{
if (soil.isWatered || !soil.isTilled) return;
if (!soil.isWatered && soil.isTilled && farmTool.GetTool() == "Waterer")
{
soil.isWatered = true;
soil.GetComponent<MeshRenderer>().material = wateredSoilTexture;
print("Watering this farm plot: " + soil.gameObject.name);
}
}
public void PlantinFarmPlot(FarmPlot soil, WeaponConfig farmTool)
{
if (soil.isPlanted || !soil.isTilled) return;
if (soil.isTilled && farmTool.GetTool() == "Seeds")
{
soil.isPlanted = true;
Vector3 soilLocation = soil.transform.position;
plant = farmTool.GetSeeds();
print(plant);
plantPrefab = plant.SpawnSeeds();
cropID = plant.GetCropID();
var newPlantPrefab = Instantiate(plantPrefab, soilLocation, Quaternion.identity);
newPlantPrefab.transform.parent = soil.gameObject.transform;
}
}
private static Ray GetMouseRay()
{
return Camera.main.ScreenPointToRay(Input.mousePosition);
}
public void WateringReset()
{
if (!isWatered) return;
if (isWatered)
{
isWatered = false;
GetComponent<MeshRenderer>().material = tilledSoilTexture;
}
}
public void GrowthStatus(FarmPlot soil)
{
if (soil.isWatered && soil.isPlanted)
{
CropGrower cropGrower = GetComponentInChildren<CropGrower>();
cropGrower.GrowthStatus(soil);
}
}
public void ResetCropStage()
{
isPlanted = false;
}
[System.Serializable]
public struct FarmPlotRecord
{
public bool waterRecord;
public bool tillRecord;
public bool plantRecord;
public int daysSincePlantedRecord;
public bool harvestableRecord;
public string cropID;
}
public object CaptureState()
{
farmPlotRecord.waterRecord = isWatered;
farmPlotRecord.tillRecord = isTilled;
farmPlotRecord.plantRecord = isPlanted;
if (isPlanted)
{
farmPlotRecord.daysSincePlantedRecord = daysSincePlanted;
farmPlotRecord.harvestableRecord = isHarvestable;
farmPlotRecord.cropID = cropID;
}
Debug.Log("testing farm save: " + gameObject.name + " " + farmPlotRecord.tillRecord + " " + farmPlotRecord.waterRecord + " " + farmPlotRecord.plantRecord);
return farmPlotRecord;
}
public void RestoreState(object state)
{
var farmPlotStatus = (FarmPlotRecord)state;
isWatered = farmPlotStatus.waterRecord;
isTilled = farmPlotStatus.tillRecord;
isPlanted = farmPlotStatus.plantRecord;
if (isPlanted)
{
plant = PlantConfig.GetFromCropID(farmPlotStatus.cropID);
Debug.Log(plant);
}
UpdateFarmPlot();
Debug.Log("testing farm load: " + gameObject.name + " " + farmPlotStatus.tillRecord + " " + farmPlotStatus.waterRecord + " " + farmPlotStatus.plantRecord);
}
}
Per the Debug Log, it looks like GetFromCropID is not able to get the crop id from the object.