parent
bbb6cd59e6
commit
a3d6a53f0f
47 changed files with 1492 additions and 414 deletions
@ -0,0 +1,77 @@ |
||||
# Visual Studio Reference: https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options |
||||
# Rider Reference: https://www.jetbrains.com/help/rider/EditorConfig_Index.html |
||||
|
||||
# Top-most EditorConfig file |
||||
root = true |
||||
|
||||
[*] |
||||
indent_style = space |
||||
|
||||
[*.{json,asmdef}] |
||||
indent_size = 2 |
||||
|
||||
[*.cs] |
||||
# Basic Text Settings |
||||
indent_size = 4 |
||||
insert_final_newline = true |
||||
max_line_length = 120 |
||||
trim_trailing_whitespace = true |
||||
charset = utf-8 |
||||
|
||||
# C# Code Style Settings |
||||
|
||||
# Require accessibility modifiers (e.g., private, public), do not omit |
||||
dotnet_style_require_accessibility_modifiers = always:warning |
||||
|
||||
# Avoid "this." unless necessary |
||||
dotnet_style_qualification_for_field = false:warning |
||||
dotnet_style_qualification_for_property = false:warning |
||||
dotnet_style_qualification_for_method = false:warning |
||||
dotnet_style_qualification_for_event = false:warning |
||||
|
||||
# Use language keywords (e.g., int) instead of framework type names (e.g., Int32) |
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning |
||||
dotnet_style_predefined_type_for_member_access = true:warning |
||||
|
||||
# Prefer "var" |
||||
csharp_style_var_for_built_in_types = true:warning |
||||
csharp_style_var_when_type_is_apparent = true:warning |
||||
csharp_style_var_elsewhere = true:warning |
||||
|
||||
# Prefer braces even for single-line statements |
||||
csharp_prefer_braces = true:warning |
||||
|
||||
# Formatting details |
||||
csharp_space_after_cast = false |
||||
csharp_preserve_single_line_blocks = true |
||||
csharp_space_within_single_line_array_initializer_braces = true |
||||
|
||||
# Naming Conventions |
||||
|
||||
# 1. Define symbol groups |
||||
# All fields (variables) |
||||
dotnet_naming_symbols.all_fields.applicable_kinds = field |
||||
dotnet_naming_symbols.all_fields.applicable_accessibilities = * |
||||
|
||||
# Properties |
||||
dotnet_naming_symbols.all_properties.applicable_kinds = property |
||||
dotnet_naming_symbols.all_properties.applicable_accessibilities = * |
||||
|
||||
# 2. Define naming styles |
||||
# camelCase |
||||
dotnet_naming_style.style_camel_case.capitalization = camel_case |
||||
|
||||
# PascalCase |
||||
dotnet_naming_style.style_pascal_case.capitalization = pascal_case |
||||
|
||||
# 3. Define rules |
||||
|
||||
# Rule: Use camelCase for all fields (both public and private) |
||||
dotnet_naming_rule.fields_must_be_camel_case.symbols = all_fields |
||||
dotnet_naming_rule.fields_must_be_camel_case.style = style_camel_case |
||||
dotnet_naming_rule.fields_must_be_camel_case.severity = warning |
||||
|
||||
# Rule: Use PascalCase for properties |
||||
dotnet_naming_rule.properties_must_be_pascal_case.symbols = all_properties |
||||
dotnet_naming_rule.properties_must_be_pascal_case.style = style_pascal_case |
||||
dotnet_naming_rule.properties_must_be_pascal_case.severity = warning |
||||
@ -0,0 +1,18 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<configuration> |
||||
<packageSources> |
||||
<clear /> |
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" enableCredentialProvider="false" /> |
||||
</packageSources> |
||||
<disabledPackageSources /> |
||||
<activePackageSource> |
||||
<add key="All" value="(Aggregate source)" /> |
||||
</activePackageSource> |
||||
<config> |
||||
<add key="packageInstallLocation" value="CustomWithinAssets" /> |
||||
<add key="repositoryPath" value="./Packages" /> |
||||
<add key="PackagesConfigDirectoryPath" value="." /> |
||||
<add key="slimRestore" value="true" /> |
||||
<add key="PreferNetStandardOverNetFramework" value="true" /> |
||||
</config> |
||||
</configuration> |
||||
@ -0,0 +1,28 @@ |
||||
fileFormatVersion: 2 |
||||
guid: dac4df2f30345e74589a00c80f392aa2 |
||||
labels: |
||||
- NuGetForUnity |
||||
PluginImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 3 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
defineConstraints: [] |
||||
isPreloaded: 0 |
||||
isOverridable: 0 |
||||
isExplicitlyReferenced: 0 |
||||
validateReferences: 1 |
||||
platformData: |
||||
Any: |
||||
enabled: 0 |
||||
settings: {} |
||||
Editor: |
||||
enabled: 0 |
||||
settings: |
||||
DefaultValueInitialized: true |
||||
WindowsStoreApps: |
||||
enabled: 0 |
||||
settings: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,8 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 26aec5e520aedf4459f70238f1d4c30e |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,8 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 1ef755df0e033724aa722a2976b1614e |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,16 @@ |
||||
using UnityEngine; |
||||
|
||||
public class GroundControl : MonoBehaviour |
||||
{ |
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created |
||||
void Start() |
||||
{ |
||||
|
||||
} |
||||
|
||||
// Update is called once per frame |
||||
void Update() |
||||
{ |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 3f58a2d2c726666469a5aa224f7227bc |
||||
@ -0,0 +1,28 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 97b3022388ed5df4f909d9f53d8cb399 |
||||
labels: |
||||
- NuGetForUnity |
||||
PluginImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 3 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
defineConstraints: [] |
||||
isPreloaded: 0 |
||||
isOverridable: 0 |
||||
isExplicitlyReferenced: 0 |
||||
validateReferences: 1 |
||||
platformData: |
||||
Any: |
||||
enabled: 0 |
||||
settings: {} |
||||
Editor: |
||||
enabled: 0 |
||||
settings: |
||||
DefaultValueInitialized: true |
||||
WindowsStoreApps: |
||||
enabled: 0 |
||||
settings: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,77 @@ |
||||
# Visual Studio Reference: https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options |
||||
# Rider Reference: https://www.jetbrains.com/help/rider/EditorConfig_Index.html |
||||
|
||||
# Top-most EditorConfig file |
||||
root = true |
||||
|
||||
[*] |
||||
indent_style = space |
||||
|
||||
[*.{json,asmdef}] |
||||
indent_size = 2 |
||||
|
||||
[*.cs] |
||||
# Basic Text Settings |
||||
indent_size = 4 |
||||
insert_final_newline = true |
||||
max_line_length = 120 |
||||
trim_trailing_whitespace = true |
||||
charset = utf-8 |
||||
|
||||
# C# Code Style Settings |
||||
|
||||
# Require accessibility modifiers (e.g., private, public), do not omit |
||||
dotnet_style_require_accessibility_modifiers = always:warning |
||||
|
||||
# Avoid "this." unless necessary |
||||
dotnet_style_qualification_for_field = false:warning |
||||
dotnet_style_qualification_for_property = false:warning |
||||
dotnet_style_qualification_for_method = false:warning |
||||
dotnet_style_qualification_for_event = false:warning |
||||
|
||||
# Use language keywords (e.g., int) instead of framework type names (e.g., Int32) |
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning |
||||
dotnet_style_predefined_type_for_member_access = true:warning |
||||
|
||||
# Prefer "var" |
||||
csharp_style_var_for_built_in_types = true:warning |
||||
csharp_style_var_when_type_is_apparent = true:warning |
||||
csharp_style_var_elsewhere = true:warning |
||||
|
||||
# Prefer braces even for single-line statements |
||||
csharp_prefer_braces = true:warning |
||||
|
||||
# Formatting details |
||||
csharp_space_after_cast = false |
||||
csharp_preserve_single_line_blocks = true |
||||
csharp_space_within_single_line_array_initializer_braces = true |
||||
|
||||
# Naming Conventions |
||||
|
||||
# 1. Define symbol groups |
||||
# All fields (variables) |
||||
dotnet_naming_symbols.all_fields.applicable_kinds = field |
||||
dotnet_naming_symbols.all_fields.applicable_accessibilities = * |
||||
|
||||
# Properties |
||||
dotnet_naming_symbols.all_properties.applicable_kinds = property |
||||
dotnet_naming_symbols.all_properties.applicable_accessibilities = * |
||||
|
||||
# 2. Define naming styles |
||||
# camelCase |
||||
dotnet_naming_style.style_camel_case.capitalization = camel_case |
||||
|
||||
# PascalCase |
||||
dotnet_naming_style.style_pascal_case.capitalization = pascal_case |
||||
|
||||
# 3. Define rules |
||||
|
||||
# Rule: Use camelCase for all fields (both public and private) |
||||
dotnet_naming_rule.fields_must_be_camel_case.symbols = all_fields |
||||
dotnet_naming_rule.fields_must_be_camel_case.style = style_camel_case |
||||
dotnet_naming_rule.fields_must_be_camel_case.severity = warning |
||||
|
||||
# Rule: Use PascalCase for properties |
||||
dotnet_naming_rule.properties_must_be_pascal_case.symbols = all_properties |
||||
dotnet_naming_rule.properties_must_be_pascal_case.style = style_pascal_case |
||||
dotnet_naming_rule.properties_must_be_pascal_case.severity = warning |
||||
@ -0,0 +1,81 @@ |
||||
# This .gitignore file should be placed at the root of your Unity project directory |
||||
# |
||||
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore |
||||
# |
||||
/[Ll]ibrary/ |
||||
/[Tt]emp/ |
||||
/[Oo]bj/ |
||||
/[Bb]uild/ |
||||
/[Bb]uilds/ |
||||
/[Ll]ogs/ |
||||
/[Uu]ser[Ss]ettings/ |
||||
|
||||
# MemoryCaptures can get excessive in size. |
||||
# They also could contain extremely sensitive data |
||||
/[Mm]emoryCaptures/ |
||||
|
||||
# Asset meta data should only be ignored when the corresponding asset is also ignored |
||||
!/[Aa]ssets/**/*.meta |
||||
|
||||
# Uncomment this line if you wish to ignore the asset store tools plugin |
||||
# /[Aa]ssets/AssetStoreTools* |
||||
|
||||
# Autogenerated Jetbrains Rider plugin |
||||
/[Aa]ssets/Plugins/Editor/JetBrains* |
||||
|
||||
# Visual Studio cache directory |
||||
.vs/ |
||||
|
||||
# Gradle cache directory |
||||
.gradle/ |
||||
|
||||
# Autogenerated VS/MD/Consulo solution and project files |
||||
ExportedObj/ |
||||
.consulo/ |
||||
*.csproj |
||||
*.unityproj |
||||
*.sln |
||||
*.suo |
||||
*.tmp |
||||
*.user |
||||
*.userprefs |
||||
*.pidb |
||||
*.booproj |
||||
*.svd |
||||
*.pdb |
||||
*.mdb |
||||
*.opendb |
||||
*.VC.db |
||||
|
||||
# Unity3D generated meta files |
||||
*.pidb.meta |
||||
*.pdb.meta |
||||
*.mdb.meta |
||||
|
||||
# Unity3D generated file on crash reports |
||||
sysinfo.txt |
||||
|
||||
# Builds |
||||
*.apk |
||||
*.unitypackage |
||||
*.unitypackage.meta |
||||
|
||||
# Crashlytics generated file |
||||
crashlytics-build.properties |
||||
|
||||
# Packed Addressables |
||||
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* |
||||
|
||||
# Temporary auto-generated Android Assets |
||||
/[Aa]ssets/[Ss]treamingAssets/aa.meta |
||||
/[Aa]ssets/[Ss]treamingAssets/aa/* |
||||
|
||||
# Visual Studio Code |
||||
/.vscode/ |
||||
|
||||
# Rider |
||||
/.idea/ |
||||
|
||||
# Custom |
||||
.vsconfig |
||||
.claude |
||||
@ -0,0 +1,8 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 4a919d6d440ab9846b7755d9e4f6cece |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,182 @@ |
||||
#if UNITY_EDITOR |
||||
using System.IO; |
||||
using System.Linq; |
||||
using UnityEditor; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public class Deploy |
||||
{ |
||||
private const string head = "[Giant Museum]"; |
||||
|
||||
[MenuItem(head + "/Build Project")] |
||||
public static void BuildProject() |
||||
{ |
||||
Build(new BuildPlayerOptions() |
||||
{ |
||||
scenes = CollectScenesPath(), |
||||
locationPathName = PlayerOutputPath, |
||||
target = EditorUserBuildSettings.activeBuildTarget, |
||||
options = BuildOptions.None, |
||||
}); |
||||
} |
||||
/* |
||||
[MenuItem( head + "/Build Development" )] |
||||
public static void BuildProjectDevelopement() |
||||
{ |
||||
Build( new BuildPlayerOptions() |
||||
{ |
||||
scenes = CollectScenesPath(), |
||||
locationPathName = DevelopmentOutputFolder, |
||||
target = EditorUserBuildSettings.activeBuildTarget, |
||||
//options = BuildOptions.Development | BuildOptions.SymlinkLibraries, |
||||
options = BuildOptions.Development, |
||||
} ); |
||||
} |
||||
*/ |
||||
private static void Build(BuildPlayerOptions options) |
||||
{ |
||||
BuildPlayer(options); |
||||
|
||||
GenerateIgnoreFile(); |
||||
GenerateAttributeFile(); |
||||
#if UNITY_STANDALONE_WIN |
||||
GenerateBatchFile(); |
||||
#endif |
||||
} |
||||
|
||||
[MenuItem(head + "/Open Output Folder")] |
||||
public static void OpenFolder() |
||||
{ |
||||
EditorUtility.RevealInFinder(RootOutputFolder); |
||||
} |
||||
|
||||
private static string[] CollectScenesPath() |
||||
{ |
||||
return EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(); |
||||
} |
||||
|
||||
private static string CheckFolder(string path) |
||||
{ |
||||
if (Directory.Exists(path) == false) |
||||
{ |
||||
Log.Info("Deploy", $"Create directory: {path}"); |
||||
Directory.CreateDirectory(path); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
private static string RootOutputFolder |
||||
{ |
||||
get |
||||
{ |
||||
var path = Core.BuildPath; |
||||
CheckFolder($"{path}/Material"); |
||||
return CheckFolder(path); |
||||
} |
||||
} |
||||
|
||||
private static string PlayerOutputFolder |
||||
{ |
||||
get |
||||
{ |
||||
var path = $"{RootOutputFolder}/{Core.OutputFolderName}"; |
||||
return CheckFolder(path); |
||||
} |
||||
} |
||||
|
||||
private static string DevelopmentOutputFolder |
||||
{ |
||||
get |
||||
{ |
||||
var path = $"{RootOutputFolder}/{Core.OutputFolderName} - Dev"; |
||||
return CheckFolder(path); |
||||
} |
||||
} |
||||
|
||||
private static string PlayerOutputPath |
||||
{ |
||||
get |
||||
{ |
||||
#if UNITY_STANDALONE_WIN |
||||
return $"{PlayerOutputFolder}/{PlayerSettings.productName}.exe"; |
||||
#elif UNITY_ANDROID |
||||
return $"{PlayerOutputFolder}.apk"; |
||||
#else |
||||
return $"{PlayerOutputFolder}"; |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
private static void BuildPlayer(BuildPlayerOptions buildPlayerOptions) |
||||
{ |
||||
var report = BuildPipeline.BuildPlayer(buildPlayerOptions); |
||||
var summary = report.summary; |
||||
var totalSizeMB = summary.totalSize / 1024.0 / 1024.0; |
||||
Log.Info("Deploy", $"Build {summary.result}: {totalSizeMB:N2} MB"); |
||||
} |
||||
|
||||
#if UNITY_EDITOR_WIN |
||||
private static void GenerateBatchFile() |
||||
{ |
||||
var path = $"{RootOutputFolder}/startup.bat"; |
||||
if (File.Exists(path)) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
var contents = $@"@ECHO OFF
|
||||
SETLOCAL |
||||
|
||||
SET ""BASE_DIR=%~dp0"" |
||||
|
||||
ECHO Starting {PlayerSettings.productName}... |
||||
START """" /D ""%BASE_DIR%{Core.OutputFolderName}"" ""{PlayerSettings.productName}.exe"" |
||||
|
||||
TIMEOUT /t 10 |
||||
|
||||
ECHO All programs started.";
|
||||
|
||||
File.WriteAllText(path, contents, System.Text.Encoding.Default); |
||||
Log.Info("Deploy", $"Generate batch file: {path}"); |
||||
} |
||||
#endif |
||||
|
||||
private static void GenerateIgnoreFile() |
||||
{ |
||||
var path = $"{RootOutputFolder}/.gitignore"; |
||||
if (File.Exists(path)) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
var contents = "\n"; |
||||
File.WriteAllText(path, contents); |
||||
Log.Info("Deploy", $"Generate ignore file: {path}"); |
||||
} |
||||
|
||||
private static void GenerateAttributeFile() |
||||
{ |
||||
var filename = ".gitattributes"; |
||||
var destPath = Path.Combine(RootOutputFolder, filename); |
||||
if (!File.Exists(filename) || File.Exists(destPath)) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
var name = Core.OutputFolderName; |
||||
var suffix = "filter=lfs diff=lfs merge=lfs"; |
||||
var baseContent = File.ReadAllText(filename); |
||||
var newLines = $@"
|
||||
# Build Output |
||||
Materials/** |
||||
{name}/** {suffix} |
||||
";
|
||||
File.WriteAllText(destPath, baseContent + "\n" + newLines.Trim()); |
||||
Log.Info("Deploy", $"Generate attribute file: {destPath}"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
#endif |
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 3f893003e6b7226428811d6c5a07f82f |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,13 @@ |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))] |
||||
public class ReadOnlyDrawer : PropertyDrawer |
||||
{ |
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) |
||||
{ |
||||
GUI.enabled = false; |
||||
EditorGUI.PropertyField(position, property, label, true); |
||||
GUI.enabled = true; |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 364be54ac7969f6418f79eb8e85de2de |
||||
@ -0,0 +1,18 @@ |
||||
{ |
||||
"name": "UltraCombos.GiantMuseum.Editor", |
||||
"rootNamespace": "UltraCombos.GiantMuseum", |
||||
"references": [ |
||||
"GUID:b2e08e75d81bb8b408397e7998130fbb" |
||||
], |
||||
"includePlatforms": [ |
||||
"Editor" |
||||
], |
||||
"excludePlatforms": [], |
||||
"allowUnsafeCode": false, |
||||
"overrideReferences": false, |
||||
"precompiledReferences": [], |
||||
"autoReferenced": true, |
||||
"defineConstraints": [], |
||||
"versionDefines": [], |
||||
"noEngineReferences": false |
||||
} |
||||
@ -0,0 +1,7 @@ |
||||
fileFormatVersion: 2 |
||||
guid: bc7633bff7d9fb941a66c76cbb3de878 |
||||
AssemblyDefinitionImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,8 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 9fdba1625ae889b4cb89256f3dc4aa51 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,48 @@ |
||||
using UnityEngine; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public class Core |
||||
{ |
||||
public static class Project |
||||
{ |
||||
public static int Serial => 25014; |
||||
} |
||||
|
||||
#if UNITY_EDITOR |
||||
public static string OutputFolderName |
||||
{ |
||||
get |
||||
{ |
||||
return $"{UnityEditor.PlayerSettings.productName.Replace(" ", "")}"; |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
public static string BuildPath |
||||
{ |
||||
get |
||||
{ |
||||
#if UNITY_EDITOR |
||||
|
||||
var path = $"{Application.dataPath}/../../../../Deploy/Build-{OutputFolderName}"; |
||||
#else |
||||
#if UNITY_STANDALONE |
||||
var path = $"{Application.dataPath}/../.."; |
||||
#else |
||||
var path = $"{Application.persistentDataPath}"; |
||||
#endif |
||||
#endif |
||||
var dir = new System.IO.DirectoryInfo(path); |
||||
return dir.FullName; |
||||
} |
||||
} |
||||
|
||||
public static string MaterialPath |
||||
{ |
||||
get { return $"{BuildPath}/Material"; } |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: cff989983e378fd45bbc38525908aefd |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,150 @@ |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using UnityEngine; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public class Misc |
||||
{ |
||||
public static object GetInstanceField(System.Type type, object instance, string fieldName) |
||||
{ |
||||
var bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; |
||||
var field = type.GetField(fieldName, bindFlags); |
||||
return field.GetValue(instance); |
||||
} |
||||
|
||||
public static string NameOfCallingClass() |
||||
{ |
||||
string fullName; |
||||
System.Type declaringType; |
||||
var skipFrames = 2; |
||||
do |
||||
{ |
||||
var method = new System.Diagnostics.StackFrame(skipFrames, false).GetMethod(); |
||||
declaringType = method.DeclaringType; |
||||
if (declaringType == null) |
||||
{ |
||||
return method.Name; |
||||
} |
||||
skipFrames++; |
||||
fullName = declaringType.FullName; |
||||
} |
||||
while (declaringType.Module.Name.Equals("mscorlib.dll", System.StringComparison.OrdinalIgnoreCase)); |
||||
|
||||
return fullName; |
||||
} |
||||
|
||||
public static byte[] ObjectToByteArray<T>(T obj) |
||||
{ |
||||
if (obj == null) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
||||
using (var ms = new System.IO.MemoryStream()) |
||||
{ |
||||
bf.Serialize(ms, obj); |
||||
return ms.ToArray(); |
||||
} |
||||
} |
||||
|
||||
public static T ByteArrayToObject<T>(byte[] arrBytes) |
||||
{ |
||||
using (var ms = new System.IO.MemoryStream()) |
||||
{ |
||||
var binForm = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
||||
ms.Write(arrBytes, 0, arrBytes.Length); |
||||
ms.Seek(0, System.IO.SeekOrigin.Begin); |
||||
var obj = (T)binForm.Deserialize(ms); |
||||
return obj; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static class Auto |
||||
{ |
||||
public static IEnumerable<T> Collect<T>(Transform target) where T : MonoBehaviour |
||||
{ |
||||
return target.GetComponentsInChildren<T>() |
||||
.Where(c => c.transform.parent == target); |
||||
} |
||||
|
||||
public static IEnumerable<GameObject> CollectGameObjects<T>(Transform target) where T : MonoBehaviour |
||||
{ |
||||
return Collect<T>(target) |
||||
.Select(c => c.gameObject); |
||||
} |
||||
|
||||
public static List<GameObject> Generate<T>(Transform target, T template, int count, string naming) where T : MonoBehaviour |
||||
{ |
||||
if (target == null || template == null || count < 0) |
||||
{ |
||||
return new List<GameObject>(); |
||||
} |
||||
|
||||
var comps = Collect<T>(target).Select(c => c.gameObject).ToList(); |
||||
var stack = new Stack<GameObject>(); |
||||
comps.ForEach(c => stack.Push(c)); |
||||
|
||||
while (stack.Count < count) |
||||
{ |
||||
var go = Object.Instantiate(template.gameObject, target); |
||||
go.name = $"{naming} - {stack.Count:D4}"; |
||||
stack.Push(go); |
||||
} |
||||
|
||||
while (stack.Count > count) |
||||
{ |
||||
var go = stack.Pop(); |
||||
#if UNITY_EDITOR |
||||
Object.DestroyImmediate(go); |
||||
#else |
||||
Object.Destroy( go ); |
||||
#endif |
||||
} |
||||
|
||||
return stack.ToList(); |
||||
} |
||||
|
||||
public static void Align(List<GameObject> objs, Vector3 spacing, Vector3 offset) |
||||
{ |
||||
for (var i = 0; i < objs.Count; ++i) |
||||
{ |
||||
var o = objs[i]; |
||||
o.transform.localPosition = offset + spacing * i; |
||||
} |
||||
} |
||||
|
||||
public static void Destroy<T>(Transform target) where T : MonoBehaviour |
||||
{ |
||||
var objects = CollectGameObjects<T>(target); |
||||
foreach (var go in objects) |
||||
{ |
||||
#if UNITY_EDITOR |
||||
Object.DestroyImmediate(go); |
||||
#else |
||||
Object.Destroy( go ); |
||||
#endif |
||||
} |
||||
; |
||||
} |
||||
} |
||||
|
||||
public static class Extension |
||||
{ |
||||
public static Vector2 Rotate(this Vector2 v, float delta) |
||||
{ |
||||
return new Vector2( |
||||
v.x * Mathf.Cos(delta) - v.y * Mathf.Sin(delta), |
||||
v.x * Mathf.Sin(delta) + v.y * Mathf.Cos(delta) |
||||
); |
||||
} |
||||
|
||||
public static long ToUnixTimeMilliseconds(this System.DateTime dateTime) |
||||
{ |
||||
return ((System.DateTimeOffset)dateTime).ToUnixTimeMilliseconds(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: d9f32c2ff30784f4cb45e75db1752c2f |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,95 @@ |
||||
using UnityEngine; |
||||
using UnityEngine.Events; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public class DisplayConfig : MonoBehaviour |
||||
{ |
||||
[Header("Display")] |
||||
[SerializeField] private FullScreenMode mode = FullScreenMode.Windowed; |
||||
[SerializeField] private int displayCount = 1; |
||||
[SerializeField] private Vector2Int resolution = new Vector2Int(1600, 900); |
||||
[SerializeField] private int targetFps = 60; |
||||
|
||||
[Header("Misc")] |
||||
[Range(0, 10)] |
||||
[SerializeField] private float autoHideCursor = 0; |
||||
private float cursorStamp; |
||||
private Vector2 cursorLastPosition; |
||||
[SerializeField] private bool exitOnEsc = true; |
||||
|
||||
private float timestamp = 0; |
||||
[field: SerializeField, ReadOnly] public float CurrentFps { get; private set; } = 30.0f; |
||||
|
||||
[Header("Event")] |
||||
public UnityEvent onQuit = new UnityEvent(); |
||||
|
||||
private void Awake() |
||||
{ |
||||
Application.targetFrameRate = targetFps; |
||||
|
||||
#if UNITY_STANDALONE || UNITY_EDITOR |
||||
if (mode == FullScreenMode.ExclusiveFullScreen) |
||||
{ |
||||
var displays = Display.displays; |
||||
var num = Mathf.Min(Mathf.Max(displayCount, 1), displays.Length); |
||||
for (var i = 0; i < num; ++i) |
||||
{ |
||||
displays[i].Activate(); |
||||
} |
||||
Screen.SetResolution(Screen.width, Screen.height, mode); |
||||
} |
||||
else if (mode == FullScreenMode.FullScreenWindow) |
||||
{ |
||||
Screen.SetResolution(Screen.width, Screen.height, mode); |
||||
} |
||||
else |
||||
{ |
||||
Screen.SetResolution(resolution.x, resolution.y, mode); |
||||
} |
||||
#else |
||||
Screen.sleepTimeout = SleepTimeout.NeverSleep; |
||||
#endif |
||||
} |
||||
|
||||
private void Update() |
||||
{ |
||||
if (autoHideCursor > 0) |
||||
{ |
||||
#if ENABLE_INPUT_SYSTEM |
||||
var pos = UnityEngine.InputSystem.Mouse.current.position.ReadValue(); |
||||
#else |
||||
var pos = (Vector2)Input.mousePosition; |
||||
#endif |
||||
var bias = pos - cursorLastPosition; |
||||
if (bias.magnitude > 1) |
||||
{ |
||||
cursorLastPosition = pos; |
||||
cursorStamp = Time.time; |
||||
} |
||||
|
||||
Cursor.visible = Time.time - cursorStamp < autoHideCursor; |
||||
} |
||||
|
||||
if (Time.time - timestamp > 0) |
||||
{ |
||||
CurrentFps = Mathf.Lerp(CurrentFps, 1.0f / (Time.time - timestamp), Time.deltaTime); |
||||
timestamp = Time.time; |
||||
} |
||||
|
||||
if (exitOnEsc) |
||||
{ |
||||
#if ENABLE_INPUT_SYSTEM |
||||
if (UnityEngine.InputSystem.Keyboard.current.escapeKey.wasPressedThisFrame) |
||||
#else |
||||
if (Input.GetKeyDown(KeyCode.Escape)) |
||||
#endif |
||||
{ |
||||
onQuit.Invoke(); |
||||
Application.Quit(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 63c5372172ea740439535067b0f1a5fc |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,79 @@ |
||||
using System; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Text.RegularExpressions; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public static class DotNetEnv |
||||
{ |
||||
private static readonly Regex lineRegex = new Regex( |
||||
@"(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*""(?:\\""|[^""])*""|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)", |
||||
RegexOptions.Multiline | RegexOptions.Compiled); |
||||
|
||||
public static void Load(string path = ".env") |
||||
{ |
||||
if (!File.Exists(path)) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
var src = File.ReadAllText(path); |
||||
|
||||
src = src.Replace("\r\n", "\n").Replace("\r", "\n"); |
||||
|
||||
var keys = new System.Collections.Generic.List<string>(); |
||||
var matches = lineRegex.Matches(src); |
||||
foreach (Match match in matches) |
||||
{ |
||||
var key = match.Groups[1].Value; |
||||
var value = match.Groups[2].Value.Trim(); |
||||
|
||||
if (string.IsNullOrEmpty(key)) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
var maybeQuote = value.Length > 0 ? value[0] : (char?)null; |
||||
|
||||
value = Regex.Replace(value, @"^(['""`])([\s\S]*)\1$", "$2"); |
||||
|
||||
if (maybeQuote == '"') |
||||
{ |
||||
value = value.Replace("\\n", "\n").Replace("\\r", "\r"); |
||||
} |
||||
|
||||
Environment.SetEnvironmentVariable(key, value); |
||||
keys.Add(key); |
||||
} |
||||
Log.Info("DotNetEnv", $"Loaded environment variable:\n{string.Join("\n", keys)}"); |
||||
} |
||||
|
||||
public static bool TryGet(string key, out string value) |
||||
{ |
||||
value = Environment.GetEnvironmentVariable(key); |
||||
return !string.IsNullOrEmpty(value); |
||||
} |
||||
|
||||
public static bool TryGetAs<T>(string key, out T value) where T : struct
|
||||
{ |
||||
var raw = Environment.GetEnvironmentVariable(key); |
||||
if (string.IsNullOrEmpty(raw)) |
||||
{ |
||||
value = default; |
||||
return false; |
||||
} |
||||
|
||||
try |
||||
{ |
||||
value = (T)Convert.ChangeType(raw, typeof(T), CultureInfo.InvariantCulture); |
||||
return true; |
||||
} |
||||
catch |
||||
{ |
||||
value = default; |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
fileFormatVersion: 2 |
||||
guid: dedd030f6276eb64994275a87ed2af1d |
||||
@ -0,0 +1,21 @@ |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
#if UNITY_EDITOR |
||||
using UnityEditor; |
||||
#endif |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
[ExecuteAlways] |
||||
public class ForceUpdater : MonoBehaviour |
||||
{ |
||||
#if UNITY_EDITOR |
||||
private static void QueueUpdate() => EditorApplication.QueuePlayerLoopUpdate(); |
||||
|
||||
private void OnEnable() => EditorApplication.update += QueueUpdate; |
||||
|
||||
private void OnDisable() => EditorApplication.update -= QueueUpdate; |
||||
#endif |
||||
} |
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: deeebc01fb69bc44a89ee2bc02a6ae88 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,16 @@ |
||||
using UnityEngine; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public static class Log |
||||
{ |
||||
public static void Info(string tag, string message) |
||||
=> Debug.Log($"<b>[{tag}]</b> {message}"); |
||||
|
||||
public static void Warning(string tag, string message) |
||||
=> Debug.LogWarning($"<b>[{tag}]</b> {message}"); |
||||
|
||||
public static void Error(string tag, string message) |
||||
=> Debug.LogError($"<b>[{tag}]</b> {message}"); |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
fileFormatVersion: 2 |
||||
guid: b7e8119c4421cb6489c2708fe2e43b87 |
||||
@ -0,0 +1,3 @@ |
||||
using UnityEngine; |
||||
|
||||
public class ReadOnlyAttribute : PropertyAttribute { } |
||||
@ -0,0 +1,2 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 01f0d168c9980894892226cc1453811f |
||||
@ -0,0 +1,61 @@ |
||||
using UnityEngine; |
||||
|
||||
namespace UltraCombos |
||||
{ |
||||
public abstract class Singleton<T> : MonoBehaviour where T : Component |
||||
{ |
||||
|
||||
#region Fields |
||||
|
||||
private static T instance; |
||||
|
||||
[SerializeField] |
||||
private bool persistance = true; |
||||
|
||||
#endregion |
||||
|
||||
#region Properties |
||||
|
||||
public static T Instance |
||||
{ |
||||
get |
||||
{ |
||||
if (instance == null) |
||||
{ |
||||
instance = FindFirstObjectByType<T>(); |
||||
if (instance == null) |
||||
{ |
||||
var go = new GameObject(); |
||||
go.name = typeof(T).Name; |
||||
instance = go.AddComponent<T>(); |
||||
} |
||||
} |
||||
return instance; |
||||
} |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region Methods |
||||
|
||||
protected virtual void Awake() |
||||
{ |
||||
if (instance == null) |
||||
{ |
||||
instance = this as T; |
||||
if (persistance) |
||||
{ |
||||
DontDestroyOnLoad(gameObject); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
Destroy(gameObject); |
||||
} |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
fileFormatVersion: 2 |
||||
guid: fb66cb43872fa254e94f4f7c8e02ed8f |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,16 @@ |
||||
{ |
||||
"name": "UltraCombos.GiantMuseum.Runtime", |
||||
"rootNamespace": "UltraCombos.GiantMuseum", |
||||
"references": [ |
||||
"GUID:75469ad4d38634e559750d17036d5f7c" |
||||
], |
||||
"includePlatforms": [], |
||||
"excludePlatforms": [], |
||||
"allowUnsafeCode": false, |
||||
"overrideReferences": false, |
||||
"precompiledReferences": [], |
||||
"autoReferenced": true, |
||||
"defineConstraints": [], |
||||
"versionDefines": [], |
||||
"noEngineReferences": false |
||||
} |
||||
@ -0,0 +1,7 @@ |
||||
fileFormatVersion: 2 |
||||
guid: b2e08e75d81bb8b408397e7998130fbb |
||||
AssemblyDefinitionImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -0,0 +1,13 @@ |
||||
{ |
||||
"name": "com.ultracombos.giant-museum", |
||||
"version": "1.0.0", |
||||
"displayName": "Giant Museum", |
||||
"description": "Unity Package for Giant Museum", |
||||
"repository": "", |
||||
"type": "library", |
||||
"author": { |
||||
"name": "ultracombos", |
||||
"url": "https://ultracombos.com", |
||||
"email": "tech@ultracombos.com" |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@ |
||||
fileFormatVersion: 2 |
||||
guid: f68ca7a8d533c8949af848b1a974c513 |
||||
PackageManifestImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
@ -1,49 +1,23 @@ |
||||
{ |
||||
"scopedRegistries": [ |
||||
{ |
||||
"name": "Keijiro", |
||||
"url": "https://registry.npmjs.com", |
||||
"scopes": [ |
||||
"jp.keijiro" |
||||
] |
||||
} |
||||
], |
||||
"dependencies": { |
||||
"com.unity.ai.navigation": "2.0.11", |
||||
"com.unity.collab-proxy": "2.11.4", |
||||
"com.unity.ide.rider": "3.0.39", |
||||
"com.github-glitchenzo.nugetforunity": "https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity", |
||||
"com.unity.ide.visualstudio": "2.0.26", |
||||
"com.unity.inputsystem": "1.19.0", |
||||
"com.unity.multiplayer.center": "1.0.1", |
||||
"com.unity.render-pipelines.universal": "17.3.0", |
||||
"com.unity.test-framework": "1.6.0", |
||||
"com.unity.timeline": "1.8.11", |
||||
"com.unity.ugui": "2.0.0", |
||||
"com.unity.visualscripting": "1.9.11", |
||||
"com.unity.modules.accessibility": "1.0.0", |
||||
"com.unity.modules.adaptiveperformance": "1.0.0", |
||||
"com.unity.modules.ai": "1.0.0", |
||||
"com.unity.modules.androidjni": "1.0.0", |
||||
"com.unity.modules.animation": "1.0.0", |
||||
"com.unity.modules.assetbundle": "1.0.0", |
||||
"com.unity.modules.audio": "1.0.0", |
||||
"com.unity.modules.cloth": "1.0.0", |
||||
"com.unity.modules.director": "1.0.0", |
||||
"com.unity.modules.imageconversion": "1.0.0", |
||||
"com.unity.modules.imgui": "1.0.0", |
||||
"com.unity.modules.jsonserialize": "1.0.0", |
||||
"com.unity.modules.particlesystem": "1.0.0", |
||||
"com.unity.modules.physics": "1.0.0", |
||||
"com.unity.modules.physics2d": "1.0.0", |
||||
"com.unity.modules.screencapture": "1.0.0", |
||||
"com.unity.modules.terrain": "1.0.0", |
||||
"com.unity.modules.terrainphysics": "1.0.0", |
||||
"com.unity.modules.tilemap": "1.0.0", |
||||
"com.unity.modules.ui": "1.0.0", |
||||
"com.unity.modules.uielements": "1.0.0", |
||||
"com.unity.modules.umbra": "1.0.0", |
||||
"com.unity.modules.unityanalytics": "1.0.0", |
||||
"com.unity.modules.unitywebrequest": "1.0.0", |
||||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0", |
||||
"com.unity.modules.unitywebrequestaudio": "1.0.0", |
||||
"com.unity.modules.unitywebrequesttexture": "1.0.0", |
||||
"com.unity.modules.unitywebrequestwww": "1.0.0", |
||||
"com.unity.modules.vectorgraphics": "1.0.0", |
||||
"com.unity.modules.vehicles": "1.0.0", |
||||
"com.unity.modules.video": "1.0.0", |
||||
"com.unity.modules.vr": "1.0.0", |
||||
"com.unity.modules.wind": "1.0.0", |
||||
"com.unity.modules.xr": "1.0.0" |
||||
"jp.keijiro.klak.spout": "https://github.com/UltraCombos/KlakSpout.git?path=Packages/jp.keijiro.klak.spout#main", |
||||
"jp.keijiro.metamesh": "1.2.0", |
||||
"jp.keijiro.metatex": "1.0.4", |
||||
"jp.keijiro.osc-jack": "2.0.0" |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue