Skip to content

Instantly share code, notes, and snippets.

@shivaduke28
Last active May 6, 2023 06:22
Show Gist options
  • Save shivaduke28/5f84131d395ebd9f7ee1aaa9a0e47659 to your computer and use it in GitHub Desktop.
Save shivaduke28/5f84131d395ebd9f7ee1aaa9a0e47659 to your computer and use it in GitHub Desktop.
A dirty code to replace LightingDataAsset field of SceneAsset directly
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
public static class LightingDataAssetReplacer
{
public static async Task ReplaceAsync(SceneAsset sceneAsset, LightingDataAsset lightingDataAsset, CancellationToken cancellationToken)
{
var assetPath = AssetDatabase.GetAssetPath(sceneAsset);
var objectId = GlobalObjectId.GetGlobalObjectIdSlow(lightingDataAsset);
var replacedLine = lightingDataAsset == null
? " m_LightingDataAsset: {fileID: 0}"
: $" m_LightingDataAsset: {{fileID: {objectId.targetObjectId.ToString()}, guid: {objectId.assetGUID.ToString()}, type: 2}}";
var stringBuilder = new StringBuilder();
var encoding = new UTF8Encoding(false); // without BOM
var dstPath = assetPath + ".txt";
var newline = await DetectNewlineAsync(assetPath, cancellationToken);
using (var fs = File.Open(assetPath, FileMode.Open, FileAccess.ReadWrite))
using (var dst = File.Open(dstPath, FileMode.OpenOrCreate, FileAccess.Write))
using (var reader = new StreamReader(fs, encoding))
using (var writer = new StreamWriter(dst, encoding))
{
try
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
cancellationToken.ThrowIfCancellationRequested();
if (line.StartsWith(" m_LightingDataAsset"))
{
var before = stringBuilder.ToString();
await writer.WriteAsync(before);
await writer.WriteAsync(replacedLine + newline);
await writer.FlushAsync();
var beforeByteCount = encoding.GetByteCount(before);
var originalByteCount = beforeByteCount + encoding.GetByteCount(line + newline);
if (!reader.EndOfStream)
{
var nextLine = await reader.ReadLineAsync();
if (nextLine.StartsWith(" "))
{
originalByteCount += encoding.GetByteCount(nextLine + newline);
}
}
fs.Position = originalByteCount;
await fs.CopyToAsync(dst, 81920, cancellationToken);
await dst.FlushAsync(cancellationToken);
break;
}
stringBuilder.Append(line + newline);
}
}
catch (Exception)
{
if (File.Exists(dstPath))
{
File.Delete(dstPath);
}
throw;
}
}
var backup = assetPath + ".bac";
File.Replace(dstPath, assetPath, backup);
AssetDatabase.ImportAsset(assetPath);
}
const char CR = '\r';
const char LF = '\n';
static async Task<string> DetectNewlineAsync(string assetPath, CancellationToken cancellationToken)
{
using (var fs = File.Open(assetPath, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[128];
int byteRead;
var returnSeen = false;
while ((byteRead = await fs.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
{
for (var i = 0; i < byteRead; i++)
{
var ch = (char) buffer[i];
switch (ch)
{
case CR:
returnSeen = true;
break;
case LF:
return returnSeen ? "\r\n" : "\n";
}
}
}
throw new ArgumentException("Newline is not found.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment