UBT.nvim
is a plugin to asynchronously execute Unreal Engine tasks such as building, header generation (UHT), compile_commands.json
generation, project file generation, and static analysis directly from Neovim.
Check out other plugins to enhance Unreal Engine development: (UEP.nvim
, UCM.nvim
, ULG.nvim
, neo-tree-unl.nvim
, tree-sitter-unreal-cpp).
.
English | ζ₯ζ¬θͺ
- Asynchronous Execution: Runs Unreal Build Tool asynchronously in the background using only Neovim's native functions (
vim.fn.jobstart
). - Flexible Configuration System:
- Based on the powerful configuration system of
UNL.nvim
, allowing project-specific settings via a.unlrc.json
file in the project root to override global settings.
- Based on the powerful configuration system of
- Rich UI Feedback: Integrates with fidget.nvim to display real-time build progress. (Optional)
- Unified UI Picker: Automatically detects popular UI plugins like telescope.nvim and fzf-lua to provide a consistent user experience. (Optional)
- Fuzzy search for build errors and warnings, preview them, and jump to the corresponding file and line with a single key press.
- Select build targets from your familiar UI picker.
- The integration with
fzf-lua
uses Lua coroutines, preventing the UI from freezing even when opening large diagnostic logs.
- Accelerated by Incremental Updates: Automatically detects the manifest file (
.uhtmanifest
) when running the Unreal Header Tool (GenHeader
) to perform incremental updates for faster header generation.
- Neovim v0.11.3 or later
- UNL.nvim (Required)
- telescope.nvim (Optional)
- fzf-lua (Optional)
- fidget.nvim (Optional)
- An environment where Unreal Build Tool is available (e.g.,
dotnet
command) - Visual Studio 2022 (including the Clang toolchain)
- Windows (Operation on other operating systems is not currently tested)
Install with your favorite plugin manager.
UNL.nvim
is a required dependency. lazy.nvim
will resolve this automatically.
-- lua/plugins/ubt.lua
return {
'taku25/UBT.nvim',
-- UBT.nvim depends on UNL.nvim.
-- This line is usually not necessary as lazy.nvim resolves it automatically.
dependencies = { 'taku25/UNL.nvim' },
-- If you use autocmd (automation), eager loading is recommended.
-- lazy = false,
opts = {
-- Add your settings here (details below)
}
}```
## βοΈ Configuration
You can customize the plugin's behavior by passing a table to the `setup()` function (or to `opts` in `lazy.nvim`).
Below are all the available options with their default values.
```lua
-- Inside init.lua or opts = { ... } for ubt.lua
{
-- Presets for build target definitions
presets = {
-- Presets for Win64 are provided by default.
-- You can add your own presets or override existing ones.
-- e.g., { name = "LinuxShipping", Platform = "Linux", IsEditor = false, Configuration = "Shipping" },
},
-- Default target when target name is omitted in :UBT Build or :UBT GenCompileDB
preset_target = "Win64DevelopWithEditor",
-- Default linter type when omitted in :UBT Lint
lint_type = "Default",
-- Usually auto-detected, but you can use this to explicitly specify the engine path
engine_path = nil,
-- Filename for UBT to write diagnostic logs (errors and warnings)
progress_file_name = "progress.log",
-- ===== UI and Logging Settings (Inherited from UNL.nvim) =====
-- Behavior settings for UI pickers (Telescope, fzf-lua, etc.)
ui = {
picker = {
mode = "auto", -- "auto", "telescope", "fzf_lua", "native"
prefer = { "telescope", "fzf_lua", "native" },
},
progress = {
mode = "auto", -- "auto", "fidget", "window", "notify"
},
},
-- Detailed logging settings
logging = {
level = "info", -- Minimum level to write to the log file
echo = { level = "warn" },
notify = { level = "error", prefix = "[UBT]" },
file = {
enable = true,
filename = "ubt.log", -- Log file for the entire plugin's operations
},
},
}
You can define settings that are only active for a specific project by creating a JSON file named .unlrc.json
in the project's root directory (where the .uproject
file is located). These settings will take precedence over global settings.
Example: .unlrc.json
{
"preset_target": "LinuxShipping",
"engine_path": "D:/UE_Custom/UE_5.4_Linux",
"presets": [
{
"name": "LinuxShipping",
"Platform": "Linux",
"IsEditor": false,
"Configuration": "Shipping"
}
]
}
Run the commands within an Unreal Engine project directory.
:UBT build[!] [target_name] " Builds the project. Use [!] to launch the UI picker.
:UBT run[!] " Runs the project. Default opens the editor. Use [!] to launch the UI picker to run a specific preset.
:UBT genHeader[!] [target_name] [module_name] " Runs the Unreal Header Tool. Use [!] for UI picker. Module name is optional.
:UBT genCompileDB[!] [target_name] " Generates compile_commands.json. Use [!] to launch the UI picker.
:UBT diagnostics " Displays errors and warnings from the last build in the UI picker.
:UBT genProject " Generates project files for Visual Studio, etc.
:UBT lint [linter_type] [target_name] " Runs static analysis.
UBT.nvim
automatically uses telescope.nvim
or fzf-lua
according to your setup.
The UI picker can be opened by running the bang
version (!
) of the following commands, or by using the Diagnostics
command.
:UBT build!
:UBT run!
:UBT genheader!
:UBT gencompiledb!
:UBT diagnostics
UBT.nvim
provides a Lua API, allowing you to streamline your development workflow by combining it with autocmd
.
For more details, see :help ubt.txt
.
When you open an Unreal Engine source file, this automatically changes the current directory to the project root of that file (the directory containing the .uproject
file).
-- init.lua or any setup file
local ubt_auto_cd_group = vim.api.nvim_create_augroup("UBT_AutoCD", { clear = true })
vim.api.nvim_create_autocmd("BufEnter", {
group = ubt_auto_cd_group,
pattern = { "*.cpp", "*.h", "*.hpp", "*.cs" },
callback = function(args)
local ok, ubt_api = pcall(require, "UBT.api")
if not (ok and ubt_api) then return end
local project_root = ubt_api.find_project_root(args.file)
if project_root and project_root ~= vim.fn.getcwd() then
vim.cmd.cd(project_root)
end
end,
})
Automatically runs :UBT GenProject
when you save a C++ header (.h
) or source (.cpp
) file.
Note: Hooking heavy processes like building can impact performance.
-- init.lua or any setup file
local ubt_auto_gen_proj_group = vim.api.nvim_create_augroup("UBT_AutoGenerateProject", { clear = true })
vim.api.nvim_create_autocmd("BufWritePost", {
group = ubt_auto_gen_proj_group,
pattern = { "*.cpp", "*.h", "*.hpp" },
callback = function()
local ok, ubt_api = pcall(require, "UBT.api")
if not (ok and ubt_api) then return end
if ubt_api.find_project_root(vim.fn.getcwd()) then
ubt_api.gen_project()
end
end,
})
Unreal Engine related plugins:
MIT License
Copyright (c) 2025 taku25
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.