Skip to content

Commit 3a2e042

Browse files
fix linux FMOD errors (#41)
2 parents 969a683 + 78caa36 commit 3a2e042

2 files changed

Lines changed: 52 additions & 21 deletions

File tree

src/unity-editor.ts

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -269,29 +269,26 @@ export class UnityEditor {
269269
throw new Error(`Cannot execute Unity ${this.version.toString()} on Apple Silicon Macs.`);
270270
}
271271

272+
const linuxEnvOverrides = process.platform === 'linux'
273+
? await this.prepareLinuxAudioEnvironment()
274+
: undefined;
275+
const baseEditorEnv: NodeJS.ProcessEnv = {
276+
...process.env,
277+
UNITY_THISISABUILDMACHINE: '1',
278+
...(linuxEnvOverrides ?? {})
279+
};
280+
272281
if (process.platform === 'linux' &&
273282
!command.args.includes('-nographics')
274283
) {
275-
// On Linux, force Unity to run under Xvfb and provide a dummy audio driver
276-
// to prevent FMOD from failing to initialize the output device when no
277-
// actual audio device is present (common in CI/container environments).
278-
const linuxEnv = {
279-
...process.env,
280-
DISPLAY: ':99',
281-
UNITY_THISISABUILDMACHINE: '1',
282-
// Tell various audio systems to use a dummy/out-of-process driver
283-
SDL_AUDIODRIVER: process.env.SDL_AUDIODRIVER || 'dummy',
284-
AUDIODRIVER: process.env.AUDIODRIVER || 'dummy',
285-
AUDIODEV: process.env.AUDIODEV || 'null',
286-
// For PulseAudio: point to an invalid socket to avoid connecting
287-
PULSE_SERVER: process.env.PULSE_SERVER || '/tmp/invalid-pulse-socket'
288-
};
289-
290284
unityProcess = spawn(
291285
'xvfb-run',
292286
[this.editorPath, ...command.args], {
293287
stdio: ['ignore', 'ignore', 'ignore'],
294-
env: linuxEnv
288+
env: {
289+
...baseEditorEnv,
290+
DISPLAY: baseEditorEnv.DISPLAY || ':99'
291+
}
295292
});
296293
} else if (process.arch === 'arm64' &&
297294
process.platform === 'darwin' &&
@@ -311,10 +308,7 @@ export class UnityEditor {
311308
this.editorPath,
312309
command.args, {
313310
stdio: ['ignore', 'ignore', 'ignore'],
314-
env: {
315-
...process.env,
316-
UNITY_THISISABUILDMACHINE: '1'
317-
}
311+
env: baseEditorEnv
318312
});
319313
}
320314

@@ -394,6 +388,43 @@ export class UnityEditor {
394388
return path.join(logsDir, `${prefix ? prefix + '-' : ''}Unity-${timestamp}.log`);
395389
}
396390

391+
private async prepareLinuxAudioEnvironment(): Promise<NodeJS.ProcessEnv> {
392+
if (process.platform !== 'linux') {
393+
return {};
394+
}
395+
396+
const envOverrides: NodeJS.ProcessEnv = {
397+
SDL_AUDIODRIVER: process.env.SDL_AUDIODRIVER || 'dummy',
398+
AUDIODRIVER: process.env.AUDIODRIVER || 'dummy',
399+
AUDIODEV: process.env.AUDIODEV || 'null',
400+
ALSA_CARD: process.env.ALSA_CARD || 'Loopback',
401+
PULSE_SINK: process.env.PULSE_SINK || 'unity_dummy'
402+
};
403+
404+
const defaultRuntimeDir = `/run/user/${typeof process.getuid === 'function' ? process.getuid() : 1000}`;
405+
const runtimeDir = process.env.XDG_RUNTIME_DIR || defaultRuntimeDir;
406+
envOverrides.XDG_RUNTIME_DIR = runtimeDir;
407+
408+
try {
409+
await fs.promises.mkdir(runtimeDir, { recursive: true, mode: 0o700 });
410+
} catch (error) {
411+
this.logger.debug(`Failed to ensure XDG_RUNTIME_DIR (${runtimeDir}): ${error}`);
412+
}
413+
414+
await this.tryExec('bash', ['-c', 'pulseaudio --check 2>/dev/null || pulseaudio --start --exit-idle-time=-1 || true']);
415+
await this.tryExec('bash', ['-c', 'command -v pactl >/dev/null 2>&1 && { pactl list short sinks 2>/dev/null | grep -q unity_dummy || pactl load-module module-null-sink sink_name=unity_dummy sink_properties=device.description=UnityCI >/tmp/unity-null-sink.id; } || true']);
416+
417+
return envOverrides;
418+
}
419+
420+
private async tryExec(command: string, args: string[]): Promise<void> {
421+
try {
422+
await Exec(command, args, { silent: true, showCommand: false });
423+
} catch (error) {
424+
this.logger.debug(`Skipped helper command "${command} ${args.join(' ')}": ${error}`);
425+
}
426+
}
427+
397428
/**
398429
* Get the root path of the Unity Editor installation based on the provided editor path.
399430
* @param editorPath The path to the Unity Editor executable.

src/unity-hub.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ wget -qO - https://hub.unity3d.com/linux/keys/public | gpg --dearmor | tee /usr/
446446
echo "deb [signed-by=/usr/share/keyrings/Unity_Technologies_ApS.gpg] https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unityhub.list
447447
echo "deb https://archive.ubuntu.com/ubuntu jammy main universe" | tee /etc/apt/sources.list.d/jammy.list
448448
apt-get update
449-
apt-get install -y --no-install-recommends unityhub${version ? '=' + version : ''} ffmpeg libgtk2.0-0 libglu1-mesa libgconf-2-4 libncurses5
449+
apt-get install -y --no-install-recommends unityhub${version ? '=' + version : ''} ffmpeg libgtk2.0-0 libglu1-mesa libgconf-2-4 libncurses5 pulseaudio
450450
apt-get clean
451451
sed -i 's/^\\(.*DISPLAY=:.*XAUTHORITY=.*\\)\\( "\\$@" \\)2>&1$/\\1\\2/' /usr/bin/xvfb-run
452452
printf '#!/bin/bash\nxvfb-run --auto-servernum /opt/unityhub/unityhub "$@" 2>/dev/null' | tee /usr/bin/unity-hub >/dev/null

0 commit comments

Comments
 (0)