- Home /
use ScriptableObject as player data (rpg combat)
So , I'm creating a simple turn-based combat (think angry birds epic RPG) , and I stumble on ScriptableObject and use it. basically I created an EnemyBase and PlayerBase ScriptableObject and create an asset for player and enemy from baseSO. (for starter it's just HP and sprite)
how do you pass the ScriptableObject value to the gameObject? because AFAIK SO is not present in the scene itself, do we still need a presistent gameObject to store the value?. let's say in a transition to battleScene, the battleScene has 6 blank gameObject (3 enemies and 3 players). how do we get all the value from SO (lets say player1,2,3 / enemy1,2,3) to the respective gameObject?
can we modify the SO value for saving player progress? (let's say the HP got upgraded after a few battle) , or again is it better to have presistent gameObject that only recieve baseValue from SO but later on we only modify the gameObject?
ScriptableObject looks very light compared to prefab so I wanted to maximize the use of SO instead of single prefab for every player / enemy
Answer by itchyOwl · Mar 08, 2018 at 03:55 PM
On creating scriptable objects:
You don't need that ScriptableObjectUtility anymore, because CreateAssetMenuAttribute should work similarly. If you really want an implementation that does not require adding that attribute, you need to use reflection to get all the scriptable object types in the project. Throw me a msg, if you need that. The code is a bit lengthy, so I'm not posting it here.
To be clear, I'm referring scriptable objects as instances stored in assets. Scriptable objects can be instantiated like other Unity Objects without storing them to assets, but I don't have any experience on using them like that.
On using scriptable object instances as assets:
After storing the scriptable object instance as asset, you use it like any other asset. They are not stored in the scene, but in the assets folder (like models, textures, script files etc). You don't need to copy the data from the scriptable object into a script, you can simply use a reference to it.
You have at least three options to make a reference to it: A) drag the reference in the editor B) load the asset from Resources (in runtime) C) use an asset bundle and get it from there (in runtime).
You can also use a scriptable object to store references to other assets. This way you only have to load the scriptable object and get all the other references via it.
Just remember that scriptable objects are not for saving the game data, because they cannot be modified outside the editor! Use binary/text serialization, json, xml, playerprefs or some other solution for that.
Answer by Harinezumi · Mar 07, 2018 at 12:31 PM
Using ScriptableObject is a great way of storing data for levels, creatures or anything. That said, you need a way to save instances as assets, which is done with an editor script. Fortunately, the Unity Wiki has a generic implementation for it (I tried, it works perfectly). EDIT: as itchyOwl writes, this isn't necessary anymore, the CreateAssetMenuAttribute can be used for this purpose.
So after you create your ScriptableObject assets you can declare a field in your creature logic and assign the asset to it (possibly with [SerializeField] if you want to assign it in the Editor).
Also, check out this video that explains some of the amazing uses of ScriptableObjects!
so how do you use the SO value? let's say I have a goblin and bat asset , do I assign them as the EnemyBase asset or just get the value from EnemyBase asset? (and implement them in correspond field like float for hp , string for name etc.). also there is a possibility to either get goblin/bat value (let's say random encounter). do I create a list of all the enemy asset and use integer as index check for enemyAsset List and spawn the index? or is there any better way to implement these?
also the createScriptableObjectAsset you share is basically [CreateAsset$$anonymous$$enu] attributes, right?
The way I do it (but I'm still experimenting, so this might not be the best approach) is that I have a Creature script (I assume for you that's EnemyBase) that has a field for a CreatureAttributes ScriptableObject. Then I create different CreatureAttributes assets, and assign them to the Creature, either at run-time, when a game object with Creature on it is created, or I can already have it assigned in a prefab.
So I think for random encounters I would do just what you said, put different CreatureAttributes assets into a List, and randomly select one and assign it to the Creature.
I hope this makes sense!
okay that actually makes sense xD
so basically Creature script is a container for GameObject that needs a CreatureAttributes .asset value. quick question tho , how do you assign the assets during play session? I usually assign the asset via inspector , but for GameObject that has wild card value (not always assigned with myAsset1) , I can't seem to find a way to do it via script or any special method from ScriptableObject