Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Ryan Hipple
Principal Engineer
Schell Games
Schell Games
VR / AR
Theme Parks
Transformational Games
Game Architecture with
Scriptable Objects
Engineering
Pillars
Modular
Editable
Debuggable
Modular
Systems not directly dependent on each other
Scenes are clean slates
Prefabs work on their own
Components!
Editable
Focus on data
Change the game without code
Emergent Design
Change at runtime
Debuggable
Test in isolation (modularity)
Debug views and features
Never fix a bug you do not understand
Engineering
Pillars
Modular
Editable
Debuggable
Scriptable Object Basics
Primer
Serializable Unity Class
Similar to MonoBehaviour, no Transform
Saved as .asset file
Simple Use Cases
Game config files
Inventory
Enemy stats
AudioCollection
Architecture
Singleton Benefits
Access anything from anywhere
Persistent State
Easy to understand
Consistent pattern
Easy to “plan”
*Li...
Singleton Problems
Rigid Connections / Not Modular
No Polymorphism
Not Testable
Dependency Nightmare
Single Instance!
Solutions
Reduce need for global managers
Inversion of Control
Example: Dependency Injection
Objects are given dependencie...
Modular Data
Enemy Prefab Example
EnemyManager.Instance.MoveSpeed?
Hard reference
Dependency on manager being loaded
EnemyConfig Script...
ScriptableObject Variables
[CreateAssetMenu]
public class FloatVariable : ScriptableObject
{
public float Value;
}
ScriptableObject Variables
Hitpoints
Damage Amounts
Timing Data
public class DumbEnemy : MonoBehaviour
{
public FloatVaria...
Float Reference
[Serializable]
public class FloatReference
{
public bool UseConstant = true;
public float ConstantValue;
p...
Float Variable
public class DumbEnemy : MonoBehaviour
{
public FloatVariable MaxHP;
public FloatVariable MoveSpeed;
}
publ...
Float Variable Secrets
[CreateAssetMenu]
public class FloatVariable : ScriptableObject
{
public float Value;
}
PlayerHPPlayer
EnemyAI
HealthUI
Audio
System
Demo!
Event Architecture
Event Architecture
Modularize systems
Reuse in other projects
Isolates Prefabs
Optimize, only execute when needed
Highly d...
UnityEvent
*Serialized Function Call
*
UnityEvent Advantages
Editor hook-ups
Less code, fewer assumptions
Pass Arguments
Extend UnityEvent<T>
Static / dynamic ar...
UnityEvent Problems
Rigid bindings
Button hard references what responds to it
Limited serialization
Garbage allocation
Making Our Own Events
Data driven
Designer authorable
Debuggable
Making Our Own Events
[CreateAssetMenu]
public class GameEvent : ScriptableObject
{
private List<GameEventListener> listen...
Making Our Own Events
public class GameEventListener : MonoBehaviour
{
public GameEvent Event;
public UnityEvent Response;...
Demo!
Scriptable Objects vs ...
Singleton Manager Goals
Track all enemies in a scene
Understand player
Issue commands
Singleton Manager Problems
Race conditions
Rigid singleton
Only one
Runtime Sets
Keep track of a list of objects in the scene
Avoid race conditions
More flexible than Unity tags, singleton
Runtime Sets
public abstract class RuntimeSet<T> : ScriptableObject
{
public List<T> Items = new List<T>();
public void Ad...
Runtime Sets
Buildings placed in an RTS
Renderers for special effects
Items on a map
Demo!
Enums
Must change in code
Difficult to remove / reorder
Can’t hold additional data
Demo!
Asset Based Systems
Generic Systems
System is ScriptableObject Asset in project
Reference directly with inspector
No code lookup
No scene-only...
Inventory
ScriptableObject Master List
ScriptableObject per item
Use different inventories in different scenes
InventoryPlayer
Inventory Example
Equip
Screen
NPC
Save
System
Demo!
Engineering
Pillars
Modular
Editable
Debuggable
Thank you!
Ryan Hipple
@roboryantron
Game Architecture with Scriptable Objects
Game Architecture with Scriptable Objects
Game Architecture with Scriptable Objects
Game Architecture with Scriptable Objects
Game Architecture with Scriptable Objects
Game Architecture with Scriptable Objects
Upcoming SlideShare
Loading in …5
×

Game Architecture with Scriptable Objects

6,307 views

Published on

Scriptable Objects are an immensely powerful yet often underutilized feature of Unity. Learn how to get the most out of this versatile data structure and build more extensible systems and data patterns. At Schell Games, we have used the Scriptable Object for everything from a hierarchical state machine, to an event system, to a method of cross scene communication. Come hear about our specific examples that push this data type to the limit. In learning about our Scriptable Object usage, you will get some extra knowledge on Unity's serialization mechanics and a ton of editor scripting tips and examples.

Published in: Engineering

Game Architecture with Scriptable Objects

  1. 1. Ryan Hipple Principal Engineer Schell Games
  2. 2. Schell Games VR / AR Theme Parks Transformational Games
  3. 3. Game Architecture with Scriptable Objects
  4. 4. Engineering Pillars Modular Editable Debuggable
  5. 5. Modular Systems not directly dependent on each other Scenes are clean slates Prefabs work on their own Components!
  6. 6. Editable Focus on data Change the game without code Emergent Design Change at runtime
  7. 7. Debuggable Test in isolation (modularity) Debug views and features Never fix a bug you do not understand
  8. 8. Engineering Pillars Modular Editable Debuggable
  9. 9. Scriptable Object Basics
  10. 10. Primer Serializable Unity Class Similar to MonoBehaviour, no Transform Saved as .asset file
  11. 11. Simple Use Cases Game config files Inventory Enemy stats AudioCollection
  12. 12. Architecture
  13. 13. Singleton Benefits Access anything from anywhere Persistent State Easy to understand Consistent pattern Easy to “plan” *Lies *
  14. 14. Singleton Problems Rigid Connections / Not Modular No Polymorphism Not Testable Dependency Nightmare Single Instance!
  15. 15. Solutions Reduce need for global managers Inversion of Control Example: Dependency Injection Objects are given dependencies Single responsibility principle
  16. 16. Modular Data
  17. 17. Enemy Prefab Example EnemyManager.Instance.MoveSpeed? Hard reference Dependency on manager being loaded EnemyConfig ScriptableObject reference? Lumps all part of the enemy stats together Limits extension / modularity Better?
  18. 18. ScriptableObject Variables [CreateAssetMenu] public class FloatVariable : ScriptableObject { public float Value; }
  19. 19. ScriptableObject Variables Hitpoints Damage Amounts Timing Data public class DumbEnemy : MonoBehaviour { public FloatVariable MaxHP; public FloatVariable MoveSpeed; }
  20. 20. Float Reference [Serializable] public class FloatReference { public bool UseConstant = true; public float ConstantValue; public FloatVariable Variable; public float Value { get { return UseConstant ? ConstantValue : Variable.Value; } } }
  21. 21. Float Variable public class DumbEnemy : MonoBehaviour { public FloatVariable MaxHP; public FloatVariable MoveSpeed; } public class DumbEnemy : MonoBehaviour { public FloatReference MaxHP; public FloatReference MoveSpeed; }
  22. 22. Float Variable Secrets [CreateAssetMenu] public class FloatVariable : ScriptableObject { public float Value; }
  23. 23. PlayerHPPlayer EnemyAI HealthUI Audio System
  24. 24. Demo!
  25. 25. Event Architecture
  26. 26. Event Architecture Modularize systems Reuse in other projects Isolates Prefabs Optimize, only execute when needed Highly debuggable
  27. 27. UnityEvent *Serialized Function Call *
  28. 28. UnityEvent Advantages Editor hook-ups Less code, fewer assumptions Pass Arguments Extend UnityEvent<T> Static / dynamic arguments
  29. 29. UnityEvent Problems Rigid bindings Button hard references what responds to it Limited serialization Garbage allocation
  30. 30. Making Our Own Events Data driven Designer authorable Debuggable
  31. 31. Making Our Own Events [CreateAssetMenu] public class GameEvent : ScriptableObject { private List<GameEventListener> listeners = new List<GameEventListener>(); public void Raise() { for(int i = listeners.Count -1; i >= 0; i--) listeners[i].OnEventRaised(); } public void RegisterListener(GameEventListener listener) ... public void UnregisterListener(GameEventListener listener) ... }
  32. 32. Making Our Own Events public class GameEventListener : MonoBehaviour { public GameEvent Event; public UnityEvent Response; private void OnEnable() { Event.RegisterListener(this); } private void OnDisable() { Event.UnregisterListener(this); } public void OnEventRaised() { Response.Invoke(); } }
  33. 33. Demo!
  34. 34. Scriptable Objects vs ...
  35. 35. Singleton Manager Goals Track all enemies in a scene Understand player Issue commands
  36. 36. Singleton Manager Problems Race conditions Rigid singleton Only one
  37. 37. Runtime Sets Keep track of a list of objects in the scene Avoid race conditions More flexible than Unity tags, singleton
  38. 38. Runtime Sets public abstract class RuntimeSet<T> : ScriptableObject { public List<T> Items = new List<T>(); public void Add(T t) { if (!Items.Contains(t)) Items.Add(t); } public void Remove(T t) { if (Items.Contains(t)) Items.Remove(t); } }
  39. 39. Runtime Sets Buildings placed in an RTS Renderers for special effects Items on a map
  40. 40. Demo!
  41. 41. Enums Must change in code Difficult to remove / reorder Can’t hold additional data
  42. 42. Demo!
  43. 43. Asset Based Systems
  44. 44. Generic Systems System is ScriptableObject Asset in project Reference directly with inspector No code lookup No scene-only references Like AudioMixer / AudioMixerGroup
  45. 45. Inventory ScriptableObject Master List ScriptableObject per item Use different inventories in different scenes
  46. 46. InventoryPlayer Inventory Example Equip Screen NPC Save System
  47. 47. Demo!
  48. 48. Engineering Pillars Modular Editable Debuggable
  49. 49. Thank you! Ryan Hipple @roboryantron

×