- Home /
How to access a list from a scriptable object?
I am in the process of making a game and currently trying to have a message appear that will state which enemy has appeared and where the battle is taking place. The various areas of the game are saved as scriptable objects. In each area I have saved a list of enemies and a list of allies.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "NewArea", menuName = "Area")]
public class Areas : ScriptableObject
{
public List<ScriptableObject> enemy;
public List<ScriptableObject> allies;
}
When the battle starts, the battle creation script goes through a list of areas and finds the one you are currently in. The script then will display the message "A wild ----- appeared in the -----". I can get the area name to appear easily enough, but I am lost when it comes to finding the enemy name from the scriptable object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class BattleCreation : MonoBehaviour
{
public Text discriptionText;
public List<ScriptableObject> areas;
public ScriptableObject CurrentArea;
void Start()
{
//Find Current Area
Scene scene = SceneManager.GetActiveScene();
for (int i = 0; i < areas.Count; i++)
{
if (scene.name == areas[i].name)
{
CurrentArea = areas[i];
}
}
//Display text (current issue)
discriptionText.text = "A wild " + CurrentArea.enemy[0] + " appeared in the " + CurrentArea.name;
}
}
CurrentArea.enemy
CurrentArea.allies
I'm not sure what the problem is?
The original issue I had was that whenever I tried to use CurrentArea.enemy I would get this:
Assets\Scripts\BattleCreation.cs(25,56): error CS1061: 'ScriptableObject' does not contain a definition for 'enemy' and no accessible extension method 'enemy' accepting a first argument of type 'ScriptableObject' could be found (are you missing a using directive or an assembly reference?)
You need to pass not scriptableobject put the class name of your scriptable object so Areas
public List<Areas> areas;
Are the allies / enemies supposed to be scriptable objects themselves? You probably want to replace that with something more specific.
public List<Enemy> enemies; // ins$$anonymous$$d of List<ScriptableObject>
//that would allow you to interact with the public members of your enemy class.
foreach(var enemy in CurrentArea.enemy) {
descriptionText.text += $"{enemy.name} appeared\n";
}
That will just print the names of the scriptable objects you assigned in the area.
The enemies are scriptable objects themselves. When I declare the list like you did I get this error:
Assets\Scripts\Areas.cs(8,17): error CS0246: The type or namespace name 'Enemy' could not be found (are you missing a using directive or an assembly reference?)
Answer by Zentiu · Mar 21, 2020 at 12:16 AM
You can not change or look up any value in a scriptableObject unless you instantiate or in this case create a new instance of it first. The instance of the scriptableObject will have all the values for that instance that you set as a scriptable object and can then manipulate it. I personally dont use scriptable objects unless i am creating like items for the game. For enemies i dont do that but it is possible. Look at scriptableObjects as prefabs. instantiate them first and then you can manipulate any value you set access for.
If you need more let me know.
Your answer
Follow this Question
Related Questions
How to Update ScriptableObject 1 Answer
How can I find all instances of a Scriptable Object in the Project (Editor) 3 Answers
Are ScriptableObjects good for non-visualised models? 2 Answers
Instancing ScriptableObject not saved in assets results in warning message 0 Answers
Why do I need to serialize a struct inside a ScriptableObject to save its data? 1 Answer