I have a folder in my unity project under "Resources/ScriptableObjects/Skins". I need to get all the objects in the folder, generate a random number for the index, then assign the sprite to an existing game object that the script is attached to. The current error I'm getting is "NullReferenceException: Object reference not set to an instance of an object" on line 151 but I'm creating an instance of the object on line 149. What gives? Here is my function to assign the sprite from a random scriptableobject in the folder to the game object the script is tied to:
void AssignRandomSkin(){
// Load all skins into memory
Object[] skinObjects = Resources.LoadAll("ScriptableObjects/Skins");
// Get length of list
int amountOfSkins = skinObjects.Length;
// Get random index of skin to assign
int skinToAssignIndex = Random.Range(0, amountOfSkins);
GameObject thisSkin = Instantiate(skinObjects[skinToAssignIndex]) as GameObject;
// Assign it to game object
gameObject.GetComponent<SpriteRenderer>().sprite = thisSkin.GetComponent<Sprite>();
}
Here is the Scriptable Object:
using UnityEngine;
[CreateAssetMenu(fileName = "Skin", menuName = "ScriptableObjects/SkinObject", order = 1)]
public class SkinObject : ScriptableObject
{
public string spriteName; // Name of sprite
public Sprite sprite;
public float xPos;
public float yPos;
public float zPos;
public float xScale;
public float yScale;
public float zScale;
public float fallSpeed; //AKA Weight
public string tier; //Category that skin can be assigned in
}
So what happens here?
Your objects are ScriptableObject of type SkinObject
! => They are not GameObject
prefabs!
Everything in your code should work until the
GameObject thisSkin = Instantiate(skinObjects[skinToAssignIndex]) as GameObject;
first of all it is unnecessary to instantiate a ScriptableObject
. This would only create a clone of the asset but you don't need this.
And second you are trying to cast it to GameObject
. As said this is a type mismatch and therefore thisSkin
will be null
!
And finally Sprite
is no component. You are rather trying to access the field .sprite
of your SkinObject
type.
I'm pretty sure it should rather be
// You can directly tell LoadAll to only load assets of the correct type
// even if there would be other assets in the same folder
SkinObject[] skinObjects = Resources.LoadAll<SkinObject>("ScriptableObjects/Skins");
var thisSkin = skinObjects[Random.Range(0, skinObjects.Length)];
// Assign it to game object
gameObject.GetComponent<SpriteRenderer>().sprite = thisSkin.sprite;
However, as said before, from the Best Practices - Resource Folder Don't use it!
Why not simply reference these ScriptableObjects the usual way via the Inspector in a field like
public SkinObject[] availableSkins;