Compare commits
14 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
12dd5d8685 | |
|
|
feb8ed3206 | |
|
|
6939d16b6c | |
|
|
ca143691aa | |
|
|
f62a2fedb0 | |
|
|
2effa79f6d | |
|
|
1a23268b03 | |
|
|
e5c3bfa184 | |
|
|
9bb1b6054e | |
|
|
ef0db32fc1 | |
|
|
f0230149ce | |
|
|
0401d638a1 | |
|
|
4ea1798700 | |
|
|
eee3dbaa69 |
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace HybridCLR.Editor.ABI
|
namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
|
|
@ -74,6 +75,10 @@ namespace HybridCLR.Editor.ABI
|
||||||
case ElementType.ValueType:
|
case ElementType.ValueType:
|
||||||
{
|
{
|
||||||
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef();
|
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef();
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"type:{type} 未能找到定义。请尝试 `HybridCLR/Genergate/LinkXml`,然后Build一次生成AOT dll,再重新生成桥接函数");
|
||||||
|
}
|
||||||
if (typeDef.IsEnum)
|
if (typeDef.IsEnum)
|
||||||
{
|
{
|
||||||
return CreateTypeInfo(typeDef.GetEnumUnderlyingType());
|
return CreateTypeInfo(typeDef.GetEnumUnderlyingType());
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,11 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sa != null && typeDef.Layout.HasFlag(dnlib.DotNet.TypeAttributes.ExplicitLayout))
|
if (typeDef.Layout.HasFlag(dnlib.DotNet.TypeAttributes.ExplicitLayout))
|
||||||
{
|
{
|
||||||
int offset = (int)field.FieldOffset.Value;
|
int offset = (int)field.FieldOffset.Value;
|
||||||
totalSize = Math.Max(totalSize, offset + fs);
|
totalSize = Math.Max(totalSize, offset + fs);
|
||||||
if (offset > sa.ClassSize)
|
if (sa != null && offset > sa.ClassSize)
|
||||||
{
|
{
|
||||||
useSLSize = false;
|
useSLSize = false;
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ namespace HybridCLR.Editor.ABI
|
||||||
totalSize = (totalSize + fa - 1) / fa * fa;
|
totalSize = (totalSize + fa - 1) / fa * fa;
|
||||||
}
|
}
|
||||||
totalSize += fs;
|
totalSize += fs;
|
||||||
if (sa != null && typeDef.Layout.HasFlag(dnlib.DotNet.TypeAttributes.SequentialLayout) && totalSize > sa.ClassSize)
|
if (sa != null && totalSize > sa.ClassSize)
|
||||||
{
|
{
|
||||||
useSLSize = false;
|
useSLSize = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,11 @@ namespace HybridCLR.Editor.BuildProcessors
|
||||||
|
|
||||||
public static void CopyStripDlls(string srcStripDllPath, BuildTarget target)
|
public static void CopyStripDlls(string srcStripDllPath, BuildTarget target)
|
||||||
{
|
{
|
||||||
|
if (!SettingsUtil.Enable)
|
||||||
|
{
|
||||||
|
Debug.Log($"[CopyStrippedAOTAssemblies] disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
Debug.Log($"[CopyStrippedAOTAssemblies] CopyScripDlls. src:{srcStripDllPath} target:{target}");
|
Debug.Log($"[CopyStrippedAOTAssemblies] CopyScripDlls. src:{srcStripDllPath} target:{target}");
|
||||||
|
|
||||||
var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
||||||
|
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
using HybridCLR.Editor.DHE;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace HybridCLR.Editor.Commands
|
|
||||||
{
|
|
||||||
public static class DifferentialHybridExecutionCommand
|
|
||||||
{
|
|
||||||
[MenuItem("HybridCLR/Generate/DHEAssemblyList", priority = 110)]
|
|
||||||
public static void GenerateAssemblyList()
|
|
||||||
{
|
|
||||||
var options = new AssemblyListGenerator.Options()
|
|
||||||
{
|
|
||||||
DifferentialHybridAssembyList = (HybridCLRSettings.Instance.differentialHybridAssemblies ?? Array.Empty<string>()).ToList(),
|
|
||||||
OutputFile = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/Il2CppCompatibleDef.cpp",
|
|
||||||
};
|
|
||||||
|
|
||||||
var g = new AssemblyListGenerator(options);
|
|
||||||
g.Generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[MenuItem("HybridCLR/Generate/DHEAssemblyOptionDatas", priority = 111)]
|
|
||||||
public static void GenerateAssemblyOptionDatas()
|
|
||||||
{
|
|
||||||
GenerateAssemblyOptionDatas(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void GenerateAssemblyOptionDatas(bool compileDll)
|
|
||||||
{
|
|
||||||
if (compileDll)
|
|
||||||
{
|
|
||||||
CompileDllCommand.CompileDllActiveBuildTarget();
|
|
||||||
}
|
|
||||||
string[] differentialHybridAssemblyList = HybridCLRSettings.Instance.differentialHybridAssemblies;
|
|
||||||
if (differentialHybridAssemblyList == null || differentialHybridAssemblyList.Length == 0)
|
|
||||||
{
|
|
||||||
Debug.Log("[DifferentialHybridExecutionCommand.GenerateAssemblyOptionDatas] differentialHybridAssemblies is empty. skip generation.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var options = new AssemblyOptionDataGenerator.Options()
|
|
||||||
{
|
|
||||||
DifferentialHybridAssembyList = differentialHybridAssemblyList.ToList(),
|
|
||||||
OutputDir = $"{SettingsUtil.ProjectDir}/{HybridCLRSettings.Instance.differentialHybridOptionOutputDir}",
|
|
||||||
};
|
|
||||||
|
|
||||||
var g = new AssemblyOptionDataGenerator(options);
|
|
||||||
g.Generate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 998b5f512dc60924e953a558ed250e15
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -42,7 +42,6 @@ namespace HybridCLR.Editor.Commands
|
||||||
g.PrepareMethods();
|
g.PrepareMethods();
|
||||||
g.Generate();
|
g.Generate();
|
||||||
Debug.LogFormat("== output:{0} ==", outputFile);
|
Debug.LogFormat("== output:{0} ==", outputFile);
|
||||||
CleanIl2CppBuildCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("HybridCLR/Generate/MethodBridge", priority = 101)]
|
[MenuItem("HybridCLR/Generate/MethodBridge", priority = 101)]
|
||||||
|
|
@ -83,6 +82,7 @@ namespace HybridCLR.Editor.Commands
|
||||||
Task.WaitAll(tasks.ToArray());
|
Task.WaitAll(tasks.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CleanIl2CppBuildCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ namespace HybridCLR.Editor.Commands
|
||||||
public static void GenerateAll()
|
public static void GenerateAll()
|
||||||
{
|
{
|
||||||
Il2CppDefGeneratorCommand.GenerateIl2CppDef();
|
Il2CppDefGeneratorCommand.GenerateIl2CppDef();
|
||||||
DifferentialHybridExecutionCommand.GenerateAssemblyList();
|
|
||||||
DifferentialHybridExecutionCommand.GenerateAssemblyOptionDatas();
|
|
||||||
// 顺序随意
|
// 顺序随意
|
||||||
ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper();
|
ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 1e6e11530acf7134796d0a439a6bbe61
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
using HybridCLR.Editor.Template;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace HybridCLR.Editor.DHE
|
|
||||||
{
|
|
||||||
public class AssemblyListGenerator
|
|
||||||
{
|
|
||||||
public class Options
|
|
||||||
{
|
|
||||||
public string OutputFile { get; set; }
|
|
||||||
|
|
||||||
public List<string> DifferentialHybridAssembyList { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Options _options;
|
|
||||||
public AssemblyListGenerator(Options options)
|
|
||||||
{
|
|
||||||
_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Generate()
|
|
||||||
{
|
|
||||||
var frr = new FileRegionReplace(File.ReadAllText(_options.OutputFile));
|
|
||||||
|
|
||||||
List<string> lines = new List<string>();
|
|
||||||
foreach (var ass in _options.DifferentialHybridAssembyList)
|
|
||||||
{
|
|
||||||
lines.Add($"\t\t\"{ass}\",");
|
|
||||||
}
|
|
||||||
|
|
||||||
frr.Replace("DHE", string.Join("\n", lines));
|
|
||||||
|
|
||||||
frr.Commit(_options.OutputFile);
|
|
||||||
Debug.Log($"output:{_options.OutputFile}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: d6be260bc9a8a40468a82b9ea49b89a1
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
using dnlib.DotNet;
|
|
||||||
using HybridCLR.Editor.Commands;
|
|
||||||
using HybridCLR.Editor.Meta;
|
|
||||||
using HybridCLR.Runtime;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace HybridCLR.Editor.DHE
|
|
||||||
{
|
|
||||||
public class AssemblyOptionDataGenerator
|
|
||||||
{
|
|
||||||
public class Options
|
|
||||||
{
|
|
||||||
public string OutputDir { get; set; }
|
|
||||||
|
|
||||||
public List<string> DifferentialHybridAssembyList { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Options _options;
|
|
||||||
|
|
||||||
public AssemblyOptionDataGenerator(Options options)
|
|
||||||
{
|
|
||||||
_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Generate()
|
|
||||||
{
|
|
||||||
foreach(string assName in _options.DifferentialHybridAssembyList)
|
|
||||||
{
|
|
||||||
using (var assCollector = new AssemblyCache(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget)))
|
|
||||||
{
|
|
||||||
var ass = assCollector.LoadModule(assName);
|
|
||||||
|
|
||||||
var dhaOptions = new DifferentialHybridAssemblyOptions()
|
|
||||||
{
|
|
||||||
notChangeMethodTokens = new List<uint>(),
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var type in ass.GetTypes())
|
|
||||||
{
|
|
||||||
foreach (var method in type.Methods)
|
|
||||||
{
|
|
||||||
var attr = method.CustomAttributes.Where(a => a.AttributeType.FullName == "HybridCLR.Runtime.UnchangedAttribute").FirstOrDefault();
|
|
||||||
if (attr != null)
|
|
||||||
{
|
|
||||||
if ((bool)attr.ConstructorArguments[0].Value)
|
|
||||||
{
|
|
||||||
dhaOptions.notChangeMethodTokens.Add(method.MDToken.Raw);
|
|
||||||
Debug.Log($"Unchanged method:{method.MDToken.Raw} {method}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
string outOptionFile = $"{_options.OutputDir}/{assName}.dhao.bytes";
|
|
||||||
File.WriteAllBytes(outOptionFile, dhaOptions.Marshal());
|
|
||||||
Debug.Log($"[AssemblyOptionDataGenerator] assembly:{ass} output:{outOptionFile}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 4a4eda50e51d72d499b439da236a8371
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -18,57 +18,35 @@ namespace HybridCLR.Editor.Installer
|
||||||
public enum InstallErrorCode
|
public enum InstallErrorCode
|
||||||
{
|
{
|
||||||
Ok,
|
Ok,
|
||||||
InvalidUnityInstallPath,
|
|
||||||
Il2CppInstallPathNotMatchIl2CppBranch,
|
|
||||||
Il2CppInstallPathNotExists,
|
|
||||||
NotIl2CppPath,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class InstallerController
|
public partial class InstallerController
|
||||||
{
|
{
|
||||||
private const string hybridclr_repo_path = "hybridclr_repo";
|
private const string hybridclr_repo_path = "hybridclr_repo";
|
||||||
|
|
||||||
private const string il2cpp_plus_repo_path = "il2cpp_plus_repo";
|
private const string il2cpp_plus_repo_path = "il2cpp_plus_repo";
|
||||||
|
|
||||||
private string m_Il2CppInstallDirectory;
|
|
||||||
|
|
||||||
public string Il2CppInstallDirectory
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_Il2CppInstallDirectory;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_Il2CppInstallDirectory = value?.Replace('\\', '/');
|
|
||||||
if (!string.IsNullOrEmpty(m_Il2CppInstallDirectory))
|
|
||||||
{
|
|
||||||
EditorPrefs.SetString("UnityInstallDirectory", m_Il2CppInstallDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetIl2CppPlusBranchByUnityVersion(string unityVersion)
|
public int MajorVersion => _curVersion.major;
|
||||||
{
|
|
||||||
if (unityVersion.Contains("2019."))
|
|
||||||
{
|
|
||||||
return "2019.4.40";
|
|
||||||
}
|
|
||||||
if (unityVersion.Contains("2020."))
|
|
||||||
{
|
|
||||||
return "2020.3.33";
|
|
||||||
}
|
|
||||||
if (unityVersion.Contains("2021."))
|
|
||||||
{
|
|
||||||
return "2021.3.1";
|
|
||||||
}
|
|
||||||
return "not support";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Il2CppBranch => GetIl2CppPlusBranchByUnityVersion(Application.unityVersion);
|
private UnityVersion _curVersion;
|
||||||
|
|
||||||
public InstallerController()
|
public InstallerController()
|
||||||
{
|
{
|
||||||
PrepareIl2CppInstallPath();
|
_curVersion = ParseUnityVersion(Application.unityVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UnityVersion
|
||||||
|
{
|
||||||
|
public int major;
|
||||||
|
public int minor1;
|
||||||
|
public int minor2;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{major}.{minor1}.{minor2}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex s_unityVersionPat = new Regex(@"(\d+)\.(\d+)\.(\d+)");
|
private static readonly Regex s_unityVersionPat = new Regex(@"(\d+)\.(\d+)\.(\d+)");
|
||||||
|
|
@ -77,145 +55,143 @@ namespace HybridCLR.Editor.Installer
|
||||||
public const int min2020_3_CompatibleMinorVersion = 21;
|
public const int min2020_3_CompatibleMinorVersion = 21;
|
||||||
public const int min2021_3_CompatibleMinorVersion = 0;
|
public const int min2021_3_CompatibleMinorVersion = 0;
|
||||||
|
|
||||||
private bool TryParseMinorVersion(string installDir, out (int Major, int Minor1, int Minor2) unityVersion)
|
private UnityVersion ParseUnityVersion(string versionStr)
|
||||||
{
|
{
|
||||||
var matches = s_unityVersionPat.Matches(installDir);
|
var matches = s_unityVersionPat.Matches(versionStr);
|
||||||
if (matches.Count == 0)
|
if (matches.Count == 0)
|
||||||
{
|
{
|
||||||
unityVersion = default;
|
return null;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// 找最后一个匹配的,有的人居然会把Unity安装目录放到其他安装版本下。无语!
|
// 找最后一个匹配的
|
||||||
Match match = matches[matches.Count - 1];
|
Match match = matches[matches.Count - 1];
|
||||||
// Debug.Log($"capture count:{match.Groups.Count} {match.Groups[1].Value} {match.Groups[2].Value}");
|
// Debug.Log($"capture count:{match.Groups.Count} {match.Groups[1].Value} {match.Groups[2].Value}");
|
||||||
int major = int.Parse(match.Groups[1].Value);
|
int major = int.Parse(match.Groups[1].Value);
|
||||||
int minor1 = int.Parse(match.Groups[2].Value);
|
int minor1 = int.Parse(match.Groups[2].Value);
|
||||||
int minor2 = int.Parse(match.Groups[3].Value);
|
int minor2 = int.Parse(match.Groups[3].Value);
|
||||||
unityVersion = (major, minor1, minor2);
|
return new UnityVersion { major = major, minor1 = minor1, minor2 = minor2 };
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetCurVersionStr(string installDir)
|
public string GetCurrentUnityVersionMinCompatibleVersionStr()
|
||||||
{
|
{
|
||||||
if (TryParseMinorVersion(installDir, out var version))
|
return GetMinCompatibleVersion(MajorVersion);
|
||||||
{
|
|
||||||
return $"{version.Major}.{version.Minor1}.{version.Minor2}";
|
|
||||||
}
|
|
||||||
throw new Exception($"not support version:{installDir}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetMinCompatibleVersion(string branch)
|
public string GetMinCompatibleVersion(int majorVersion)
|
||||||
{
|
{
|
||||||
switch(branch)
|
switch(majorVersion)
|
||||||
{
|
{
|
||||||
case "2019.4.40": return $"2019.4.{min2019_4_CompatibleMinorVersion}";
|
case 2019: return $"2019.4.{min2019_4_CompatibleMinorVersion}";
|
||||||
case "2020.3.33": return $"2020.3.{min2020_3_CompatibleMinorVersion}";
|
case 2020: return $"2020.3.{min2020_3_CompatibleMinorVersion}";
|
||||||
case "2021.3.1": return $"2021.3.{min2021_3_CompatibleMinorVersion}";
|
case 2021: return $"2021.3.{min2021_3_CompatibleMinorVersion}";
|
||||||
default: throw new Exception($"not support version:{branch}");
|
default: throw new Exception($"not support version:{majorVersion}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsComaptibleWithIl2CppPlusBranch(string branch, string installDir)
|
public bool IsComaptibleVersion()
|
||||||
{
|
{
|
||||||
if (!TryParseMinorVersion(installDir, out var unityVersion))
|
UnityVersion version = _curVersion;
|
||||||
|
switch (version.major)
|
||||||
{
|
{
|
||||||
return false;
|
case 2019:
|
||||||
}
|
|
||||||
switch(branch)
|
|
||||||
{
|
|
||||||
case "2019.4.40":
|
|
||||||
{
|
{
|
||||||
if (unityVersion.Major != 2019 || unityVersion.Minor1 != 4)
|
if (version.major != 2019 || version.minor1 != 4)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return unityVersion.Minor2 >= min2019_4_CompatibleMinorVersion;
|
return version.minor2 >= min2019_4_CompatibleMinorVersion;
|
||||||
}
|
}
|
||||||
case "2020.3.33":
|
case 2020:
|
||||||
{
|
{
|
||||||
if (unityVersion.Major != 2020 || unityVersion.Minor1 != 3)
|
if (version.major != 2020 || version.minor1 != 3)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return unityVersion.Minor2 >= min2020_3_CompatibleMinorVersion;
|
return version.minor2 >= min2020_3_CompatibleMinorVersion;
|
||||||
}
|
}
|
||||||
case "2021.3.1":
|
case 2021:
|
||||||
{
|
{
|
||||||
if (unityVersion.Major != 2021 || unityVersion.Minor1 != 3)
|
if (version.major != 2021 || version.minor1 != 3)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return unityVersion.Minor2 >= min2021_3_CompatibleMinorVersion;
|
return version.minor2 >= min2021_3_CompatibleMinorVersion;
|
||||||
}
|
}
|
||||||
default: throw new Exception($"not support il2cpp_plus branch:{branch}");
|
default: throw new Exception($"not support il2cpp_plus branch:{version.major}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareIl2CppInstallPath()
|
private string _hybridclrLocalVersion;
|
||||||
{
|
|
||||||
#if UNITY_EDITOR_WIN
|
|
||||||
|
|
||||||
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
|
public string HybridclrLocalVersion => _hybridclrLocalVersion != null ? _hybridclrLocalVersion : _hybridclrLocalVersion = GetHybridCLRLocalVersion();
|
||||||
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
|
|
||||||
|
|
||||||
|
public string HybridCLRRepoInstalledVersion
|
||||||
|
{
|
||||||
|
get { return EditorPrefs.GetString($"hybridclr_repo#{MajorVersion}"); }
|
||||||
|
set { EditorPrefs.SetString($"hybridclr_repo#{MajorVersion}", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Il2CppRepoInstalledVersion
|
||||||
|
{
|
||||||
|
get { return EditorPrefs.GetString($"il2cpp_plus_repo#{MajorVersion}"); }
|
||||||
|
set { EditorPrefs.SetString($"il2cpp_plus_repo#{MajorVersion}", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string GetHybridCLRLocalVersion()
|
||||||
|
{
|
||||||
|
string workDir = SettingsUtil.HybridCLRDataDir;
|
||||||
|
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
||||||
|
if (Directory.Exists(hybridclrRepoDir))
|
||||||
{
|
{
|
||||||
return;
|
var ret = BashUtil.RunCommand2(hybridclrRepoDir, "git",
|
||||||
}
|
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
|
||||||
var il2cppBranch = Il2CppBranch;
|
false);
|
||||||
var curAppInstallPath = EditorApplication.applicationPath;
|
if (ret.ExitCode == 0)
|
||||||
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
|
|
||||||
{
|
|
||||||
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
|
|
||||||
// Debug.Log("unity hub root dir:" + unityHubRootDir);
|
|
||||||
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
// Debug.Log("Unity install dir:" + unityInstallDir);
|
|
||||||
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
|
|
||||||
{
|
{
|
||||||
Il2CppInstallDirectory = $"{unityInstallDir}/Editor/Data/il2cpp";
|
return ret.StdOut.Trim();
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "ERROR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
|
|
||||||
#else
|
|
||||||
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
|
|
||||||
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var il2cppBranch = Il2CppBranch;
|
|
||||||
var curAppInstallPath = EditorApplication.applicationPath;
|
|
||||||
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
|
|
||||||
{
|
|
||||||
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
|
|
||||||
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
Debug.Log("nity install dir:" + unityInstallDir);
|
|
||||||
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
|
|
||||||
{
|
|
||||||
Il2CppInstallDirectory = $"{unityInstallDir}/Unity.app/Contents/il2cpp";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitHybridCLR(string il2cppBranch, string il2cppInstallPath, string hybridclrVer, string il2cppPlusVer)
|
private string _il2cppPlusLocalVersion;
|
||||||
|
|
||||||
|
public string Il2cppPlusLocalVersion => _il2cppPlusLocalVersion != null ? _il2cppPlusLocalVersion : _il2cppPlusLocalVersion = GetIl2cppPlusLocalVersion();
|
||||||
|
|
||||||
|
private string GetIl2cppPlusLocalVersion()
|
||||||
{
|
{
|
||||||
if (CheckValidIl2CppInstallDirectory(il2cppBranch, il2cppInstallPath) != InstallErrorCode.Ok)
|
string workDir = SettingsUtil.HybridCLRDataDir;
|
||||||
|
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
||||||
|
if (Directory.Exists(il2cppPlusRepoDir))
|
||||||
{
|
{
|
||||||
Debug.LogError($"请正确设置 il2cpp 安装目录");
|
var ret = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
|
||||||
return;
|
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
|
||||||
|
false);
|
||||||
|
if (ret.ExitCode == 0)
|
||||||
|
{
|
||||||
|
return ret.StdOut.Trim();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RunInitLocalIl2CppData(il2cppBranch, il2cppInstallPath, hybridclrVer, il2cppPlusVer);
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetIl2CppPathByContentPath(string contentPath)
|
||||||
|
{
|
||||||
|
return $"{contentPath}/il2cpp";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InstallLocalHybridCLR(string hybridclrVer, string il2cppPlusVer)
|
||||||
|
{
|
||||||
|
RunInitLocalIl2CppData(GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath), _curVersion, hybridclrVer, il2cppPlusVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasInstalledHybridCLR()
|
public bool HasInstalledHybridCLR()
|
||||||
|
|
@ -223,34 +199,6 @@ namespace HybridCLR.Editor.Installer
|
||||||
return Directory.Exists($"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr");
|
return Directory.Exists($"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr");
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstallErrorCode CheckValidIl2CppInstallDirectory(string il2cppBranch, string installDir)
|
|
||||||
{
|
|
||||||
installDir = installDir.Replace('\\', '/');
|
|
||||||
if (!Directory.Exists(installDir))
|
|
||||||
{
|
|
||||||
return InstallErrorCode.Il2CppInstallPathNotExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsComaptibleWithIl2CppPlusBranch(il2cppBranch, installDir))
|
|
||||||
{
|
|
||||||
return TryParseMinorVersion(installDir, out _) ?
|
|
||||||
InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch
|
|
||||||
: InstallErrorCode.InvalidUnityInstallPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!installDir.EndsWith("/il2cpp"))
|
|
||||||
{
|
|
||||||
return InstallErrorCode.NotIl2CppPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
return InstallErrorCode.Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsUnity2019(string branch)
|
|
||||||
{
|
|
||||||
return branch.Contains("2019.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string GetUnityIl2CppDllInstallLocation()
|
private string GetUnityIl2CppDllInstallLocation()
|
||||||
{
|
{
|
||||||
|
|
@ -270,7 +218,7 @@ namespace HybridCLR.Editor.Installer
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunInitLocalIl2CppData(string il2cppBranch, string il2cppInstallPath, string hybridclrVer, string il2cppPlusVer)
|
private void RunInitLocalIl2CppData(string editorIl2cppPath, UnityVersion version, string hybridclrVer, string il2cppPlusVer)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR_WIN
|
#if UNITY_EDITOR_WIN
|
||||||
if (!BashUtil.ExistProgram("git"))
|
if (!BashUtil.ExistProgram("git"))
|
||||||
|
|
@ -292,15 +240,7 @@ namespace HybridCLR.Editor.Installer
|
||||||
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
||||||
{
|
{
|
||||||
BashUtil.RemoveDir(hybridclrRepoDir);
|
BashUtil.RemoveDir(hybridclrRepoDir);
|
||||||
string[] args = string.IsNullOrWhiteSpace(hybridclrVer) ? new string[]
|
string[] args = new string[]
|
||||||
{
|
|
||||||
"clone",
|
|
||||||
"--depth=1",
|
|
||||||
hybridclrRepoURL,
|
|
||||||
hybridclrRepoDir,
|
|
||||||
}
|
|
||||||
:
|
|
||||||
new string[]
|
|
||||||
{
|
{
|
||||||
"clone",
|
"clone",
|
||||||
"--depth=1",
|
"--depth=1",
|
||||||
|
|
@ -321,18 +261,7 @@ namespace HybridCLR.Editor.Installer
|
||||||
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
||||||
{
|
{
|
||||||
BashUtil.RemoveDir(il2cppPlusRepoDir);
|
BashUtil.RemoveDir(il2cppPlusRepoDir);
|
||||||
string[] args = string.IsNullOrWhiteSpace(il2cppPlusVer) ?
|
string[] args = new string[]
|
||||||
new string[]
|
|
||||||
{
|
|
||||||
"clone",
|
|
||||||
"--depth=1",
|
|
||||||
"-b",
|
|
||||||
il2cppBranch,
|
|
||||||
il2cppPlusRepoURL,
|
|
||||||
il2cppPlusRepoDir,
|
|
||||||
}
|
|
||||||
:
|
|
||||||
new string[]
|
|
||||||
{
|
{
|
||||||
"clone",
|
"clone",
|
||||||
"--depth=1",
|
"--depth=1",
|
||||||
|
|
@ -353,10 +282,10 @@ namespace HybridCLR.Editor.Installer
|
||||||
BashUtil.RecreateDir(localUnityDataDir);
|
BashUtil.RecreateDir(localUnityDataDir);
|
||||||
|
|
||||||
// copy MonoBleedingEdge
|
// copy MonoBleedingEdge
|
||||||
BashUtil.CopyDir($"{Directory.GetParent(il2cppInstallPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
|
BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
|
||||||
|
|
||||||
// copy il2cpp
|
// copy il2cpp
|
||||||
BashUtil.CopyDir(Il2CppInstallDirectory, SettingsUtil.LocalIl2CppDir, true);
|
BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true);
|
||||||
|
|
||||||
// replace libil2cpp
|
// replace libil2cpp
|
||||||
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
||||||
|
|
@ -366,9 +295,9 @@ namespace HybridCLR.Editor.Installer
|
||||||
// clean Il2cppBuildCache
|
// clean Il2cppBuildCache
|
||||||
BashUtil.RemoveDir($"{SettingsUtil.ProjectDir}/Library/Il2cppBuildCache", true);
|
BashUtil.RemoveDir($"{SettingsUtil.ProjectDir}/Library/Il2cppBuildCache", true);
|
||||||
|
|
||||||
if (IsUnity2019(il2cppBranch))
|
if (version.major == 2019)
|
||||||
{
|
{
|
||||||
string curVersionStr = GetCurVersionStr(il2cppInstallPath);
|
string curVersionStr = version.ToString();
|
||||||
string srcIl2CppDll = GetUnityIl2CppDllModifiedPath(curVersionStr);
|
string srcIl2CppDll = GetUnityIl2CppDllModifiedPath(curVersionStr);
|
||||||
if (File.Exists(srcIl2CppDll))
|
if (File.Exists(srcIl2CppDll))
|
||||||
{
|
{
|
||||||
|
|
@ -384,8 +313,10 @@ namespace HybridCLR.Editor.Installer
|
||||||
if (HasInstalledHybridCLR())
|
if (HasInstalledHybridCLR())
|
||||||
{
|
{
|
||||||
Debug.Log("安装成功!");
|
Debug.Log("安装成功!");
|
||||||
_hybridclrLocalVersion = hybridclrVer;
|
_hybridclrLocalVersion = null;
|
||||||
_il2cppPlusLocalVersion = il2cppPlusVer;
|
_il2cppPlusLocalVersion = null;
|
||||||
|
HybridCLRRepoInstalledVersion = hybridclrVer;
|
||||||
|
Il2CppRepoInstalledVersion = il2cppPlusVer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,24 @@ namespace HybridCLR.Editor.Installer
|
||||||
{
|
{
|
||||||
public class InstallerWindow : EditorWindow
|
public class InstallerWindow : EditorWindow
|
||||||
{
|
{
|
||||||
private InstallerController m_Controller;
|
private InstallerController _controller;
|
||||||
|
|
||||||
string _hybridclrVersion = "";
|
string _hybridclrVersion;
|
||||||
string _il2cppPlusVersion = "";
|
string _il2cppPlusVersion;
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
m_Controller = new InstallerController();
|
_controller = new InstallerController();
|
||||||
|
_hybridclrVersion = _controller.HybridCLRRepoInstalledVersion;
|
||||||
|
if (string.IsNullOrWhiteSpace(_hybridclrVersion))
|
||||||
|
{
|
||||||
|
_hybridclrVersion = "1.0";
|
||||||
|
}
|
||||||
|
_il2cppPlusVersion = _controller.Il2CppRepoInstalledVersion;
|
||||||
|
if (string.IsNullOrWhiteSpace(_il2cppPlusVersion))
|
||||||
|
{
|
||||||
|
_il2cppPlusVersion = $"{_controller.MajorVersion}-1.0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
|
|
@ -34,141 +44,69 @@ namespace HybridCLR.Editor.Installer
|
||||||
SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
|
SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
string il2cppBranch = m_Controller.Il2CppBranch;
|
|
||||||
string minCompatibleVersion = m_Controller.GetMinCompatibleVersion(il2cppBranch);
|
|
||||||
GUI.enabled = true;
|
|
||||||
GUILayout.Space(10f);
|
GUILayout.Space(10f);
|
||||||
EditorGUILayout.LabelField("=======================说明====================");
|
|
||||||
EditorGUILayout.LabelField(
|
|
||||||
$"你所在项目的Unity版本可以与il2cpp_plus版本:{il2cppBranch} 不一样。\n"
|
|
||||||
+ $"如果你的Unity的版本号 >= {minCompatibleVersion}, 可以直接安装。\n"
|
|
||||||
+ $"如果你的Unity的版本号 < {minCompatibleVersion}, \n"
|
|
||||||
+ $"由于安装HybridCLR时需要从il2cpp_plus兼容版本{il2cppBranch}(而不是你项目版本)拷贝il2cpp目录,\n"
|
|
||||||
+ $"你必须同时安装兼容版本 {il2cppBranch} 才能完成安装", EditorStyles.wordWrappedLabel);
|
|
||||||
EditorGUILayout.LabelField("==============================================");
|
|
||||||
|
|
||||||
GUILayout.Space(10f);
|
|
||||||
|
|
||||||
EditorGUILayout.LabelField($"当前Unity版本: {Application.unityVersion},匹配的il2cpp_plus分支: {il2cppBranch}");
|
|
||||||
GUILayout.Space(5f);
|
|
||||||
|
|
||||||
EditorGUILayout.BeginVertical("box");
|
EditorGUILayout.BeginVertical("box");
|
||||||
bool hasInstall = m_Controller.HasInstalledHybridCLR();
|
bool hasInstall = _controller.HasInstalledHybridCLR();
|
||||||
EditorGUILayout.LabelField($"安装状态:{(hasInstall ? "已安装" : "未安装")}", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField($"安装状态:{(hasInstall ? "已安装" : "未安装")}", EditorStyles.boldLabel);
|
||||||
|
|
||||||
string hybridclrLocalVersion = m_Controller.HybridclrLocalVersion;
|
|
||||||
string il2cppPlusLocalVersion = m_Controller.Il2cppPlusLocalVersion;
|
|
||||||
if (hasInstall)
|
if (hasInstall)
|
||||||
{
|
{
|
||||||
EditorGUILayout.LabelField($"HybridCLR 版本: {hybridclrLocalVersion}");
|
EditorGUILayout.LabelField($"HybridCLR 版本: {_controller.HybridclrLocalVersion}");
|
||||||
GUILayout.Space(5f);
|
GUILayout.Space(5f);
|
||||||
EditorGUILayout.LabelField($"il2cpp_plus 版本: {il2cppPlusLocalVersion}");
|
EditorGUILayout.LabelField($"il2cpp_plus 版本: {_controller.Il2cppPlusLocalVersion}");
|
||||||
GUILayout.Space(5f);
|
GUILayout.Space(5f);
|
||||||
//GUIInstallButton("检查更新", "检查", UpdateHybridCLR);
|
//GUIInstallButton("检查更新", "检查", UpdateHybridCLR);
|
||||||
//GUILayout.Space(40f);
|
//GUILayout.Space(40f);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUISelectUnityDirectory($"il2cpp_plus分支对应的Unity兼容版本的il2cpp路径", "Select");
|
|
||||||
GUILayout.Space(10f);
|
GUILayout.Space(10f);
|
||||||
|
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.LabelField("待安装的 hybridclr 仓库版本号(或tag)(默认取最新版本):", GUILayout.MaxWidth(400));
|
EditorGUILayout.LabelField("待安装的 hybridclr 仓库版本号(或branch或tag)(默认取最新版本):", GUILayout.MaxWidth(400));
|
||||||
_hybridclrVersion = EditorGUILayout.TextField(_hybridclrVersion);
|
_hybridclrVersion = EditorGUILayout.TextField(_hybridclrVersion);
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.LabelField($"待安装的 il2cpp_plus 仓库版本号(或tag)(默认取{il2cppBranch}分支最新版本):", GUILayout.MaxWidth(400));
|
EditorGUILayout.LabelField($"待安装的 il2cpp_plus 仓库版本号(或branch或tag)(默认取{_controller.MajorVersion}-main分支最新版本):", GUILayout.MaxWidth(400));
|
||||||
_il2cppPlusVersion = EditorGUILayout.TextField(_il2cppPlusVersion);
|
_il2cppPlusVersion = EditorGUILayout.TextField(_il2cppPlusVersion);
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
|
||||||
GUIInstallButton("安装hybridclr+il2cpp_plus代码到本地目录", "安装", InitHybridCLR);
|
GUIInstallButton("安装hybridclr+il2cpp_plus代码到本地目录", "安装");
|
||||||
EditorGUILayout.EndVertical();
|
EditorGUILayout.EndVertical();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GUIInstallButton(string content, string button, Action onClick)
|
private void GUIInstallButton(string content, string button)
|
||||||
{
|
{
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.LabelField(content);
|
EditorGUILayout.LabelField(content);
|
||||||
GUI.enabled = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory) == InstallErrorCode.Ok;
|
|
||||||
if (GUILayout.Button(button, GUILayout.Width(100)))
|
if (GUILayout.Button(button, GUILayout.Width(100)))
|
||||||
{
|
{
|
||||||
onClick?.Invoke();
|
InstallLocalHybridCLR();
|
||||||
GUIUtility.ExitGUI();
|
GUIUtility.ExitGUI();
|
||||||
}
|
}
|
||||||
GUI.enabled = true;
|
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InstallLocalHybridCLR()
|
||||||
private void GUISelectUnityDirectory(string content, string selectButton)
|
|
||||||
{
|
{
|
||||||
EditorGUILayout.BeginHorizontal();
|
if (!_controller.IsComaptibleVersion())
|
||||||
EditorGUILayout.LabelField(content, GUILayout.MaxWidth(300));
|
|
||||||
string il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = EditorGUILayout.TextField(m_Controller.Il2CppInstallDirectory);
|
|
||||||
if (GUILayout.Button(selectButton, GUILayout.Width(100)))
|
|
||||||
{
|
{
|
||||||
string temp = EditorUtility.OpenFolderPanel(content, m_Controller.Il2CppInstallDirectory, string.Empty);
|
Debug.LogError($"il2cpp 版本不兼容,最小版本为 {_controller.GetCurrentUnityVersionMinCompatibleVersionStr()}");
|
||||||
if (!string.IsNullOrEmpty(temp))
|
return;
|
||||||
{
|
|
||||||
il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = temp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EditorGUILayout.EndHorizontal();
|
if (string.IsNullOrWhiteSpace(_hybridclrVersion))
|
||||||
|
|
||||||
InstallErrorCode err = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, il2cppInstallDirectory);
|
|
||||||
switch (err)
|
|
||||||
{
|
{
|
||||||
case InstallErrorCode.Ok:
|
_hybridclrVersion = "main";
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case InstallErrorCode.Il2CppInstallPathNotExists:
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox("li2cpp 路径不存在", MessageType.Error);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case InstallErrorCode.InvalidUnityInstallPath:
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox($"Unity安装目录必须包含版本号,否则无法识别版本", MessageType.Error);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch:
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox($"il2cpp 版本不兼容,最小版本为 {m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch)}", MessageType.Error);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case InstallErrorCode.NotIl2CppPath:
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox($"当前选择的路径不是il2cpp目录(必须类似 xxx/il2cpp)", MessageType.Error);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: throw new Exception($"not support {err}");
|
|
||||||
}
|
}
|
||||||
}
|
if (string.IsNullOrWhiteSpace(_il2cppPlusVersion))
|
||||||
|
|
||||||
private void InitHybridCLR()
|
|
||||||
{
|
|
||||||
m_Controller.InitHybridCLR(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory, _hybridclrVersion, _il2cppPlusVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateHybridCLR()
|
|
||||||
{
|
|
||||||
bool hasUpdateIl2Cpp = m_Controller.HasUpdateIl2Cpp(m_Controller.Il2CppBranch);
|
|
||||||
if (hasUpdateIl2Cpp)
|
|
||||||
{
|
{
|
||||||
bool ret = EditorUtility.DisplayDialog("检查更新", "版本不一致", "更新","取消");
|
_il2cppPlusVersion = $"{_controller.MajorVersion}-main";
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
InitHybridCLR();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayDialog("检查更新", "暂无更新", "确定");
|
|
||||||
}
|
}
|
||||||
|
_controller.InstallLocalHybridCLR(_hybridclrVersion, _il2cppPlusVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace HybridCLR.Editor.Installer
|
|
||||||
{
|
|
||||||
public partial class InstallerController
|
|
||||||
{
|
|
||||||
private string _hybridclrLocalVersion;
|
|
||||||
|
|
||||||
public string HybridclrLocalVersion => _hybridclrLocalVersion ??= GetHybridCLRLocalVersion();
|
|
||||||
|
|
||||||
private string GetHybridCLRLocalVersion()
|
|
||||||
{
|
|
||||||
string workDir = SettingsUtil.HybridCLRDataDir;
|
|
||||||
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
|
||||||
if (Directory.Exists(hybridclrRepoDir))
|
|
||||||
{
|
|
||||||
var ret = BashUtil.RunCommand2(hybridclrRepoDir, "git",
|
|
||||||
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
|
|
||||||
false);
|
|
||||||
if (ret.ExitCode == 0)
|
|
||||||
{
|
|
||||||
return ret.StdOut.Trim();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "ERROR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _il2cppPlusLocalVersion;
|
|
||||||
|
|
||||||
public string Il2cppPlusLocalVersion => _il2cppPlusLocalVersion ??= GetIl2cppPlusLocalVersion();
|
|
||||||
|
|
||||||
private string GetIl2cppPlusLocalVersion()
|
|
||||||
{
|
|
||||||
string workDir = SettingsUtil.HybridCLRDataDir;
|
|
||||||
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
|
||||||
if (Directory.Exists(il2cppPlusRepoDir))
|
|
||||||
{
|
|
||||||
var ret = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
|
|
||||||
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
|
|
||||||
false);
|
|
||||||
if (ret.ExitCode == 0)
|
|
||||||
{
|
|
||||||
return ret.StdOut.Trim();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "ERROR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasUpdateIl2Cpp(string il2cppBranch)
|
|
||||||
{
|
|
||||||
string workDir = SettingsUtil.HybridCLRDataDir;
|
|
||||||
// last hash hybridclr
|
|
||||||
{
|
|
||||||
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
|
||||||
var ret1 = BashUtil.RunCommand2(hybridclrRepoDir, "git", new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", }, false);
|
|
||||||
BashUtil.RunCommand2(hybridclrRepoDir, "git", new string[] { "fetch", "--depth=1" }, false);
|
|
||||||
var ret2 = BashUtil.RunCommand2(hybridclrRepoDir, "git",
|
|
||||||
new string[] { "log", "remotes/origin/HEAD", "-n", "1", "--pretty=format:\"%H\"", }
|
|
||||||
, false);
|
|
||||||
if (ret1.StdOut != ret2.StdOut)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// last hash il2cpp_plus
|
|
||||||
{
|
|
||||||
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
|
||||||
var ret1 = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
|
|
||||||
new string[] { "log", $"{il2cppBranch}", "-n", "1", "--pretty=format:\"%H\"", }, false);
|
|
||||||
BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
|
|
||||||
new string[] { "fetch", "--depth=1" }, false);
|
|
||||||
var ret2 = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
|
|
||||||
new string[] { "log", $"remotes/origin/{il2cppBranch}", "-n", "1", "--pretty=format:\"%H\"", }, false);
|
|
||||||
if (ret1.StdOut != ret2.StdOut)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 91454a4f0a354d11830642b4d4474d7e
|
|
||||||
timeCreated: 1665546286
|
|
||||||
|
|
@ -36,7 +36,7 @@ Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] =
|
||||||
lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", __M2N_{method.CreateInvokeSigName()}}},");
|
lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", __M2N_{method.CreateInvokeSigName()}}},");
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.Add($"\t{{\"\", nullptr}},");
|
lines.Add($"\t{{nullptr, nullptr}},");
|
||||||
lines.Add("};");
|
lines.Add("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace HybridCLR.Editor.ReversePInvokeWrap
|
||||||
codes.Add($@"
|
codes.Add($@"
|
||||||
{method.ReturnInfo.Type.GetTypeName()} __ReversePInvokeMethod_{methodIndex}({paramDeclaringListWithoutMethodInfoStr})
|
{method.ReturnInfo.Type.GetTypeName()} __ReversePInvokeMethod_{methodIndex}({paramDeclaringListWithoutMethodInfoStr})
|
||||||
{{
|
{{
|
||||||
const MethodInfo* method = MetadataModule::GetMethodInfoByReversePInvokeWrapperIndex({i});
|
const MethodInfo* method = MetadataModule::GetMethodInfoByReversePInvokeWrapperIndex({methodIndex});
|
||||||
{methodTypeDef};
|
{methodTypeDef};
|
||||||
{(method.ReturnInfo.IsVoid ? "" : "return ")}((Callback)(method->methodPointerCallByInterp))({paramNameListWithoutMethodInfoStr});
|
{(method.ReturnInfo.IsVoid ? "" : "return ")}((Callback)(method->methodPointerCallByInterp))({paramNameListWithoutMethodInfoStr});
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ namespace HybridCLR.Editor
|
||||||
private SerializedProperty _hotUpdateDllCompileOutputRootDir;
|
private SerializedProperty _hotUpdateDllCompileOutputRootDir;
|
||||||
private SerializedProperty _strippedAOTDllOutputRootDir;
|
private SerializedProperty _strippedAOTDllOutputRootDir;
|
||||||
private SerializedProperty _patchAOTAssemblies;
|
private SerializedProperty _patchAOTAssemblies;
|
||||||
private SerializedProperty _differentialHybridAssemblies;
|
|
||||||
private SerializedProperty _differentialHybridOptionOutputDir;
|
|
||||||
private SerializedProperty _collectAssetReferenceTypes;
|
private SerializedProperty _collectAssetReferenceTypes;
|
||||||
private SerializedProperty _outputLinkFile;
|
private SerializedProperty _outputLinkFile;
|
||||||
private SerializedProperty _outputAOTGenericReferenceFile;
|
private SerializedProperty _outputAOTGenericReferenceFile;
|
||||||
|
|
@ -48,8 +46,6 @@ namespace HybridCLR.Editor
|
||||||
_hotUpdateDllCompileOutputRootDir = _serializedObject.FindProperty("hotUpdateDllCompileOutputRootDir");
|
_hotUpdateDllCompileOutputRootDir = _serializedObject.FindProperty("hotUpdateDllCompileOutputRootDir");
|
||||||
_strippedAOTDllOutputRootDir = _serializedObject.FindProperty("strippedAOTDllOutputRootDir");
|
_strippedAOTDllOutputRootDir = _serializedObject.FindProperty("strippedAOTDllOutputRootDir");
|
||||||
_patchAOTAssemblies = _serializedObject.FindProperty("patchAOTAssemblies");
|
_patchAOTAssemblies = _serializedObject.FindProperty("patchAOTAssemblies");
|
||||||
_differentialHybridAssemblies = _serializedObject.FindProperty("differentialHybridAssemblies");
|
|
||||||
_differentialHybridOptionOutputDir = _serializedObject.FindProperty("differentialHybridOptionOutputDir");
|
|
||||||
_collectAssetReferenceTypes = _serializedObject.FindProperty("collectAssetReferenceTypes");
|
_collectAssetReferenceTypes = _serializedObject.FindProperty("collectAssetReferenceTypes");
|
||||||
_outputLinkFile = _serializedObject.FindProperty("outputLinkFile");
|
_outputLinkFile = _serializedObject.FindProperty("outputLinkFile");
|
||||||
_outputAOTGenericReferenceFile = _serializedObject.FindProperty("outputAOTGenericReferenceFile");
|
_outputAOTGenericReferenceFile = _serializedObject.FindProperty("outputAOTGenericReferenceFile");
|
||||||
|
|
@ -138,8 +134,6 @@ namespace HybridCLR.Editor
|
||||||
EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir);
|
EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir);
|
||||||
EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir);
|
EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir);
|
||||||
EditorGUILayout.PropertyField(_patchAOTAssemblies);
|
EditorGUILayout.PropertyField(_patchAOTAssemblies);
|
||||||
EditorGUILayout.PropertyField(_differentialHybridAssemblies);
|
|
||||||
EditorGUILayout.PropertyField(_differentialHybridOptionOutputDir);
|
|
||||||
EditorGUILayout.PropertyField(_collectAssetReferenceTypes);
|
EditorGUILayout.PropertyField(_collectAssetReferenceTypes);
|
||||||
EditorGUILayout.PropertyField(_outputLinkFile);
|
EditorGUILayout.PropertyField(_outputLinkFile);
|
||||||
EditorGUILayout.PropertyField(_outputAOTGenericReferenceFile);
|
EditorGUILayout.PropertyField(_outputAOTGenericReferenceFile);
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,6 @@ namespace HybridCLR.Editor
|
||||||
[Header("补充元数据AOT dlls")]
|
[Header("补充元数据AOT dlls")]
|
||||||
public string[] patchAOTAssemblies;
|
public string[] patchAOTAssemblies;
|
||||||
|
|
||||||
[Header("差分混合热更新 dlls")]
|
|
||||||
public string[] differentialHybridAssemblies;
|
|
||||||
|
|
||||||
[Header("差分混合热更新配置数据输出目录")]
|
|
||||||
public string differentialHybridOptionOutputDir = "Assets/StreamingAssets";
|
|
||||||
|
|
||||||
[Header("生成link.xml时扫描asset中引用的类型")]
|
[Header("生成link.xml时扫描asset中引用的类型")]
|
||||||
public bool collectAssetReferenceTypes;
|
public bool collectAssetReferenceTypes;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,15 @@ namespace HybridCLR.Editor
|
||||||
{
|
{
|
||||||
public static class SettingsUtil
|
public static class SettingsUtil
|
||||||
{
|
{
|
||||||
public static bool Enable => HybridCLRSettings.Instance.enable;
|
public static bool Enable
|
||||||
|
{
|
||||||
|
get => HybridCLRSettings.Instance.enable;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
HybridCLRSettings.Instance.enable = value;
|
||||||
|
HybridCLRSettings.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string PackageName { get; } = "com.focus-creative-games.hybridclr_unity";
|
public static string PackageName { get; } = "com.focus-creative-games.hybridclr_unity";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace HybridCLR.Runtime
|
|
||||||
{
|
|
||||||
public class DifferentialHybridAssemblyOptions
|
|
||||||
{
|
|
||||||
public const uint Signature = 0xABCDABCD;
|
|
||||||
|
|
||||||
public List<uint> notChangeMethodTokens;
|
|
||||||
|
|
||||||
|
|
||||||
public byte[] Marshal()
|
|
||||||
{
|
|
||||||
var stream = new MemoryStream();
|
|
||||||
var writer = new BinaryWriter(stream);
|
|
||||||
writer.Write(Signature);
|
|
||||||
writer.Write((uint)notChangeMethodTokens.Count);
|
|
||||||
foreach (uint token in notChangeMethodTokens)
|
|
||||||
{
|
|
||||||
writer.Write(token);
|
|
||||||
}
|
|
||||||
writer.Flush();
|
|
||||||
stream.Flush();
|
|
||||||
byte[] result = new byte[stream.Length];
|
|
||||||
stream.Position = 0;
|
|
||||||
stream.Read(result, 0, result.Length);
|
|
||||||
Debug.Log($"HotPatchAssemblyConfig. options bytes:{result.Length}");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 3394055921ccce643b09466544ea3634
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -46,56 +46,6 @@ namespace HybridCLR
|
||||||
public static extern unsafe int LoadMetadataForAOTAssembly(byte* dllBytes, int dllSize, int mode);
|
public static extern unsafe int LoadMetadataForAOTAssembly(byte* dllBytes, int dllSize, int mode);
|
||||||
|
|
||||||
|
|
||||||
//[DllImport(dllName, EntryPoint = "RuntimeApi_UseDifferentialHybridAOTAssembly")]
|
|
||||||
//public static unsafe LoadImageErrorCode UseDifferentialHybridAOTAssembly(string assemblyName)
|
|
||||||
//{
|
|
||||||
// byte[] nameBytes = System.Text.Encoding.UTF8.GetBytes(assemblyName);
|
|
||||||
// fixed(byte* namePtr = nameBytes)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 指示混合执行assembly使用原始的AOT代码。当assembly没有发生变化时必须调用此接口。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="assemblyName"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
public static LoadImageErrorCode UseDifferentialHybridAOTAssembly(string assemblyName)
|
|
||||||
{
|
|
||||||
return LoadImageErrorCode.OK;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
[DllImport(dllName, EntryPoint = "RuntimeApi_UseDifferentialHybridAOTAssembly")]
|
|
||||||
public static extern LoadImageErrorCode UseDifferentialHybridAOTAssembly(string assemblyName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载差分混合执行 assembly
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dllBytes"></param>
|
|
||||||
/// <param name="optionBytes"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static unsafe LoadImageErrorCode LoadDifferentialHybridAssembly(byte[] dllBytes, byte[] optionBytes)
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
return LoadImageErrorCode.OK;
|
|
||||||
#else
|
|
||||||
fixed(byte* dllBytesPtr = dllBytes)
|
|
||||||
{
|
|
||||||
fixed(byte* optionBytesPtr = optionBytes)
|
|
||||||
{
|
|
||||||
return (LoadImageErrorCode)LoadDifferentialHybridAssembly(dllBytesPtr, dllBytes.Length, optionBytesPtr, optionBytes.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport(dllName, EntryPoint = "RuntimeApi_LoadDifferentialHybridAssembly")]
|
|
||||||
public static extern unsafe int LoadDifferentialHybridAssembly(byte* dllBytes, int dllSize, byte* optionBytesPtr, int optionBytesLength);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取解释器线程栈的最大StackObject个数(size*8 为最终占用的内存大小)
|
/// 获取解释器线程栈的最大StackObject个数(size*8 为最终占用的内存大小)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace HybridCLR.Runtime
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Struct)]
|
|
||||||
public class UnchangedAttribute : Attribute
|
|
||||||
{
|
|
||||||
public bool Unchanged { get; }
|
|
||||||
|
|
||||||
public UnchangedAttribute(bool unchanged = true)
|
|
||||||
{
|
|
||||||
Unchanged = unchanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 704603a2a0551f247a30e331ca476870
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "com.focus-creative-games.hybridclr_unity",
|
"name": "com.focus-creative-games.hybridclr_unity",
|
||||||
"version": "1.0.1",
|
"version": "1.0.11",
|
||||||
"displayName": "HybridCLR",
|
"displayName": "HybridCLR",
|
||||||
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
||||||
"category": "Runtime",
|
"category": "Runtime",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue