I’ll drop my scripts in first, I’m not sure how much of it is necessary.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Type { Player, Enemy}
public enum AttackType { Slashing, Piercing, Blunt, Arcana}
[CreateAssetMenu(fileName ="New Unit", menuName ="Scriptable Objects/New Unit")]
public class UnitObject : ScriptableObject
{
public Sprite uiDisplay;
public Type type;
public AttackType attackType;
[TextArea(15, 20)]
public string Description;
public Unit data = new Unit();
public string UnitName;
public int maxHP;
public int minDamage;
public int maxDamage;
public int defense;
public int evasionChance;
public int critChance;
public int critPercentExtraDamage;
public float startTimeToAttack;
public Unit CreateUnit()
{
Unit newUnit = new Unit(this);
return newUnit;
}
}
[System.Serializable]
public class Unit
{
public int Id = -1;
public Unit()
{
Id = -1;
}
public Unit(UnitObject unit)
{
Id = unit.data.Id;
}
}
public class UnitInventoryObject : ScriptableObject, ISerializationCallbackReceiver
{
public string savePath;
public UnitInventory UnitContainer;
public UnitDatabaseObject unitDatabase;
public UnitInventorySlot[] GetUnitSlots { get { return UnitContainer.unitSlots; } }
public bool AddUnit(Unit _unit)
{
if (EmptyUnitSlotCount <= 0)
return false;
UnitInventorySlot slot = FindUnitOnInventory(_unit);
if (slot == null)
{
SetEmptySlot(_unit);
return true;
}
return true;
}
public int EmptyUnitSlotCount
{
get
{
int counter = 0;
for (int i = 0; i < GetUnitSlots.Length; i++)
{
if (GetUnitSlots[i].unit.Id <= -1)
{
counter++;
}
}
return counter;
}
}
public UnitInventorySlot FindUnitOnInventory(Unit _unit)
{
for (int i = 0; i < GetUnitSlots.Length; i++)
{
if (GetUnitSlots[i].unit.Id == _unit.Id)
{
return GetUnitSlots[i];
}
}
return null;
}
public UnitInventorySlot SetEmptySlot(Unit _unit)
{
for (int i = 0; i < GetUnitSlots.Length; i++)
{
if(GetUnitSlots[i].unit.Id <= -1)
{
GetUnitSlots[i].UpdateUnitSlot(_unit);
return GetUnitSlots[i];
}
}
return null;
}
public void SwapUnits(UnitInventorySlot unit1, UnitInventorySlot unit2)
{
if (unit2.CanPlaceInUnitSlot(unit1.UnitObject) && unit1.CanPlaceInUnitSlot(unit2.UnitObject))
{
UnitInventorySlot temp = new UnitInventorySlot(unit2.unit);
unit2.UpdateUnitSlot(unit1.unit);
unit1.UpdateUnitSlot(temp.unit);
}
}
public void RemoveUnit(Unit _unit)
{
for (int i = 0; i < GetUnitSlots.Length; i++)
{
if(GetUnitSlots[i].unit == _unit)
{
GetUnitSlots[i].UpdateUnitSlot(null);
}
}
}
public void OnAfterDeserialize()
{
}
public void OnBeforeSerialize()
{
}
[System.Serializable]
public class UnitInventory
{
public UnitInventorySlot[] unitSlots = new UnitInventorySlot[4];
public void Clear()
{
for (int i = 0; i < unitSlots.Length; i++)
{
unitSlots[i].RemoveUnit();
}
}
}
}
public delegate void UnitSlotUpdated(UnitInventorySlot _slot);
[System.Serializable]
public class UnitInventorySlot
{
[System.NonSerialized]
public UserInterfaceUnit Unitparent;
[System.NonSerialized]
public UnitSlotUpdated UnitOnAfterUpdate, UnitOnBeforeUpdate;
[System.NonSerialized]
public GameObject unitSlotDisplay;
[System.NonSerialized]
public UnitSlotUpdated OnAfterUpdate, OnBeforeUpdate;
public Unit unit;
public UnitObject UnitObject
{
get
{
if (unit.Id >= 0)
return Unitparent.inventory.unitDatabase.GetUnit[unit.Id];
return null;
}
}
public UnitInventorySlot()
{
UpdateUnitSlot(new Unit());
}
public UnitInventorySlot(Unit _unit)
{
UpdateUnitSlot(_unit);
}
public void UpdateUnitSlot(Unit _unit)
{
//if (OnBeforeUpdate != null)
// UnitOnBeforeUpdate.Invoke(this);
unit = _unit;
//if (OnAfterUpdate != null)
// UnitOnAfterUpdate.Invoke(this);
}
public void RemoveUnit()
{
UpdateUnitSlot(new Unit());
}
public bool CanPlaceInUnitSlot(UnitObject _unitObject)
{
if (_unitObject.data.Id <= -1)
return false;
return true;
}
}
public class CombatController : MonoBehaviour
{
public List<UnitObject> Entities = new List<UnitObject>();
private void Start()
{
Entities.Add(PlayerParty.UnitContainer.unitSlots[i].UnitObject);
{
}
I’ve recently followed a tutorial on an Inventory system using scriptable objects and have adapted the system to be an Inventory system for units. A unit is a scriptable object that holds information about an entity like health and damage stats. The system works fine, however I have a problem now referencing my unit inventory. I have a inventory object that holds the scriptable objects for the units currently in my player’s party. From my CombatController script I’m trying to get the scriptable objects of the units in my party to use in the combat system I’m creating. The scripts are pretty long but I’m pretty sure my error lies in how my Unit Object is declared.
Here I create a UnitObject property.
public class UnitInventorySlot
{
public UnitObject UnitObject
{
get
{
if (unit.Id >= 0)
return Unitparent.inventory.unitDatabase.GetUnit[unit.Id];
return null;
}
}
From the CombatController script I try to access the scriptableObjects in my party and add them to a list and I get a null reference exeption error.
Entities.Add(PlayerParty.UnitContainer.unitSlots[i].UnitObject);
How would I edit my scripts so that I can access the Scriptable Objects in my party without getting the error?
Any help is appreciated.
Original System That I modified -
GitHub link for Inventory System - GitHub - sniffle6/Scriptable-Object-Inventory: A scriptable object based inventory system for Unity3D