背景
使用CI/CD
构建unity
项目, shell
脚本调用npm script
拉起unity
后UnityEngin.Debug.Log
的输出只会展示在unity
的控制台里, 那么如何将其输出到终端以便监控其构建过程呢
解决方案
- 将要输出日志写入到
log.txt
文件
public static void Print(string str)
{
using (StreamWriter logFile = new StreamWriter('log.txt', true))
logFile.WriteLine($"[{DateTime.Now}] {str}");
UnityEngine.Debug.Log(str);
}
- 使用
node.js
监听log.txt
文件并打印到终端
要注意避免文件系统多次触发change
事件导致的重复打印, 另外要注意停止文件监听以便退出构建流程
代码如下
let watcher;
function unityConsoleLog() {
const fs = require("fs");
const readline = require("readline");
const path = require("path");
const filePath = path.join(__dirname, "log.txt");
let lastKnownPosition = 0;
// 检查文件是否存在
if (fs.existsSync(filePath)) {
// 文件存在,清空文件内容
fs.writeFile(filePath, "", (err) => {
if (err) {
console.error("Failed to clear file:", err);
} else {
console.log(filePath + " File content has been cleared.");
}
});
} else {
// 文件不存在,创建文件
fs.writeFile(filePath, "", (err) => {
if (err) {
console.error("Failed to create file:", err);
} else {
console.log(filePath + " File has been created.");
}
});
}
let processing = false;
let lastLineHashes = new Set();
function readNewLines(start) {
const stream = fs.createReadStream(filePath, {
start: start,
encoding: "utf8",
});
const rl = readline.createInterface({
input: stream,
output: process.stdout,
terminal: false,
});
processing = true;
rl.on("line", (line) => {
const lineHash = hashLine(line);
if (!lastLineHashes.has(lineHash)) {
console.log("Unity Build Log: ", line);
lastLineHashes.add(lineHash);
}
});
rl.on("close", () => {
lastKnownPosition = fs.statSync(filePath).size;
processing = false;
});
}
function hashLine(line) {
let hash = 0;
for (let i = 0; i < line.length; i++) {
let char = line.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash |= 0;
}
return hash;
}
watcher = fs.watch(filePath, (eventType, filename) => {
if (eventType === "change" && !processing) {
readNewLines(lastKnownPosition);
}
});
// Initialize the start of the file watching
fs.stat(filePath, (err, stats) => {
if (err) {
console.error("File not found:", err);
return;
}
lastKnownPosition = stats.size;
});
}
function stopUnityConsoleLog() {
if (watcher) {
watcher.close();
console.log("Stopped watching file.");
} else {
console.log("No watcher to stop.");
}
}