Skip to content

Commit b317a8f

Browse files
committed
docs: best practices
1 parent 53e00b8 commit b317a8f

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

docs/src/content/docs/guides/best-practices.mdx

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,66 @@ sidebar:
55
order: 50
66
---
77

8-
TODO: Best practices for using Scriptable Values
8+
Scriptable Values is simple to use, but there are some best practices that you should follow to make your code cleaner and easier to maintain. This page will cover some of the best practices for using Scriptable Values.
99

1010
## Events
1111

12-
## Property Tracking
12+
### Unsubscribing
13+
14+
When you subscribe to an event, you should always unsubscribe from it when you are done using it. This is especially important when using events in Unity, as they can cause memory leaks if not unsubscribed properly. Fortunately, Scriptable Values has a built-in warning system that will warn you if you forget to unsubscribe from an event. This warning will only show up in the editor, so it won't affect your game in any way. It will also clear subscribers when the game starts. **But you should still always unsubscribe from the event when you are done with the event.**
15+
16+
```csharp title="Unsubscribing Example" ins="playerHealth.OnValueChanged -= OnPlayerHealthChanged;"
17+
using UnityEngine;
18+
using Hertzole.ScriptableValues;
19+
20+
public class HealthUI : MonoBehaviour
21+
{
22+
public ScriptableInt playerHealth;
23+
24+
private void OnEnable()
25+
{
26+
playerHealth.OnValueChanged += OnPlayerHealthChanged;
27+
}
28+
29+
private void OnDisable()
30+
{
31+
// Unsubscribe from the event when the object is disabled.
32+
playerHealth.OnValueChanged -= OnPlayerHealthChanged;
33+
}
34+
35+
private void OnPlayerHealthChanged(int oldValue, int newValue) { }
36+
}
37+
```
38+
39+
## Property Tracking
40+
41+
### Cache Property Change Event Args
42+
43+
Property Tracking can be used to update UI, track changes, and more. Invoking a property change event requires you to create a new `PropertyChangedEventArgs` and `PropertyChangingEventArgs` object. This can cause more allocations than necessary. Fortunately, all these objects are cached and reused in Scriptable Values to minimize allocations. However, when [creating your own types](/scriptable-values/guides/creating-custom-types) you should also cache your event args. `RuntimeScriptableObject.SetField` allows you to pass in your own event args to be used.
44+
45+
Scriptable Values will try to avoid creating these event args when possible, but it is still a good idea to cache them yourself. This will help reduce allocations and improve performance.
46+
47+
```csharp title="Cache Args" ins="currentValueChangingArgs, currentValueChangedArgs"
48+
using UnityEngine;
49+
using Hertzole.ScriptableValues;
50+
using System.ComponentModel;
51+
52+
[CreateAssetMenu]
53+
public class CustomType : RuntimeScriptableObject
54+
{
55+
private int currentValue;
56+
57+
public int CurrentValue
58+
{
59+
get { return currentValue; }
60+
set { SetField(ref currentValue, value, currentValueChangingArgs, currentValueChangedArgs); }
61+
}
62+
63+
// Cache the event args as static readonly fields
64+
// to avoid creating new instances every time.
65+
static readonly PropertyChangingEventArgs currentValueChangingArgs =
66+
new PropertyChangingEventArgs(nameof(CurrentValue));
67+
static readonly PropertyChangedEventArgs currentValueChangedArgs =
68+
new PropertyChangedEventArgs(nameof(CurrentValue));
69+
}
70+
```

0 commit comments

Comments
 (0)