# Verifying EventRefs in pre-build script

**URL:** https://qa.fmod.com/t/verifying-eventrefs-in-pre-build-script/16019
**Category:** Unity
**Tags:** unity
**Created:** [July 28, 2020, 2:16am UTC](https://qa.fmod.com/t/verifying-eventrefs-in-pre-build-script/16019 "2020-07-28T02:16:43Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![kyle\_n](https://avatars.discourse-cdn.com/v4/letter/k/7cd45c/32.png) [@kyle\_n](https://qa.fmod.com/u/kyle_n)
#### Post date: [July 28, 2020, 2:16am UTC](https://qa.fmod.com/t/verifying-eventrefs-in-pre-build-script/16019/1 "2020-07-28T02:16:43Z")

</div>

I’m wondering if there is any way to verify all EventRefs in a pre-build script?

If you change the path of an event in FMOD studio and don’t update the references in editor these events obviously wont play so I’m hoping for a way to find all the EventRefs and check that they are valid before doing a build.

Unless there’s already a way to do this I’m guessing this would require reflection to find all strings that have the [EventRef] attribute but I’m not really sure how to use reflection to do this. Hooking into the prebuild script I’m good with.

---

<div class="post-metadata">

### Author: ![cameron-fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/cameron-fmod/32/261_2.png) [@cameron-fmod](https://qa.fmod.com/u/cameron-fmod)
#### Post date: [August 4, 2020, 6:30am UTC](https://qa.fmod.com/t/verifying-eventrefs-in-pre-build-script/16019/2 "2020-08-04T06:30:10Z")

</div>

There isn’t currently a feature for this built in to the integration, you would have to do it manually. The `[EventRef]` objects are created in memory and attached to the `FMODStudioCache` object in the integration.

I have created a task to look into this further and see if it is something we can add.

---

<div class="post-metadata">

### Author: ![kyle\_n](https://avatars.discourse-cdn.com/v4/letter/k/7cd45c/32.png) [@kyle\_n](https://qa.fmod.com/u/kyle_n)
#### Post date: [August 4, 2020, 4:42pm UTC](https://qa.fmod.com/t/verifying-eventrefs-in-pre-build-script/16019/3 "2020-08-04T16:42:39Z")

</div>

Hi Cameron, thanks for looking in this.

I managed to create a bit of a solution using reflection. It’s not able to check every possible reference but it should work for our needs.

Basically I created a editor menu option to get every monobehaviour in the scene and check if it has a field with the [EventRef] attribute using reflection. Currently it only will find `string` or any `IEnumerable` of `string` (i.e. `string[]` or `List<string>`) with the attribute. Custom classes that have an [EventRef] attribute field wont be found. This could be done recursively but I didn’t want to deal with checking for cycles in the recursion and it wasn’t needed for our project currently. Once all the field with that attribute are found I use `EventManager.EventFromPath(ref)` to verify if it’s a valid reference.

Here’s a rough copy of the code:

```
foreach (GameObject gameObject in rootObjects)
            {
                MonoBehaviour[] allBehvaiours = gameObject.GetComponentsInChildren<MonoBehaviour>();

                for (int i = 0; i < allBehvaiours.Length; i++)
                {
                    Type componentType = allBehvaiours[i].GetType();

                    FieldInfo[] fields = componentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                    foreach (FieldInfo item in fields)
                    {
                        if (HasAttribute(item, typeof(EventRefAttribute)))
                        {
                            if (item.FieldType == typeof(string))
                            {
                                string output = item.GetValue(allBehvaiours[i]) as string;

                                if (!IsValidEventRef(output))
                                {
                                    Debug.LogError($"Unable to find FMOD Event {output} on object of type {componentType.ToString()} from gameobject {allBehvaiours[i].gameObject.name}");
                                    allValid = false;
                                }
                            }
                            else if (typeof(IEnumerable).IsAssignableFrom(item.FieldType))
                            {
                                foreach (var listItem in (IEnumerable)item.GetValue(allBehvaiours[i]))
                                {
                                    if (listItem.GetType() == typeof(string))
                                    {
                                        string listOutput = listItem as string;
                                        if (!IsValidEventRef(listOutput))
                                        {
                                                 Debug.LogError($"Unable to find FMOD Event {listOutput} on object 
                                                {valueObject.ToString()}");
                                        }
                            }
                                    }
                                }
                            }
                        }
                    }
                }
            }

```

And the helper functions:

```
private static bool HasAttribute(MemberInfo provider, params Type[] attributeTypes)
{
    Attribute[] allAttributes = Attribute.GetCustomAttributes(provider, typeof(Attribute), true);

    if (allAttributes.Length == 0)
        return false;

    return allAttributes.Where(a => attributeTypes.Any(x => a.GetType() == x || x.IsAssignableFrom(a.GetType()))).Any();
}

    public static bool IsValidEventRef(string reference)
    {
        if (string.IsNullOrEmpty(reference)) return true;

        EditorEventRef eventRef = EventManager.EventFromPath(reference);

        return eventRef != null;
    }

```

I hope that makes sense, it’s a lot of code to paste into this form. Not sure if it’s the best way but seems to work for finding event references that are not valid. (In the code I ignore empty event reference strings but that can be changed easily). I also have a method that takes a list of scriptable objects and does a similar check. The code is basically the same.

Let me know if you can think of an better way but maybe this will help anyone else looking for a similar solution.
