{"id":18043714,"url":"https://github.com/roytheunissen/fmod-syntax","last_synced_at":"2026-02-23T23:37:43.156Z","repository":{"id":196051022,"uuid":"691256749","full_name":"RoyTheunissen/FMOD-Syntax","owner":"RoyTheunissen","description":"Generates code to allow invoking FMOD events with a strongly-typed syntax.","archived":false,"fork":false,"pushed_at":"2025-12-17T12:52:31.000Z","size":1124,"stargazers_count":38,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-12-18T17:11:18.489Z","etag":null,"topics":["fmod","fmod-studio","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RoyTheunissen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-13T20:08:15.000Z","updated_at":"2025-12-17T12:51:56.000Z","dependencies_parsed_at":"2024-02-01T11:38:07.992Z","dependency_job_id":"a1537044-0bea-4e4f-b9f5-1ed40468821d","html_url":"https://github.com/RoyTheunissen/FMOD-Syntax","commit_stats":null,"previous_names":["roytheunissen/fmod-syntax"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/RoyTheunissen/FMOD-Syntax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyTheunissen%2FFMOD-Syntax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyTheunissen%2FFMOD-Syntax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyTheunissen%2FFMOD-Syntax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyTheunissen%2FFMOD-Syntax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RoyTheunissen","download_url":"https://codeload.github.com/RoyTheunissen/FMOD-Syntax/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyTheunissen%2FFMOD-Syntax/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29760808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T21:02:23.375Z","status":"ssl_error","status_checked_at":"2026-02-23T20:58:31.539Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fmod","fmod-studio","unity"],"created_at":"2024-10-30T17:09:32.568Z","updated_at":"2026-02-23T23:37:43.133Z","avatar_url":"https://github.com/RoyTheunissen.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Roy Theunissen](Documentation~/Github%20Header.jpg)](http://roytheunissen.com)\n[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](LICENSE.md)\n![GitHub Follow](https://img.shields.io/github/followers/RoyTheunissen?label=RoyTheunissen\u0026style=social)\n\u003ca href=\"https://roytheunissen.com\" target=\"blank\"\u003e\u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/globe_dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/globe_light.png\"\u003e\n    \u003cimg alt=\"globe\" src=\"globe_dark.png\" width=\"20\" height=\"20\" /\u003e\n\u003c/picture\u003e\u003c/a\u003e\n\u003ca href=\"https://bsky.app/profile/roytheunissen.com\" target=\"blank\"\u003e\u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/bluesky_dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/bluesky_light.png\"\u003e\n    \u003cimg alt=\"bluesky\" src=\"bluesky_dark.png\" width=\"20\" height=\"20\" /\u003e\n\u003c/picture\u003e\u003c/a\u003e\n\u003ca href=\"https://www.youtube.com/c/r_m_theunissen\" target=\"blank\"\u003e\u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/youtube_dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/youtube_light.png\"\u003e\n    \u003cimg alt=\"youtube\" src=\"youtube_dark.png\" width=\"20\" height=\"20\" /\u003e\n\u003c/picture\u003e\u003c/a\u003e \n\u003ca href=\"https://www.tiktok.com/@roy_theunissen\" target=\"blank\"\u003e\u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/tiktok_dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/RoyTheunissen/RoyTheunissen/raw/master/tiktok_light.png\"\u003e\n    \u003cimg alt=\"tiktok\" src=\"tiktok_dark.png\" width=\"20\" height=\"20\" /\u003e\n\u003c/picture\u003e\u003c/a\u003e\n\n_Generates code to allow invoking FMOD events with a strongly-typed syntax._\n\n## About the Project\n\nOut-of-the-box FMOD requires you to access events and parameters via inspector references or by name.\nNeither of these setups is ideal.\n\nDispatching an event this way requires you to define a bunch of fields, assign things in the inspector, and then the syntax for setting parameters is weakly-typed.\nYou can skip some of this by dispatching events/setting parameters by name but that has the drawback that you need to look up what the name is and it's very hard and error-prone to rename anything as it'll break references.\n\nFor ease of use it's preferable if FMOD events and parameters are accessed in a strongly-typed way such that they're known at compile-time. Maybe something like this:\n\n```cs\nAudioEvents.PlayerJump.Play(transform);\n```\n\nThis would require a little bit of code generation, and that's where `FMOD-Syntax` comes in. With a simple setup wizard and one line of code in your audio service for culling expired events you can start dispatching FMOD events with parameters in as little as one line of code.\n\n![Example](Documentation~/Generated%20Code%20Files.png)\n\nThis setup allows events and parameters to be renamed gracefully as you can do it via your IDE, update your banks accordingly and then re-generate the code. If events are renamed in the banks and you still reference those events by their old names, warnings will be thrown to give you a chance to refactor without immediately getting compile errors.\n\nOverall this system significantly speeds up your audio implementation workflow and makes it more robust, at the expense of a little bit of boilerplate code that you won't even have to maintain yourself.\n\n## Getting Started\n\n- Install the package to your Unity project\n- The Setup Wizard will pop up and allow you to specify where and how to create the settings file \u0026 save generated code files\n- Configure the system as desired and press Initialize\n- Use `FMOD \u003e Generate FMOD Code` or `CTRL+ALT+G` to generate the FMOD code\n- Cull expired FMOD playback instances by calling `FmodSyntaxSystem.CullPlaybacks();` in an `Update` loop somewhere. I recommend putting this in your audio service.\n- You can now fire your FMOD events in a strongly typed way\n\n## How to use\n\n### One-offs\n```cs\n// Parameterless one-off sound (global)\nAudioEvents.TestOneOff.Play();\n\n// Parameterless one-off sound (spatialized)\nAudioEvents.TestOneOff.Play(transform);\n\n// Spatialized one-off with parameters\nAudioEvents.Footstep.Play(transform, FootstepPlayback.SurfaceValues.Generic);\n```\n\n### Loops\n```cs\n// Start a looping sound\nTestContinuousPlayback testContinuousPlayback = AudioEvents.TestContinuous.Play(transform);\n\n// Set the parameter on a looping sound\nfloat value = Mathf.Sin(Time.time * Mathf.PI * 1.0f).Map(-1, 1);\ntestContinuousPlayback.Strength.Value = value;\n\n// Stop a looping sound\ntestContinuousPlayback?.Stop();\n\n// Cancel a looping sound in OnDestroy\ntestContinuousPlayback?.Cleanup();\n```\n\n### Global Parameters\n```cs\n// Setting global parameters\nAudioGlobalParameters.PlayerSpeed.Value = value;\n```\n\n### Dispatching a parameterless event that is chosen via the inspector\n```cs\n// Get a reference to the event that you can assign via the inspector\n[SerializeField] private AudioConfigReference parameterlessAudio;\n\n// Dispatch as per usual\nparameterlessAudio.Play(transform);\n```\n\n### Labeled parameter enums\nIn FMOD there are three types of parameters: \"Continuous\" (`int`), \"Discrete\" (`float`) and \"Labeled\" (`enum`).\n\nLabeled parameters are sent and received as integers, but they are associated with a name for convenience, exactly like enums in C#.\n\n![image](https://github.com/RoyTheunissen/FMOD-Syntax/assets/3997055/280da27d-abde-4faf-b260-0a2591ea4d29)\n\nFor convenience, FMOD Syntax generates an enum for every event with a labeled parameter, so auto-complete conveniently suggests all valid values when you are invoking the event.\n\n```cs\nAudioEvents.Footstep.Play(transform, FootstepPlayback.SurfaceValues.Generic);\n```\n\nBut let's say you have several events that share the same \"Surface\" parameter, for instance a Jump and a Footstep event.\nIt could be inconvenient if you just want to determine the current surface type, and then fire jump and footstep events with that type,\nbecause you would have to cast it to the appropriate event-specific enum.\n\n```cs\nAudioEvents.Footstep.Play(transform, FootstepPlayback.SurfaceValues.Generic);\nAudioEvents.Jump.Play(transform, JumpPlayback.SurfaceValues.Generic);\n```\n\nFurthermore, the enums in FMOD may actually represent an enum in your game. So it's inconvenient to have to map from that game enum to the FMOD enum. But there's a solution for that: **User-specified labeled parameter enums**.\n\nSimply tag your game enum with `[FmodLabelType]` and specify the names of the labeled parameters that it represents, and then when code is generated instead of generating event-specific enums, it uses the game enum you specified for those events.\n\nNo more duplication, no more mapping.\n\n```cs\n[FmodLabelType(\"Surface\")]\npublic enum SurfaceTypes\n{\n    Generic,\n    Dirt,\n    Rock,\n}\n```\n```cs\nAudioEvents.Footstep.Play(transform, SurfaceTypes.Generic);\nAudioEvents.Jump.Play(transform, SurfaceTypes.Generic);\n```\n#### Scriptable Object Collection Support\n\nThe above 'Labeled parameter enums' feature now also works for the [Scriptable Object Collection](https://github.com/brunomikoski/ScriptableObjectCollection). Simply add the `[FmodLabelType]` attribute to the Scriptable Object Collection Item the same way you would with an enum.\n\n\u003e [!IMPORTANT]  \n\u003e If you installed FMOD-Syntax or ScriptableObjectCollection to the `Assets` folder instead of via the Package Manager / in the Packages folder, a `SCRIPTABLE_OBJECT_COLLECTION` scripting define symbol will not be defined automatically and you will have to manually add this to the project settings for this feature to work._\n\n\n\n### Moving/renaming Events\nFMOD-Syntax has a two-tiered solution for allowing you to move/rename events in FMOD and update your code accordingly:\n- **Alias Generation** - When an event is detected as having been moved or renamed, 'aliases' are generated under the old name, tagged with an `[Obsolete]` attribute that informs you what the event is currently called. This causes the game to throw a compile warning everywhere that the old incorrect syntax is used, and you can copy/paste the correct name from the warning. This lets you manually migrate your event code without compile errors and with reminders for what the new syntax is.\n- **Auto-Refactoring** - When an event is detected has having been moved or renamed, you are also presented with the option to Auto-Refactor. If chosen, FMOD-Syntax will look through your .cs files, find any references to the old events and automatically refactor them to use the new event syntax.\n\n### Syntax Formats\nFMOD-Syntax provides three syntax formats for defining events:\n- **Flat**: All events are defined in `AudioEvents`. Simplest / shortest syntax, but event names have to be unique.\u003cbr /\u003e\n  An event called `Player/Footstep` is invoked via `AudioEvents.Footstep.Play();`\n- **Flat (With Path Included In Name)**: Slightly longer names, but event names don't have to be unique. Requested by @AldeRoberge \u003cbr/\u003e\n  An event called `Player/Footstep` is invoked via `AudioEvents.Player_Footstep.Play();`\n- **Subclasses Per Folder**: Subclasses are generated inside the `AudioEvents` class for every folder holding their events. Longer syntax, but events are neatly organized and names don't have to be unique.\n  An event called `Player/Footstep` is invoked via `AudioEvents.Player.Footstep.Play();`\n\nThe default syntax is `Flat`, and you are recommended to use that and give unique names to your events.\n\nFor example, you can use the following naming convention: `Object_Event`. That way you can have a footstep event for both a player and a monster without getting a name clash, and it doesn't matter if the event is in a folder called `Core/World1/Gameplay/Characters/Enemies/Monster/Monster_Footstep`, because including all those folders in the name is cumbersome.\n\nHowever, as you may be integrating FMOD-Syntax into an existing project and may not have the ability to affect the naming convention of events much, we recognize that different projects have different structures and you are free to choose whatever syntax suits your project best.\n\nSwitching syntax formats supports all the same migration features as renaming or moving events.\n\n#### Miscellaneous Features\n\n- Code is also generated for playing Snapshots. Basically treated like events, though it's separated in its own `AudioSnapshots` class.\n- Code is also generated for Buses and VCA's, which can be accessed via an `AudioBuses` and `AudioVCAs` class respectively.\n\n## Compatibility\n\nThis system was developed for Unity 2021 and upwards, it's recommended that you use it for these versions.\n\nIf you use an older version of Unity and are running into trouble, feel free to reach out and I'll see what I can do.\n\n## Known Issues\n- There is a setup for automatically regenerating the code when the FMOD banks update, but this would require you to modify the FMOD Unity plugin so that feature is currently disabled.\n\n\n## Installation\n\n### Package Manager\n\nGo to `Edit \u003e Project Settings \u003e Package Manager`. Under 'Scoped Registries' make sure there is an OpenUPM entry.\n\nIf you don't have one: click the `+` button and enter the following values:\n\n- Name: `OpenUPM` \u003cbr /\u003e\n- URL: `https://package.openupm.com` \u003cbr /\u003e\n\nThen under 'Scope(s)' press the `+` button and add `com.roytheunissen`.\n\nIt should look something like this: \u003cbr /\u003e\n![image](https://user-images.githubusercontent.com/3997055/185363839-37b3bb3d-f70c-4dbd-b30d-cc8a93b592bb.png)\n\n\u003cbr /\u003e\nAll of my packages will now be available to you in the Package Manager in the 'My Registries' section and can be installed from there.\n\u003cbr /\u003e\n\n\n### Git Submodule\n\nYou can check out this repository as a submodule into your project's Assets folder. This is recommended if you intend to contribute to the repository yourself.\n\n### OpenUPM\nThe package is available on the [openupm registry](https://openupm.com). It's recommended to install it via [openupm-cli](https://github.com/openupm/openupm-cli).\n\n```\nopenupm add com.roytheunissen.fmod-syntax\n```\n\n### Manifest\nYou can also install via git URL by adding this entry in your **manifest.json** (make sure to end with a comma if you're adding this at the top)\n\n```\n\"com.roytheunissen.fmod-syntax\": \"https://github.com/RoyTheunissen/FMOD-Syntax.git\"\n```\n\n### Unity Package Manager\nFrom Window-\u003ePackage Manager, click on the + sign and Add from git: \n```\nhttps://github.com/RoyTheunissen/FMOD-Syntax.git\n```\n\n\n## Contact\n[Roy Theunissen](https://roytheunissen.com)\n\n[roy.theunissen@live.nl](mailto:roy.theunissen@live.nl)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froytheunissen%2Ffmod-syntax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froytheunissen%2Ffmod-syntax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froytheunissen%2Ffmod-syntax/lists"}