2026-06-06 20:12:40 +07:00
parent de84b2bf48
commit 97ac0f71f5
13682 changed files with 1125938 additions and 0 deletions
@@ -0,0 +1,215 @@
using UnityEditor;
using UnityEngine;
using SynapticAIPro;
using System.IO;
using System.Linq;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
namespace SynapticPro
{
/// <summary>
/// Detects installed Cinemachine version and defines appropriate scripting symbols
/// Supports both Cinemachine 2.x and 3.x
/// Automatically installs Unity.Splines dependency for Cinemachine 3.x
/// </summary>
[InitializeOnLoad]
public static class CinemachineVersionDetector
{
private const string CINEMACHINE_2_SYMBOL = "CINEMACHINE_2";
private const string CINEMACHINE_3_SYMBOL = "CINEMACHINE_3";
private const string CINEMACHINE_SYMBOL = "CINEMACHINE";
private const string SPLINES_PACKAGE = "com.unity.splines";
private static AddRequest splinesAddRequest;
static CinemachineVersionDetector()
{
DetectAndSetSymbols();
}
[MenuItem("Tools/Synaptic Pro/Detect Cinemachine Version")]
public static void DetectAndSetSymbols()
{
var cinemachineVersion = GetCinemachineVersion();
if (cinemachineVersion == null)
{
SynLog.Info("[Synaptic] Cinemachine not detected. Cinemachine features will be disabled.");
RemoveAllCinemachineSymbols();
return;
}
SynLog.Info($"[Synaptic] Detected Cinemachine version: {cinemachineVersion}");
// Parse version
var versionParts = cinemachineVersion.Split('.');
if (versionParts.Length > 0 && int.TryParse(versionParts[0], out int majorVersion))
{
if (majorVersion >= 3)
{
SetCinemachineSymbol(3);
SynLog.Info("[Synaptic] ✅ Cinemachine 3.x detected - Using Cinemachine 3 API");
// Cinemachine 3.x requires Unity.Splines package
CheckAndInstallSplines();
}
else if (majorVersion == 2)
{
SetCinemachineSymbol(2);
SynLog.Info("[Synaptic] ✅ Cinemachine 2.x detected - Using Cinemachine 2 API");
}
else
{
SynLog.Warn($"[Synaptic] ⚠️ Unsupported Cinemachine version: {cinemachineVersion}. Recommended: 2.9.7 or 3.0+");
RemoveAllCinemachineSymbols();
}
}
}
private static string GetCinemachineVersion()
{
// Check via PackageInfo
var request = UnityEditor.PackageManager.Client.List(true, false);
// Wait for completion (synchronous for InitializeOnLoad)
while (!request.IsCompleted)
{
System.Threading.Thread.Sleep(10);
}
if (request.Status == UnityEditor.PackageManager.StatusCode.Success)
{
var cinemachinePackage = request.Result.FirstOrDefault(p => p.name == "com.unity.cinemachine");
if (cinemachinePackage != null)
{
return cinemachinePackage.version;
}
}
// Fallback: Check if namespace exists via type checking
var cinemachine2Type = System.Type.GetType("Cinemachine.CinemachineVirtualCamera, Cinemachine");
var cinemachine3Type = System.Type.GetType("Unity.Cinemachine.CinemachineCamera, Unity.Cinemachine");
if (cinemachine3Type != null)
{
return "3.0.0"; // 3.x detected
}
else if (cinemachine2Type != null)
{
return "2.9.7"; // 2.x detected
}
return null; // Not installed
}
private static void SetCinemachineSymbol(int majorVersion)
{
var buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
var definesList = defines.Split(';').ToList();
// Remove old symbols
definesList.Remove(CINEMACHINE_2_SYMBOL);
definesList.Remove(CINEMACHINE_3_SYMBOL);
definesList.Remove(CINEMACHINE_SYMBOL);
// Add appropriate symbols
definesList.Add(CINEMACHINE_SYMBOL);
if (majorVersion == 2)
{
definesList.Add(CINEMACHINE_2_SYMBOL);
}
else if (majorVersion == 3)
{
definesList.Add(CINEMACHINE_3_SYMBOL);
}
var newDefines = string.Join(";", definesList.Distinct().Where(s => !string.IsNullOrEmpty(s)));
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, newDefines);
SynLog.Info($"[Synaptic] Scripting symbols updated: {newDefines}");
}
private static void RemoveAllCinemachineSymbols()
{
var buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
var definesList = defines.Split(';').ToList();
definesList.Remove(CINEMACHINE_2_SYMBOL);
definesList.Remove(CINEMACHINE_3_SYMBOL);
definesList.Remove(CINEMACHINE_SYMBOL);
var newDefines = string.Join(";", definesList.Distinct().Where(s => !string.IsNullOrEmpty(s)));
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, newDefines);
SynLog.Info("[Synaptic] Cinemachine symbols removed");
}
private static void CheckAndInstallSplines()
{
var listRequest = Client.List(true, false);
// Wait for completion (synchronous for simplicity)
while (!listRequest.IsCompleted)
{
System.Threading.Thread.Sleep(10);
}
if (listRequest.Status == StatusCode.Success)
{
bool isInstalled = false;
foreach (var package in listRequest.Result)
{
if (package.name == SPLINES_PACKAGE)
{
isInstalled = true;
SynLog.Info($"[Synaptic] Unity.Splines is already installed (version {package.version})");
break;
}
}
if (!isInstalled)
{
SynLog.Info("[Synaptic] Unity.Splines not found. Installing dependency for Cinemachine 3.x...");
InstallSplines();
}
}
else if (listRequest.Status >= StatusCode.Failure)
{
Debug.LogError($"[Synaptic] Failed to check Splines package: {listRequest.Error.message}");
}
}
private static void InstallSplines()
{
splinesAddRequest = Client.Add(SPLINES_PACKAGE);
EditorApplication.update += CheckSplinesInstallProgress;
}
private static void CheckSplinesInstallProgress()
{
if (splinesAddRequest == null || !splinesAddRequest.IsCompleted)
return;
EditorApplication.update -= CheckSplinesInstallProgress;
if (splinesAddRequest.Status == StatusCode.Success)
{
SynLog.Info($"[Synaptic] ✅ Successfully installed {SPLINES_PACKAGE} for Cinemachine 3.x");
SynLog.Info("[Synaptic] Please wait for Unity to recompile scripts...");
}
else if (splinesAddRequest.Status >= StatusCode.Failure)
{
Debug.LogError($"[Synaptic] ❌ Failed to install {SPLINES_PACKAGE}: {splinesAddRequest.Error.message}");
SynLog.Warn("[Synaptic] Cinemachine 3.x requires Unity.Splines package.\n" +
"Please install it manually via Package Manager:\n" +
"Window > Package Manager > + > Add package by name...\n" +
$"Package name: {SPLINES_PACKAGE}");
}
splinesAddRequest = null;
}
}
}