diff --git a/Scriptable Variables/Variables/Base Types/ListScriptableVariable.cs b/Scriptable Variables/Variables/Base Types/ListScriptableVariable.cs
index 8e2889a7e31c6ac65025dfadae453a4d94abf1a3..cacbd071797d5a08b5618b23fc66fdd600b59986 100644
--- a/Scriptable Variables/Variables/Base Types/ListScriptableVariable.cs	
+++ b/Scriptable Variables/Variables/Base Types/ListScriptableVariable.cs	
@@ -14,118 +14,129 @@ namespace Shared.ScriptableVariables {
     [Tooltip("The default value of the variable to go back to on Reset")]
     public List<T> defaultList = new List<T>();
 
-    public delegate void ValueChangeHandler();
-    public event ValueChangeHandler OnValueChanged;
+    public delegate void ListChangeHandler();
+    public event ListChangeHandler OnListChanged;
+
+    public delegate void ListItemChangeHandler(int index, T item);
+    public event ListItemChangeHandler OnListItemChanged;
 
     //////////////////////////////// LIST MODIFIERS /////////////////////////////
+    public T this[int index] {
+      get { return list[index]; }
+      set {
+        list[index] = value;
+        ListItemChanged(index, value);
+      }
+    }
+
     //---------------------------------------------------------------------------
     public void Reset() {
       list = new List<T>(defaultList);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Set(List<T> other) {
       list.Clear();
       list.AddRange(other);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Clear() {
       list.Clear();
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Add(T value) {
       list.Add(value);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void AddRange(List<T> otherList) {
       list.AddRange(otherList);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Insert(int index, T item) {
       list.Insert(index, item);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void InsertRange(int index, IEnumerable<T> collection) {
       list.InsertRange(index, collection);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Remove(T value) {
       list.Remove(value);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public int RemoveAll(Predicate<T> match) {
       var removedCount = list.RemoveAll(match);
-      ValueChanged();
+      ListChanged();
       return removedCount;
     }
 
     //---------------------------------------------------------------------------
     public void RemoveAt(int index) {
       list.RemoveAt(index);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void RemoveRange(int index, int count) {
       list.RemoveRange(index, count);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Reverse(int index, int count) {
       list.Reverse(index, count);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Reverse() {
       list.Reverse();
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Sort(Comparison<T> comparison) {
       list.Sort(comparison);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Sort(int index, int count, IComparer<T> comparer) {
       list.Sort(index, count, comparer);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Sort() {
       list.Sort();
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void Sort(IComparer<T> comparer) {
       list.Sort(comparer);
-      ValueChanged();
+      ListChanged();
     }
 
     //---------------------------------------------------------------------------
     public void TrimExcess() {
       list.TrimExcess();
-      ValueChanged();
+      ListChanged();
     }
 
     //////////////////////////////// LIST ACCESSORS /////////////////////////////
@@ -134,6 +145,9 @@ namespace Shared.ScriptableVariables {
       get { return list.AsReadOnly(); }
     } 
 
+    //---------------------------------------------------------------------------
+    public int Count { get { return list.Count; } }
+
     //---------------------------------------------------------------------------
     public int BinarySearch(T item) {
       return list.BinarySearch(item);
@@ -265,10 +279,32 @@ namespace Shared.ScriptableVariables {
     }
     
     //---------------------------------------------------------------------------
-    protected void ValueChanged() {
-      if (OnValueChanged != null) {
-        OnValueChanged.Invoke();
-      }
+    // This function is public so that users can fire it in the specific cases
+    // where the ListScriptableVariable has no idea that aspects of an item in the
+    // list has changed
+    //
+    // For example, if the item type is a reference type, then when a field/property
+    // of an item changes, the list can't know.
+    //
+    // list[index].field = value;
+    //
+    // So the user of the ListScriptableVariable needs to call this function so
+    // the anyone who cares can be notified:
+    //
+    // list[index].field = value;
+    // list.ListItemChanged(index, list[index]);
+    //
+    // If a user sets the item directly with the index, this function automatically
+    // gets called
+    //
+    // list[index] = value;
+    public void ListItemChanged(int index, T item) {
+      OnListItemChanged?.Invoke(index, item);
+    }
+
+    //---------------------------------------------------------------------------
+    protected void ListChanged() {
+      OnListChanged?.Invoke();
     }
 
 #if UNITY_EDITOR
@@ -280,9 +316,7 @@ namespace Shared.ScriptableVariables {
         base.OnInspectorGUI();
         if (UnityEditor.EditorGUI.EndChangeCheck()) {
           var scriptableVariable = target as ListScriptableVariable<T>;
-          if (scriptableVariable.OnValueChanged != null) {
-            scriptableVariable.OnValueChanged.Invoke();
-          }
+          scriptableVariable.ListChanged();
         }
       }
     }