DCS资源上传公司gitea地址

This commit is contained in:
root 2026-06-09 13:59:11 +08:00
commit 46f9cf3bf3
1415 changed files with 457597 additions and 0 deletions

155
ruiyiweiUX/.gitignore vendored Normal file
View File

@ -0,0 +1,155 @@
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/gabrieldevsouza/unity-ignore/blob/main/.gitignore
/Assets/Resources/Fonts/HONORSansCN-Regular SDF.*
/Assets/Resources/Fonts/simhei SDF.*
/Assets/Resources/Fonts/SIMLI SDF.*
/Assets/Exports
/Assets/Logs
/Assets/StreamingAssets/PatientInfo
/Assets/Resources/TextMesh Pro
/Assets/Resources/Models/Mat/BodyAndOrgans
/Packages/packages-lock.json
/Packages/manifest.json
# --- Unity Generated Folders ---
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Ll]og/
/[Uu]ser[Ss]ettings/
/[Mm]emoryCaptures/ # Can be large and contain sensitive data
/[Rr]ecordings/ # Typically video/audio recordings for debugging
/Burst/ # Burst compiler cache
/.unitycache/ # Unity Hub's cache
/.utmp/ # Unity test runner temp files
/[Pp]ackages/
# --- Crash Logs & Dumps ---
sysinfo.txt
*.dmp
*.stacktrace
# --- Build Artifacts ---
*.apk
*.aab
*.unitypackage
*.unitypackage.meta
*.app
crashlytics-build.properties
# --- Packed Addressables ---
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# --- StreamingAssets (temporary generated addressable data) ---
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*
# --- Autogenerated IDE & Unity Files ---
.vs/
.gradle/
.idea/
.vscode/
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
*.vsconfig
*.sln.iml
*.UpgradeLoh.htm
# --- Optional: Unity-generated .meta files for debug symbols (keep ignored unless needed) ---
# *.pidb.meta
# *.pdb.meta
# *.mdb.meta
# --- Plugin & Tool-Specific Caches ---
/[Aa]ssets/Plugins/Editor/JetBrains*
/[Aa]ssets/TextMesh*Pro/ # Ignore only if you reimport it every time
# Uncomment to ignore Asset Store Tools plugin
# /[Aa]ssets/AssetStoreTools*
# --- Merge Tool Artifacts ---
*.merge
*.orig
# --- OS-specific Files ---
*.DS_Store
*.pfx # Certificates/private keys sensitive!
# --- Do NOT ignore essential Unity files ---
!/[Aa]ssets/**/*.meta
![Aa]ssets/**/*.meta
# --- Do NOT ignore plugin folders ---
!/[Aa]ssets/[Pp]lugins/**
!/[Aa]ssets/[Ii]nternal/[Pp]lugins/**
!/[Aa]ssets/[Ee]xternal/[Pp]lugins/**
![Aa]ssets/[Pp]lugins/**
![Aa]ssets/[Ii]nternal/[Pp]lugins/**
![Aa]ssets/[Ee]xternal/[Pp]lugins/**
*.pdb.meta
*.mdb.meta
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.unitypackage.meta
*.app
# Crashlytics
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/*
# Plugins and Tools
/[Aa]ssets/Plugins/Editor/JetBrains*
[Aa]ssets/Plugins/Editor/JetBrains*
# Uncomment below to ignore Asset Store Tools
# /[Aa]ssets/AssetStoreTools*
# TextMesh Pro
/[Aa]ssets/TextMesh*Pro/
[Aa]ssets/TextMesh*Pro/
# Platform-specific
*.pfx
*.DS_Store
# Do NOT ignore meta files
!/[Aa]ssets/**/*.meta
![Aa]ssets/**/*.meta
# Do NOT ignore plugin assets
!/[Aa]ssets/[Pp]lugins/**
!/[Aa]ssets/[Ii]nternal/[Pp]lugins/**
!/[Aa]ssets/[Ee]xternal/[Pp]lugins/**
![Aa]ssets/[Pp]lugins/**
![Aa]ssets/[Ii]nternal/[Pp]lugins/**
![Aa]ssets/[Ee]xternal/[Pp]lugins/**

1
ruiyiweiUX/Assets/.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*SDF.asset filter=lfs diff=lfs merge=lfs -text

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c47acad4caedbde4a8d8c3d5cc43a6ec
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,158 @@
| **DCS ****项目****串口通信协议说明书** | |
| --- | --- |
| **版本** | **日期** | **负责人** | **主要内容** |
| --- | --- | --- | --- |
| Version v1.0.0v1.0.0 | 2025-10-17 | 开发部/覃陆孙 | 通信协议与示例帧 |
| **1. ****通信参数** | |
| --- | --- |
| **项目** | **参数** |
| --- | --- |
| 通信方式 | UARTRS232/TTL 兼容) |
| 波特率 | 115200 bps |
| 数据位 | 8 |
| 停止位 | 1 |
| 校验位 | None |
| 流控 | None |
| 通信方向 | 双向(嵌入式主控 ↔ 安卓上位机) |
| 字节序 | Little Endian |
| **2. ****通信帧格式** | |
| --- | --- |
| **字段** | **长度****(Byte)** | **说明** |
| --- | --- | --- |
| 帧头 | 2 | 固定: 0xAA 0x55 |
| 命令字 | 1 | 指令类型(握手/心跳/上报/报警等) |
| 数据长度 | 1 | 数据区字节数 |
| 数据区 | N | 实际数据内容 |
| 校验 | 1 | 从“命令字”到“数据区最后字节”的异或校验 |
| 帧尾 | 2 | 固定: 0x0D 0x0A |
| **3. ****命令字定义** | |
| --- | --- |
| **命令字** | **方向** | **含义** |
| --- | --- | --- |
| 0x01 | 下→上 | 握手应答 + 时间同步 |
| 0x02 | 上→下 | 握手请求 |
| 0x03 | 上→下 | 心跳上报(含状态) |
| 0x04 | 下→上 | 心跳应答 |
| 0x05 | 下→上 | 报警控制命令(开启/关闭/等级) |
| 0x06 | 上→下 | 数据上报BFI、电量、温度等 |
| 0x07 | 下→上 | 参数查询或设置命令 |
| 0x08 | 上→下 | 告警状态反馈 |
| 0x09 | 下→上 | 时间同步命令(可选) |
| **4. ****协议说明** **4.1 ****握手流程(上电后)** | |
| --- | --- |
**嵌入式上电后主动发送握手请求:**
| **字段** | **示例值** | **说明** |
| --- | --- | --- |
| 帧头 | AA 55 | 固定 |
| 命令字 | 0x02 | 握手请求 |
| 数据长度 | 1 | 固件版本号长度 |
| 数据 | 0x01 | 固件版本 V1 |
| 校验 | XOR | 异或和 |
| 帧尾 | 0D 0A | 固定 |
上位机收到后返回时间同步帧:
AA 55 01 05 YY MM DD HH mm ss CS 0D 0A
| **4.2 ****心跳与状态上报(周期**** 1s****** | |
| --- | --- |
命令字0x03
| **字段** | **长度** | **说明** |
| --- | --- | --- |
| BFI 血流值 | 4 | float, 嵌入式算法计算结果 |
| 电池电量 | 1 | 百分比 0100% |
| 电池电压 | 2 | 单位 mV |
| 内部温度 | 2 | 单位 0.1°C |
| 激光器状态 | 1 | 0=异常1=工作,2=停止 |
| 电源类型 | 1 | 0=AC,1=BAT |
| 保留扩展 | 4 | 预留字段 |
| 校验 | 1 | 异或校验 |
上位机应答帧:
AA 55 04 01 00 CS 0D 0A
| **4.3 ****报警控制命令(上位机**** → ****嵌入式)** | |
| --- | --- |
命令字:**0x05**
| **字段** | **长度** | **说明** |
| --- | --- | --- |
| 报警代码 | 1 | 见下方报警表 |
| 报警级别 | 1 | 0=低,1=中,2=高 |
| 报警状态 | 1 | 0=清除,1=触发 |
| 校验 | 1 | 异或校验 |
**示例:**
AA 55 05 03 31 02 01 CS 0D 0A
→ 表示触发高优先报警代码31电池电量<5%
嵌入式根据报警等级执行:
| **优先级** | **指示灯** |
| --- | --- |
| 高 | 详细见《报警声光表达》 |
| 中 | - |
| 低 | - |
| **4.4 ****数据上报(嵌入式**** → ****上位机)** | |
| --- | --- |
命令字:**0x06**
| **字段** | **长度** | **说明** |
| --- | --- | --- |
| BFI 数据 | 4 | Float 32 位 |
| 电池电量 | 1 | 百分比 |
| 电压 | 2 | mV |
| 内部温度 | 2 | 0.1°C |
| 激光器状态 | 1 | 0=关,1=开,2=异常 |
| 电源状态 | 1 | 0=AC,1=BAT |
| 扩展保留 | 4 | 预留字段 |
| 校验 | 1 | 异或校验 |
**示例:**
AA 55 06 0B 42 48 00 00 64 0F 27 01 2C 00 01 00 00 00 CS 0D 0A
→ BFI=50.0,电量=100%,电压=9999mV温度=30.0°C激光状态工作中
| **5. ****报警代码表** | |
| --- | --- |
| **报警代码** | **优先级** | **报警原因** | **报文方向** |
| --- | --- | --- | --- |
| 11 | 低 | 电池电量低(<40% | 下位上位 |
| 21 | 中 | 电池电量低(<20% | 下位上位 |
| 31 | 高 | 电池电量空(<5% | 下位上位 |
| 32 | 高 | BFI 数值异常 | 上位→下位 |
| 22 | 中 | 激光器温度异常 | 上位→下位 |
| 33 | 高 | 激光器工作异常 | 上位→下位 |
| 34 | 高 | 通信异常 | 上位→下位 |
| 35 | 高 | 电池故障 | 上位→下位 |
| 12 | 低 | 交流电未连接 | 上位→下位 |
| **6. ****典型通信时序流程** | |
| --- | --- |
| MCU Android |
| --- |
| 握手请求 (0x02) ->|
|<- 握手应答 + 时间同步 (0x01) |
| 周期心跳上报 (0x03) ->|
|<- 心跳应答 (0x04) |
|<-触发报警 33高优先 |
| 确认并执行灯光报警 ->|
| 周期数据上报 (0x06) ->|
| |

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 46354ea8b1983694fa9e5e8039cb2857
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 681e13528bd941a489d144b9035e54d4
folderAsset: yes
timeCreated: 1626155774
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 74619302947489a4299e02c7b6fdaf8a
folderAsset: yes
timeCreated: 1565057152
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,143 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using GeneralTools;
public class AutoBuild : MonoBehaviour
{
/// <summary>
///
/// </summary>
public static void Build(bool development)
{
BuildTargetGroup group = EditorUserBuildSettings.selectedBuildTargetGroup;
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
RuntimePlatform tr = Application.platform;
if (group == BuildTargetGroup.Standalone && target == BuildTarget.StandaloneWindows)
{
//Windows
Debug.Log("Windows打包_x86");
BuildEXE(development);
}
else if (group == BuildTargetGroup.Standalone && target == BuildTarget.StandaloneWindows64)
{
//Windows
Debug.Log("Windows打包_x86x64");
BuildEXE64(development);
}
else if (group == BuildTargetGroup.Android && target == BuildTarget.Android)
{
//Android
Debug.Log("Android打包");
BuildAPK(development);
}
else if (group == BuildTargetGroup.iOS && target == BuildTarget.iOS)
{
//iOS
Debug.Log("iOS打包");
BuildIPA(development);
}
else if (group == BuildTargetGroup.Standalone && target == BuildTarget.StandaloneOSX)
{
//MacApp
Debug.Log("MacApp打包");
BuildAPP(development);
}
}
/// <summary>
/// Windows32位
/// </summary>
private static void BuildEXE(bool development)
{
//EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
//AssetDatabase.Refresh();
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.locationPathName = "Build/Windows/" + Application.productName + "/" + Application.productName + ".exe";
buildPlayerOptions.scenes = EditorBuildSettings.scenes.Where(s => s.enabled && !string.IsNullOrEmpty(s.path)).Select(s => s.path).ToArray();
buildPlayerOptions.targetGroup = BuildTargetGroup.Standalone;
buildPlayerOptions.target = BuildTarget.StandaloneWindows;
buildPlayerOptions.options = (BuildOptions)(8 + (development ? 1 : 0));
OnPreprocessBuildDoing.OverridesBuildPlayer(buildPlayerOptions);
// BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildPlayerOptions);
//OpenFolder(Path.GetDirectoryName(Application.dataPath), "Build", "Windows", Application.productName);
}
/// <summary>
/// Windows64位
/// </summary>
private static void BuildEXE64(bool development)
{
//EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
//AssetDatabase.Refresh();
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.locationPathName = "Build/Windows/" + Application.productName + "/" + Application.productName + ".exe";
buildPlayerOptions.scenes = EditorBuildSettings.scenes.Where(s => s.enabled && !string.IsNullOrEmpty(s.path)).Select(s => s.path).ToArray();
buildPlayerOptions.targetGroup = BuildTargetGroup.Standalone;
buildPlayerOptions.target = BuildTarget.StandaloneWindows64;
buildPlayerOptions.options = (BuildOptions)(8 + (development ? 1 : 0));
OnPreprocessBuildDoing.OverridesBuildPlayer(buildPlayerOptions);
// BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildPlayerOptions);
//OpenFolder(Path.GetDirectoryName(Application.dataPath), "Build", "Windows", Application.productName);
}
/// <summary>
/// Android
/// </summary>
private static void BuildAPK(bool development)
{
//EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Android, BuildTarget.Android);
//AssetDatabase.Refresh();
EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.locationPathName = "Build/Android/" + Application.productName + "/" + Application.productName + ".apk";
buildPlayerOptions.scenes = EditorBuildSettings.scenes.Where(s => s.enabled && !string.IsNullOrEmpty(s.path)).Select(s => s.path).ToArray();
buildPlayerOptions.targetGroup = BuildTargetGroup.Android;
buildPlayerOptions.target = BuildTarget.Android;
buildPlayerOptions.options = (BuildOptions)(8 + (development ? 1 : 0));
OnPreprocessBuildDoing.OverridesBuildPlayer(buildPlayerOptions);
// BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildPlayerOptions);
// OpenFolder(Path.GetDirectoryName(Application.dataPath), "Build", "Android", Application.productName);
}
/// <summary>
/// IOS
/// </summary>
private static void BuildIPA(bool development)
{
//EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.iOS, BuildTarget.iOS);
//AssetDatabase.Refresh();
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.locationPathName = "Build/iOS/" + Application.productName;
buildPlayerOptions.scenes = EditorBuildSettings.scenes.Where(s => s.enabled && !string.IsNullOrEmpty(s.path)).Select(s => s.path).ToArray();
buildPlayerOptions.targetGroup = BuildTargetGroup.iOS;
buildPlayerOptions.target = BuildTarget.iOS;
buildPlayerOptions.options = (BuildOptions)(8 + (development ? 1 : 0));
OnPreprocessBuildDoing.OverridesBuildPlayer(buildPlayerOptions);
// BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildPlayerOptions);
// OpenFolder(Path.GetDirectoryName(Application.dataPath), "Build", "iOS", Application.productName);
}
/// <summary>
/// Mac
/// </summary>
private static void BuildAPP(bool development)
{
//EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneOSX);
//AssetDatabase.Refresh();
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.locationPathName = "Build/MacOS/" + Application.productName + "/" + Application.productName;
buildPlayerOptions.scenes = EditorBuildSettings.scenes.Where(s => s.enabled && !string.IsNullOrEmpty(s.path)).Select(s => s.path).ToArray();
buildPlayerOptions.targetGroup = BuildTargetGroup.Standalone;
buildPlayerOptions.target = BuildTarget.StandaloneOSX;
buildPlayerOptions.options = (BuildOptions)(8 + (development ? 1 : 0));
OnPreprocessBuildDoing.OverridesBuildPlayer(buildPlayerOptions);
// BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildPlayerOptions);
// OpenFolder(Path.GetDirectoryName(Application.dataPath), "Build", "MacOS", Application.productName);
}
private static void OpenFolder(params string[] path)
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
System.Diagnostics.Process.Start("explorer.exe", Path.Combine(path));
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: de3d27fdc42bbf04da0e31dc1f0d02e9
timeCreated: 1636104095
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
namespace GeneralTools
{
public class Menu
{
[MenuItem("GeneralTools/项目设置", false, 3)]
static void ProductSetttings()
{
ScriptableWizard.DisplayWizard<ProductWindow>("产品设置", "确认并关闭", "设置默认");
}
[MenuItem("GeneralTools/证书设置/设置证书配置(生成)", false, 1)]
public static CertificateSetting SetCertificate()
{
string path = "Assets/GeneralTools/Resources/Setting/CertificateSetting.asset";
string dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
if (!File.Exists(path))
{
CertificateSetting asset = ScriptableObject.CreateInstance<CertificateSetting>();
AssetDatabase.CreateAsset(asset, path);
AssetDatabase.SaveAssets();
}
CertificateSetting scriptObject = AssetDatabase.LoadAssetAtPath<CertificateSetting>(path);
EditorUtility.FocusProjectWindow();
Selection.activeObject = scriptObject;
return scriptObject;
}
[MenuItem("GeneralTools/证书设置/生成新证书", false, 2)]
static void CreateCertificate()
{
//读取配置
CertificateSetting setting = CertificateSetting.GetCertificateSetting();
LockDll.CertificateVerification.CreateForeverCertificate(DevicePath.CertificateProgramPath, setting.useProdctName);
}
[MenuItem("GeneralTools/证书设置/删除当前证书", false, 3)]
static void DeleteCertificate()
{
if (File.Exists(DevicePath.CertificateProgramPath))
File.Delete(DevicePath.CertificateProgramPath);
}
[MenuItem("GeneralTools/一键打包/Development")]
static void Build_Development()
{
AutoBuild.Build(true);
}
[MenuItem("GeneralTools/一键打包/普通模式")]
static void Build()
{
AutoBuild.Build(false);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d6f302892cfa3824982d9e8fe93ccd51
timeCreated: 1565057152
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,78 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace GeneralTools
{
public class OnPreprocessBuildDoing : IPreprocessBuild, IPostprocessBuild
{
public int callbackOrder { get { return 0; } }
/// <summary>
/// 打包前
/// </summary>
/// <param name="target"></param>
/// <param name="path"></param>
public void OnPreprocessBuild(BuildTarget target, string path)
{
CustomPlayerSettings();
CheckCertificatePath();
}
/// <summary>
/// 打包后
/// </summary>
/// <param name="target"></param>
/// <param name="path"></param>
public void OnPostprocessBuild(BuildTarget target, string path)
{
}
/// <summary>
/// //代码编译完成时调用
/// </summary>
[UnityEditor.Callbacks.DidReloadScripts]
static void OnScriptsEditOver()
{
//注册打包发布的事件unity在打包发布的时候会判断buildPlayerHandler 是不是为null为空就执行默认打包方法不为空就执行注册的事件
BuildPlayerWindow.RegisterBuildPlayerHandler(OverridesBuildPlayer);
}
public static void OverridesBuildPlayer(BuildPlayerOptions BPOption)
{
//添加自己的逻辑
CertificateSetting setting = Resources.Load<CertificateSetting>("Setting/CertificateSetting");
if (setting == null)
{
Debug.LogError("未找到CertificateSetting,请生成");
if (EditorUtility.DisplayDialog("提示", "未找到CertificateSetting,请生成", "生成"))
{
Menu.SetCertificate();
}
}
else
{
Debug.Log("开始打包,当前项目名称:" + (string.IsNullOrWhiteSpace(setting.productID) ? Application.productName : setting.productID));
BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(BPOption);//调用unity默认的打包方法。取消打包不用写其他代码
}
}
private static void CustomPlayerSettings()
{
PlayerSettings.runInBackground = true;
PlayerSettings.displayResolutionDialog = ResolutionDialogSetting.Disabled;
PlayerSettings.usePlayerLog = false;
PlayerSettings.forceSingleInstance = true;
PlayerSettings.SplashScreen.show = false;
}
private static void CheckCertificatePath()
{
string path = DevicePath.CertificateProgramPath;
if (!File.Exists(path))
{
Debug.Log("未找到证书文件,生成默认证书");
CertificateManager.CreateOneCertificate();
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 74cec066ca62aa44393124b630744f01
timeCreated: 1625131554
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,40 @@
using UnityEngine;
using UnityEditor;
namespace GeneralTools
{
public class ProductWindow : ScriptableWizard
{
public string companyName;
public string productName;
private void OnEnable()
{
productName = PlayerSettings.productName;
companyName = PlayerSettings.companyName;
}
private void OnWizardCreate()
{
SetProduct();
}
private void OnWizardOtherButton()
{
companyName = "FengYuZhu";
productName = Application.productName;
SetProduct();
}
private void SetProduct()
{
PlayerSettings.companyName = companyName;
PlayerSettings.productName = productName;
string identifier = string.Format("com.{0}.{1}", companyName, productName);
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Standalone, identifier);
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, identifier);
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.iOS, identifier);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1762b31139588254eb938238e4e996c3
timeCreated: 1565057152
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,405 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Xml;
using UnityEditor;
using UnityEngine.Networking;
using System.Text;
using System;
using System.Media;
namespace GeneralTools
{
public class ResourcesDwonload : EditorWindow
{
private static ResourcesDwonload window;
private static string downloadRootUrl;
private static string downloadGetUrl;
private static string webVideoUrl;
private static string webAudioUrl;
private static string dataPath;
private List<DownloadXML> xmlList;
private List<string> titleList;
private int nowIndex = 0;
private string tempSaveDir;
private string saveFilePath;
private DateTime downloadBeginTime;
private bool httpGetFinished = false;
DownloadXML nowChooseXml;
bool autoopen = false;
bool autoimport = false;
string importdir = "";
string folderMode = "";
bool allowDownload = true;
Vector2 infopos = Vector2.zero;
Vector2 btnpos = Vector2.zero;
bool isShowBar = false;
float downPragrass = 0;
Thread downLoadThread = null;
Stream st;
Stream so;
[MenuItem("GeneralTools/资源下载/外网环境", false, 1)]
static void OpenWindow()
{
downloadRootUrl = "http://UnityResources.fyzdev.com";
downloadGetUrl = "http://UnityResources.fyzdev.com/download.php";
webVideoUrl = "http://UnityResources.fyzdev.com/video.php?url=";
webAudioUrl = "http://UnityResources.fyzdev.com/audio.php?url=";
//获取窗口并打开
window = GetWindow<ResourcesDwonload>("下载页Beta");
window.Show();//显示窗口
}
[MenuItem("GeneralTools/资源下载/风语筑局域网", false, 2)]
static void OpenWindowLocal()
{
downloadRootUrl = "http://192.168.21.136:1212";
downloadGetUrl = "http://192.168.21.136:1212/download.php";
webVideoUrl = "http://192.168.21.136:1212/video.php?url=";
webAudioUrl = "http://192.168.21.136:1212/audio.php?url=";
//获取窗口并打开
window = GetWindow<ResourcesDwonload>("下载页Beta");
window.Show();//显示窗口
}
private void Awake()
{
dataPath = Application.dataPath + "/";
httpGetFinished = false;
string xmlStr = HttpGet(downloadGetUrl, "");
xmlList = HandleXML(xmlStr);
titleList = xmlList.Select(m => m.rootName).ToList();
ChangeIndex(0);
httpGetFinished = true;
}
void ChangeIndex(int index)
{
nowIndex = index;
nowChooseXml = xmlList[nowIndex];
autoopen = nowChooseXml.autoOpen;
autoimport = nowChooseXml.autoImport;
importdir = nowChooseXml.importPath;
folderMode = nowChooseXml.folderMode;
allowDownload = nowChooseXml.allowDownload;
}
private void OnGUI()
{
if (!httpGetFinished)
return;
///自动生成
///
///生成最顶端按钮
///
btnpos = EditorGUILayout.BeginScrollView(btnpos, GUILayout.Height(40));
EditorGUILayout.BeginHorizontal();
for (int i = 0; i < titleList.Count; i++)
{
int index = i;
if (GUILayout.Button(titleList[index], GUILayout.Width(100)))
{
ChangeIndex(index);
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndScrollView();
//下方的东西会刷新
//临时路径
tempSaveDir = GetTempSavePath(nowChooseXml.rootName);
EditorGUILayout.BeginHorizontal();
GUILayout.Label("下载临时文件保存路径(电脑的绝对路径,无法更改)");
autoopen = EditorGUILayout.Toggle("下载完自动打开", autoopen);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.TextField(tempSaveDir);
//自动导入
autoimport = EditorGUILayout.BeginToggleGroup("下载完自动导入", autoimport);
GUILayout.Label("导入工程路径(Asset/下的相对路径)");
importdir = EditorGUILayout.TextField(importdir);
EditorGUILayout.EndToggleGroup();
EditorGUILayout.Space();
//子文件
infopos = EditorGUILayout.BeginScrollView(infopos);
for (int i = 0; i < nowChooseXml.itemList.Count; i++)
{
EditorGUILayout.Space();
DownloadXMLItem tempItep = nowChooseXml.itemList[i];
EditorGUILayout.BeginHorizontal();
GUILayout.Label((i + 1).ToString(), GUILayout.Width(20));
GUILayout.TextField(tempItep.fileName, GUILayout.Width(300));
GUILayout.TextArea(tempItep.info);
GUILayout.TextField(tempItep.size, GUILayout.Width(100));
if (allowDownload && GUILayout.Button("下载", GUILayout.Width(100)))
{
object[] objee = new object[6] { downloadRootUrl + "/" + tempItep.url, Path.Combine(tempSaveDir, tempItep.fileName), Path.Combine(importdir, tempItep.fileName), autoopen, autoimport, tempItep.size };
GoDownload(objee);
window.RemoveNotification();
window.ShowNotification(new GUIContent("开始下载" + tempItep.fileName + "\r\n" + "文件大小:" + tempItep.size));
}
if (folderMode == "Audio")
{
if (GUILayout.Button("试听(网页)", GUILayout.Width(100)))
{
System.Diagnostics.Process.Start(webAudioUrl + "/" + tempItep.url);
}
}
else if (folderMode == "Photo")
{
if (GUILayout.Button("浏览(网页)", GUILayout.Width(100)))
{
System.Diagnostics.Process.Start(downloadRootUrl + "/" + tempItep.url);
}
}
else if (folderMode == "Video")
{
if (GUILayout.Button("观看(网页)", GUILayout.Width(100)))
{
System.Diagnostics.Process.Start(webVideoUrl + "/" + tempItep.url);
}
}
else if (folderMode == "General")
{
if (GUILayout.Button("下载(网页)", GUILayout.Width(100)))
{
System.Diagnostics.Process.Start(downloadRootUrl + "/" + tempItep.url);
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
private void Update()
{
if (!isShowBar)
{
EditorUtility.ClearProgressBar();
return;
}
bool isCancel = EditorUtility.DisplayCancelableProgressBar("下载中...", (downPragrass * 100).ToString("F2") + "%", downPragrass);
if (isCancel)
{
window.RemoveNotification();
window.ShowNotification(new GUIContent("取消下载:" + Path.GetFileName(saveFilePath)));
CloseAll();
isShowBar = false;
string ts = (DateTime.Now - downloadBeginTime).TotalSeconds.ToString("F2");
Debug.Log("下载取消用时:" + ts + "秒,");
Debug.Log("---------------------------------------------------------");
}
if (downPragrass >= 1)
{
window.RemoveNotification();
window.ShowNotification(new GUIContent("下载成功,详情在Console窗口"));
isShowBar = false;
}
}
void CloseAll()
{
if (downLoadThread != null)
{
downLoadThread.Interrupt();
downLoadThread.Abort();
downLoadThread = null;
}
if (so != null)
{
so.Close();
so.Dispose();
so = null;
}
if (st != null)
{
st.Close();
st.Dispose();
st = null;
}
if (!string.IsNullOrEmpty(saveFilePath))
{
File.Delete(saveFilePath);
saveFilePath = "";
}
}
void GoDownload(object path)
{
downloadBeginTime = DateTime.Now;
downPragrass = 0;
isShowBar = true;
CloseAll();
downLoadThread = new Thread(Download);
downLoadThread.IsBackground = true;
downLoadThread.Start(path);
}
private void Download(object obj)
{
string URL = ((object[])obj)[0].ToString();
saveFilePath = ((object[])obj)[1].ToString();
string fileCopyToPath = Path.Combine(dataPath, ((object[])obj)[2].ToString());
bool _autoopen = (bool)((object[])obj)[3];
bool _autoimport = (bool)((object[])obj)[4];
string _fileSize = ((object[])obj)[5].ToString();
string dir = Path.GetDirectoryName(saveFilePath);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
downPragrass = 0;
isShowBar = true;
HttpWebRequest Myrq = (HttpWebRequest)WebRequest.Create(URL);
HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse();
long fileLength = myrp.ContentLength;
Debug.Log("开始下载");
st = myrp.GetResponseStream();
so = new FileStream(saveFilePath, FileMode.Create);
long totalDownloadedByte = 0;
byte[] by = new byte[1024];
int osize = st.Read(by, 0, by.Length);
while (osize > 0)
{
totalDownloadedByte = osize + totalDownloadedByte;
so.Write(by, 0, osize);
osize = st.Read(by, 0, by.Length);
downPragrass = totalDownloadedByte / (float)fileLength;
}
so.Close();
so.Dispose();
st.Close();
st.Dispose();
downPragrass = 1;
if (_autoopen)
{
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
info.FileName = saveFilePath;
info.Arguments = "";
try
{
System.Diagnostics.Process pro = System.Diagnostics.Process.Start(info);
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
Debug.Log("临时文件保存成功,路径:" + saveFilePath);
if (_autoimport)
{
try
{
string fileCopyDir = Path.GetDirectoryName(fileCopyToPath);
if (!Directory.Exists(fileCopyDir))
Directory.CreateDirectory(fileCopyDir);
File.Copy(saveFilePath, fileCopyToPath, true);
Debug.Log("导入工程,路径:" + fileCopyToPath);
}
catch (Exception)
{
}
}
string ts = (DateTime.Now - downloadBeginTime).TotalSeconds.ToString("F2");
Debug.Log("下载结束,文件大小:" + _fileSize + ",用时:" + ts + "秒,");
Debug.Log("---------------------------------------------------------");
saveFilePath = "";
}
public string HttpGet(string Url, string postDataStr)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
private List<DownloadXML> HandleXML(string xml)
{
List<DownloadXML> xmlList = new List<DownloadXML>();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNode resources = xmlDoc.SelectSingleNode("UnityResources");
foreach (XmlElement res in resources)
{
DownloadXML newXml = new DownloadXML();
newXml.rootName = res.GetAttribute("floder_name");
newXml.autoOpen = (res.GetAttribute("auto_open") == "false") ? false : true;
newXml.autoImport = (res.GetAttribute("auto_import") == "false") ? false : true;
newXml.importPath = res.GetAttribute("import_path");
newXml.folderMode = res.GetAttribute("folder_mode");
newXml.allowDownload = (res.GetAttribute("allow_download") == "false") ? false : true;
foreach (XmlElement item in res.ChildNodes)
{
DownloadXMLItem newItem = new DownloadXMLItem();
newItem.fileName = item.GetAttribute("filename");
newItem.url = item.GetAttribute("url");
string info = item.GetAttribute("info");
newItem.info = info;
long sizeL = long.Parse(item.GetAttribute("size"));
newItem.size = ConvertFileSize(sizeL);
newXml.itemList.Add(newItem);
}
xmlList.Add(newXml);
}
return xmlList;
}
public string GetTempSavePath(string floder)
{
return Application.temporaryCachePath + "/PackageCache/" + floder + "/";
}
public static string ConvertFileSize(long size)
{
string result = "0KB";
int filelength = size.ToString().Length;
if (filelength < 4)
result = size + "byte";
else if (filelength < 7)
result = Math.Round(Convert.ToDouble(size / 1024d), 2) + "KB";
else if (filelength < 10)
result = Math.Round(Convert.ToDouble(size / 1024d / 1024), 2) + "MB";
else if (filelength < 13)
result = Math.Round(Convert.ToDouble(size / 1024d / 1024 / 1024), 2) + "GB";
else
result = Math.Round(Convert.ToDouble(size / 1024d / 1024 / 1024 / 1024), 2) + "TB";
return result;
}
}
public class DownloadXML
{
public string rootName;
public bool autoOpen;
public bool autoImport;
public string importPath;
public string folderMode;
public bool allowDownload;
public List<DownloadXMLItem> itemList;
public DownloadXML()
{
itemList = new List<DownloadXMLItem>();
}
}
public class DownloadXMLItem
{
public string fileName;
public string url;
public string info;
public string size;
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 7e2e91de19625f34b9a8aa9dcc97b87c
timeCreated: 1629103560
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f69de3a2c41dfcb4a9fd595656e490ed
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
[Serializable]
public class FolderItem
{
public string folderName;
public int fileCount;
}
[Serializable]
public class Folders
{
public List<FolderItem> folders;
}
public static class FolderChecker
{
private static Folders jsonFolders;
private static void ReadJson()
{
string jsonPath = Path.Combine(Application.streamingAssetsPath, "folderInfo.json");
string jsonContent = File.ReadAllText(jsonPath);
jsonFolders = JsonUtility.FromJson<Folders>(jsonContent);
Debug.Log($"待检测文件夹数目:{jsonFolders.folders.Count}");
}
public static bool CheckFolders()
{
if (Application.isEditor) return true;
// 读取Json
ReadJson();
// 获取根目录
string path = Directory.GetParent(Application.streamingAssetsPath).ToString();
path = Directory.GetParent(path).ToString();
// 检查文件夹是否完整
if (Directory.Exists(path))
{
List<string> folderList = Directory.GetDirectories(path).ToList();
List<string> floderNameList = new List<string>();
for (int i = 0; i < folderList.Count; i++)
{
string[] temp = folderList[i].Split('\\');
floderNameList.Add(temp[temp.Length - 1]);
}
for (int i = 0; i < jsonFolders.folders.Count; i++)
{
if (!floderNameList.Contains(jsonFolders.folders[i].folderName))
{
Debug.LogError($"不存在文件夹:{jsonFolders.folders[i].folderName}");
return false;
}
}
return true;
}
else
{
Debug.LogError($"路径不存在:{path}");
return false;
}
}
public static bool CheckDllFileCount()
{
if (Application.isEditor) return true;
// 读取Json
ReadJson();
// 获取根目录
string path = Directory.GetParent(Application.streamingAssetsPath).ToString();
path = Directory.GetParent(path).ToString();
// 检查文件夹是否完整
if (Directory.Exists(path))
{
List<string> folderList = Directory.GetDirectories(path).ToList();
List<string> floderNameList = new List<string>();
for(int i = 0; i < folderList.Count; i++)
{
string[] temp = folderList[i].Split('\\');
floderNameList.Add(temp[temp.Length - 1]);
}
// 检查dll数量
for (int i = 0; i < jsonFolders.folders.Count; i++)
{
string folderName = jsonFolders.folders[i].folderName;
string folderPath = $"{path}\\{folderName}";
if (!floderNameList.Contains(folderName))
{
Debug.LogError($"不存在文件夹:{folderName}");
return false;
}
else
{
int fileCount = Directory.GetFiles(folderPath, "*.dll", SearchOption.AllDirectories).Length;
if(fileCount != jsonFolders.folders[i].fileCount)
{
Debug.LogError($"{folderPath} dll文件缺失请检查");
return false;
}
}
}
return true;
}
else
{
Debug.LogError($"路径不存在:{path}");
return false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9b30960e4f6b9048b576c8970d8d60d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b7fe07be0bee19944822bbe3aa9a21a1
folderAsset: yes
timeCreated: 1569293741
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -0,0 +1,78 @@
fileFormatVersion: 2
guid: 7bbd0d552967c8a4ab207558e5051413
timeCreated: 1569464332
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,78 @@
fileFormatVersion: 2
guid: c98f0ae4a8bf8c6419027088fe9434ba
timeCreated: 1569293761
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d3ce456e3ae674c4cab69ed8f8067a21
folderAsset: yes
timeCreated: 1567504239
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 9198c70a01b168f439b2feff871316f5
timeCreated: 1628659597
licenseType: Free
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 480b8881de2de8f4fab6035d614173c3
timeCreated: 1628659597
licenseType: Free
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 8c202f0d82fdb9b41a47e156a831b978
timeCreated: 1628585060
licenseType: Free
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: e6aa0de797b42144bbbac85deedf4242
timeCreated: 1567504275
licenseType: Pro
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5f870822b5192724aa11b082df1ae3ec
folderAsset: yes
timeCreated: 1566140136
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c417e776b1d71fb4886257ced4f56b8c
timeCreated: 1628238124
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 79cf44e22c4c6b04eb8d48fd127c0e4c
timeCreated: 1628237523
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3492b63f9aa10ac45b1e549f7b3627cd
folderAsset: yes
timeCreated: 1566015165
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a8f7215f459f4564c9aaec9ddba3c1ca
folderAsset: yes
timeCreated: 1628564264
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: cbdadb604224e5e4290b66d51fb65c9a, type: 3}
m_Name: CertificateSetting
m_EditorClassIdentifier:
isCheckCertificate: 0
lockType: 1
productID:
useProdctName:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e163cbb88a49bba4cbcf527844d5914f
timeCreated: 1628564264
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 483682ad50f1d744181257257b48844e
folderAsset: yes
timeCreated: 1598176428
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: ffe2644ce1807714da6cbcdf54a5c6b2
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b0d28dc9d0b8d804da54488e0a4d3386
folderAsset: yes
timeCreated: 1564815011
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3b641b1044c4a684ab9b30ef5ecd4757
folderAsset: yes
timeCreated: 1564815028
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,227 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class AudioManager : SingletonBaseAttribute<AudioManager>
{
private AudioSource bgmSource;
protected List<AudioSource> playingAudioList = new List<AudioSource>();
private Dictionary<string, AudioClip> clipDict = new Dictionary<string, AudioClip>();
private string thirdResPath;
public override void IStart()
{
thirdResPath = DevicePath.StreamingAssetsPath + "/Audio/";
Init();
KeyDownManager.Instance.AddKeyDownAction(KeyCode.F4, () => { MuteBGM(); }, "静音/恢复BGM", false, 0);
}
public override void IOnApplicationQuit()
{
bgmSource.Stop();
for (int i = 0; i < playingAudioList.Count; i++)
{
playingAudioList[i].Stop();
}
playingAudioList.Clear();
}
void Init()
{
//创建BGM组件
if (gameObject.GetComponent<AudioSource>() == null)
{
bgmSource = gameObject.AddComponent<AudioSource>();
bgmSource.loop = true;
}
else
{
bgmSource = gameObject.GetComponent<AudioSource>();
}
//读取音效 存入词典
AudioClip[] clip = Resources.LoadAll<AudioClip>("Audio");
for (int i = 0; i < clip.Length; i++)
{
AddClipToDict(clip[i], clip[i].name);
}
//加载外部音频
LoadThirdRes();
}
void AddClipToDict(AudioClip clip, string url)
{
string clipName = Path.GetFileNameWithoutExtension(Path.GetFullPath(url).Replace(Path.GetFullPath(thirdResPath), ""));
if (!clipDict.ContainsKey(clipName))
{
clipDict[clipName] = clip;
}
else
{
Debug.LogError("音频文件名:" + clipName + " 文件名重复");
}
}
public void PlayBGM(AudioClip clip, float volume = 1.0f)
{
if (clip == null)
return;
if (!ConfigHelper.isAllowPlayBGM)
{
Debug.LogError("BGM设置为不播放");
return;
}
bgmSource.Stop();
bgmSource.clip = clip;
bgmSource.loop = true;
SetBGMVolume(volume);
bgmSource.Play();
}
public void PlayBGM(string clipName, float volume = 1.0f)
{
if (!clipDict.ContainsKey(clipName))
{
Debug.LogError("未找到音乐名:" + clipName);
return;
}
PlayBGM(clipDict[clipName], volume);
}
public void StopBGM()
{
bgmSource.Stop();
}
public void SetBGMVolume(float volume)
{
bgmSource.volume = volume;
}
public void MuteBGM()
{
bgmSource.mute = !bgmSource.mute;
}
public void MuteBGM(bool isMute)
{
bgmSource.mute = isMute;
}
public void PauseBgm()
{
if (bgmSource.clip == null)
return;
if (bgmSource.isPlaying)
{
bgmSource.Pause();
}
else
{
bgmSource.Play();
}
}
public void PauseBgm(bool isPause)
{
if (isPause)
{
bgmSource.Pause();
}
else
{
bgmSource.Play();
}
}
private void PlayShot(AudioClip clip, float volume = 1.0f)
{
if (playingAudioList.Count >= ConfigHelper.audioShotLimit)
{
Debug.LogError("同时播放音效数量超出上限");
return;
}
CreateAudio(clip, volume);
}
public void PlayShot(string clipName, float volume = 1.0f)
{
if (!clipDict.ContainsKey(clipName))
{
Debug.LogError("未找到音效名:" + clipName);
return;
}
PlayShot(clipDict[clipName], volume);
}
public void PlayShotOnlyOne(string clipName, float volume = 1.0f)
{
if (!playingAudioList.Exists(o => o.clip.name == clipName))
{
PlayShot(clipName, volume);
}
}
public void PlayShotDelay(string clipName, float delayTime, float volume = 1.0f)
{
StartCoroutine(UtilityTool.DelayToInvokeDo(() =>
{
PlayShot(clipName, volume);
}, delayTime));
}
private void CreateAudio(AudioClip clip, float volume)
{
GameObject gameObj = new GameObject();
gameObj.name = clip.name;
gameObj.transform.parent = transform;
AudioSource newSource = gameObj.AddComponent<AudioSource>();
newSource.clip = clip;
newSource.loop = false;
newSource.volume = volume;
newSource.Play();
playingAudioList.Add(newSource);
}
void Update()
{
if (playingAudioList.Count <= 0)
return;
for (int i = 0; i < playingAudioList.Count; i++)
{
if (!playingAudioList[i].isPlaying)
{
AudioSource temp = playingAudioList[i];
playingAudioList.RemoveAt(i);
#if UNITY_2018_1_OR_NEWER
Destroy(temp.gameObject);
#else
DestroyObject(temp.gameObject);
#endif
i--;
}
}
}
void LoadThirdRes()
{
#if !UNITY_2017_1_OR_NEWER
return;
#endif
if (!Directory.Exists(thirdResPath))
return;
//读取外部音效,默认StreamAssets/Audio
// List<string> mp3Flies = FileReader.GetPathAllFilesRoot(outDir, "*.mp3");
List<string> oggFlies = FileReader.GetPathAllFilesRoot(thirdResPath, "*.ogg");
List<string> wavFlies = FileReader.GetPathAllFilesRoot(thirdResPath, "*.wav");
//for (int i = 0; i < mp3Flies.Count; i++)
//{
// string savepath = mp3Flies[i].Replace(".mp3", ".wav");
// if (!File.Exists(savepath)) //MP3 转wav
// {
// FileStream stream = File.Open(mp3Flies[i], FileMode.Open);
// Mp3FileReader reader = new Mp3FileReader(stream);
// WaveFileWriter.CreateWaveFile(savepath, reader);
// }
//}
for (int i = 0; i < wavFlies.Count; i++)
{
WebRequestManager.Instance.GetAudioClip(wavFlies[i], AddClipToDict, AudioType.WAV);
}
for (int i = 0; i < oggFlies.Count; i++)
{
WebRequestManager.Instance.GetAudioClip(oggFlies[i], AddClipToDict, AudioType.OGGVORBIS);
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 3dd6a4c5e7e351c4a9bcd41216337fe3
timeCreated: 1611739379
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GeneralTools
{
public class BaseAttribute : MonoBehaviour
{
public virtual void IAwake()
{
}
public virtual void IStart()
{
}
public virtual void GameStart()
{
}
public virtual void IOnApplicationQuit()
{
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: fe7edbd02c761644083e905876886b91
timeCreated: 1564814475
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,35 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace GeneralTools
{
public class BroadcastDebug : SingletonBaseAttribute<BroadcastDebug>
{
SocketBase broadcastSender;
public override void IAwake()
{
base.IAwake();
if (ConfigHelper.broadcastDebug)
{
broadcastSender = SocketManager.Instance.CreateUdp(19527).SetSocketName("BroadcastDebugSocket").SetMsgEncoding(Encoding.GetEncoding("GB2312"));
Application.logMessageReceived += LogHandler;
}
}
public override void IOnApplicationQuit()
{
if (ConfigHelper.broadcastDebug)
{
Application.logMessageReceived -= LogHandler;
}
}
private void LogHandler(string condition, string stackTrace, LogType type)
{
var timeStr = DateTime.Now.ToString("HH:mm:ss.ff");
var logStr = string.Format("{0}-[{1}]{2}", timeStr, type, condition);
broadcastSender.SendMsg(logStr);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d226fcd3925c19342aba73c65c31fb0b
timeCreated: 1627892252
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 267bd4f0f978f7344b781a5f4b5abd82
folderAsset: yes
timeCreated: 1597424208
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,129 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class CertificateManager : SingletonBaseAttribute<CertificateManager>
{
private static string productName;
private SocketBase udpSender;
private string udpSenderStr;
private Coroutine TrialCor;
private static CertificateSetting setting;
public override void IAwake()
{
base.IAwake();
setting = CertificateSetting.GetCertificateSetting();
//读取配置
productName = setting.useProdctName;
LockDll.CertificateVerification.OnPrintMsg += (msg) => { Debug.Log(msg); };
if (!setting.isCheckCertificate)
{
Debug.Log("START: Frame Game Debug");
return;
}
CheckCertificate();
}
public override void IStart()
{
base.IStart();
udpSender = SocketManager.Instance.CreateUdp(39527).SetSocketName("CertificateUDPSender").AddReceiveEvent(UdpReceiveHandler);
StartCoroutine(NetWorkBroadcast());
}
public bool CheckCertificate()
{
if (TrialCor != null)
{
StopCoroutine(TrialCor);
TrialCor = null;
}
MessageBox.Instance.Hide("证书提示");
bool checkSuccess = LockDll.CertificateVerification.CheckCertificate(DevicePath.CertificateProgramPath, DevicePath.CertificateSystemPath, productName);
udpSenderStr = CreateUdpInfo(DevicePath.CertificateSystemPath);
if (!checkSuccess)
{
HandlerLock("证书到期\r\n请联系管理员");
}
return checkSuccess;
}
private void HandlerLock(string showStr)
{
if (setting.lockType == LockType.退)
{
Application.Quit();
}
else if (setting.lockType == LockType.)
{
MessageBox.Instance.Show("提示", showStr, "退出", () => { Application.Quit(); }, "证书提示");
}
else if (setting.lockType == LockType.)
{
MessageBox.Instance.Show("提示", showStr, "试用", () => { MessageBox.Instance.Hide(); TrialProgram(); }, "证书提示");
}
}
private void TrialProgram()
{
float time = 3600;
MessageBox.Instance.Show("开始试用,时间" + time + "秒");
TrialCor = StartCoroutine(TrialIEnumerator(time));
}
IEnumerator TrialIEnumerator(float time)
{
Debug.Log("开始试用,时间:" + time + "秒");
yield return new WaitForSeconds(time);
MessageBox.Instance.Show("试用已经结束,即将关闭。", "退出", Application.Quit);
Debug.Log("试用结束");
yield return new WaitForSeconds(10);
Application.Quit();
}
public static void CreateOneCertificate()
{
LockDll.CertificateVerification.CreateForeverCertificate(DevicePath.CertificateProgramPath, productName);
}
#region
private string CreateUdpInfo(string path)
{
Dictionary<string, string> certificateInfo = LockDll.CertificateVerification.GetCertificateInfo(DevicePath.CertificateProgramPath);
string tempInfo = "programProductName=" + productName + "&";
foreach (var item in certificateInfo)
{
tempInfo += item.Key + "=" + item.Value + "&";
}
return tempInfo;
}
private IEnumerator NetWorkBroadcast()
{
while (true)
{
yield return new WaitForSeconds(5);
udpSender.SendMsg("certificatehere");
}
}
private void UdpReceiveHandler(SocketMsg msg)
{
if (msg.msg == "certificateshow")
{
UDPClient.SendMsgOnce(msg.remoteIpEndPoint.Address.ToString(), msg.remoteIpEndPoint.Port, udpSenderStr);
}
else if (msg.msg.StartsWith("certificateinfo:"))
{
string m = msg.msg.Replace("certificateinfo:", "");
LockDll.CertificateVerification.CreateCertificate(DevicePath.CertificateSystemPath, m);
Debug.Log("写入证书,重新检测");
CheckCertificate();
}
}
#endregion
}
public enum LockType
{
,
,
退,
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 5c9400e9e90ceb849a94c37e80315c7b
timeCreated: 1626318866
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class CertificateSetting : ScriptableObject
{
[Header("是否检查证书")]
public bool isCheckCertificate;
[Header("加密弹窗模式")]
public LockType lockType;
[Header("项目ID")]
public string productID;
[HideInInspector]
public string useProdctName;
public CertificateSetting()
{
isCheckCertificate = true;
lockType = LockType.;
productID = "";
useProdctName = "";
}
public static CertificateSetting GetCertificateSetting()
{
CertificateSetting setting;
string outsidePath = DevicePath.StreamingAssetsPath + "/CertificateSetting.ini";
if (File.Exists(outsidePath))
{
setting = new CertificateSetting();
setting.isCheckCertificate = IniFile.GetTypeValue<bool>("Setting", "isCheckCertificate", true, outsidePath);
setting.lockType = (LockType)IniFile.GetTypeValue<int>("Setting", "lockType", 0, outsidePath);
setting.productID = IniFile.GetTypeValue<string>("Setting", "productID", "", outsidePath);
}
else
{
setting = Resources.Load<CertificateSetting>("Setting/CertificateSetting");
if (setting == null)
setting = new CertificateSetting();//赋予默认值
}
setting.useProdctName = string.IsNullOrWhiteSpace(setting.productID) ? Application.productName : setting.productID;
return setting;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: cbdadb604224e5e4290b66d51fb65c9a
timeCreated: 1628490899
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace GeneralTools
{
public class ConfigHelper
{
protected static string configPath;
protected static Dictionary<string, Dictionary<string, object>> configDict;
#region
public static int screen_width { get; set; }
public static int screen_height { get; set; }
public static int window_Left { get; set; }
public static int window_Top { get; set; }
public static bool showcursor { get; set; }
public static int fullscreen { get; set; }
public static int screenDepth { get; set; }
public static bool isAllowPlayBGM { get; set; }
public static int audioShotLimit { get; set; }
public static int logType { get; set; }
public static bool saveLog { get; set; }
public static bool broadcastDebug { get; set; }
public static int debugSocketMsgMode { get; set; }
public static int targetFramerate { get; set; }
public static int keyDownActionLevel { get; set; }
public static int releaseTime { get; set; }
#region
public static string serialPortName { get; set; }
public static int baudRate { get; set; }
public static bool enabled { get; set; }
public static int connectionTimeoutMs { get; set; }
public static int heartbeatIntervalSeconds { get; set; }
#endregion
#endregion
public static void Init(string _configPath)
{
configPath = _configPath;
ConfigHelper consts = new ConfigHelper();
Type type = consts.GetType();
PropertyInfo[] propertyInfoArr = type.GetProperties();
foreach (PropertyInfo property in propertyInfoArr)
{
string propertyName = property.Name;
Type t = property.PropertyType;
object obj = GetObj(t, propertyName);
if (obj == null)
{
Debug.LogError("错误的类型" + propertyName);
continue;
}
property.SetValue(consts, obj);
}
FieldInfo[] fieldInfoArr = type.GetFields();
foreach (FieldInfo fieldInfo in fieldInfoArr)
{
string propertyName = fieldInfo.Name;
Type t = fieldInfo.FieldType;
object obj = GetObj(t, propertyName);
if (obj == null)
{
Debug.LogError("错误的类型" + propertyName);
continue;
}
fieldInfo.SetValue(consts, obj);
}
}
public static T GetConfig<T>(string configName, string section = "config", T defultValue = default(T)) where T : IComparable
{
if (configDict == null)
{
configDict = new Dictionary<string, Dictionary<string, object>>();
}
if (!configDict.ContainsKey(section))
{
configDict[section] = new Dictionary<string, object>();
}
if (configDict[section].ContainsKey(configName))
{
return (T)configDict[section][configName];
}
else
{
if (defultValue == null) defultValue = (T)Convert.ChangeType("", typeof(T));
object obj = ReadConfigFromFile(configName, section, defultValue);
configDict[section][configName] = obj;
return (T)obj;
}
}
public static string GetConfigPath()
{
return configPath;
}
private static T ReadConfigFromFile<T>(string configName, string section, T defultValue) where T : IComparable
{
return IniFile.GetTypeValue(section, configName, defultValue, configPath);
}
private static object GetObj(Type t, string n)
{
object obj;
if (t == typeof(int))
obj = GetConfig<int>(n);
else if (t == typeof(float))
obj = GetConfig<float>(n);
else if (t == typeof(bool))
obj = GetConfig<bool>(n);
else if (t == typeof(string))
obj = GetConfig<string>(n);
else if (t == typeof(double))
obj = GetConfig<double>(n);
else if (t == typeof(short))
obj = GetConfig<short>(n);
else
obj = null;
return obj;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 11e95f5a3c249e74685f968f9a354ecf
timeCreated: 1615131753
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,84 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class DevicePath : MonoBehaviour
{
private static string streamingAssetsPath;
private static string persistentDataPath;
private static string currentDirectory;
private static string certificateProgramPath;
private static string certificateSystemPath;
public static string StreamingAssetsPath
{
get
{
if (string.IsNullOrEmpty(streamingAssetsPath))
{
streamingAssetsPath = Application.streamingAssetsPath;
}
return streamingAssetsPath;
}
}
public static string PersistentDataPath
{
get
{
if (string.IsNullOrEmpty(persistentDataPath))
{
persistentDataPath = Application.persistentDataPath;
}
return persistentDataPath;
}
}
public static string CurrentDirectory
{
get
{
if (string.IsNullOrEmpty(currentDirectory))
{
#if UNITY_STANDALONE_WIN
currentDirectory = Directory.GetCurrentDirectory();
#else
currentDirectory = Application.persistentDataPath;
#endif
}
return currentDirectory;
}
}
public static string CertificateProgramPath
{
get
{
if (string.IsNullOrEmpty(certificateProgramPath))
{
#if UNITY_STANDALONE_WIN
certificateProgramPath = Application.streamingAssetsPath + "/Certificate.ctf";
#else
certificateProgramPath = Application.streamingAssetsPath + "/Certificate.ctf";
#endif
}
return certificateProgramPath;
}
}
public static string CertificateSystemPath
{
get
{
if (string.IsNullOrEmpty(certificateSystemPath))
{
#if UNITY_STANDALONE_WIN
certificateSystemPath = Application.persistentDataPath + "/Certificate.ctf";
#else
certificateSystemPath = Application.persistentDataPath + "/Certificate.ctf";
#endif
}
return certificateSystemPath;
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 03ab300377358db4f86f98fcd1e9d557
timeCreated: 1619600005
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ba9531748d0fc4c4a84b8cb7cab7fd0d
folderAsset: yes
timeCreated: 1617951156
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,190 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
namespace GeneralTools
{
public class FileReader
{
/// <summary>
/// 获取指定目录下 所有指定类型的文件路径
/// 例如 *.BMP|*.JPG|*.GIF|*.PNG 所有文件 *.*
/// </summary>
/// <param name="path"></param>
/// <param name="filesType"></param>
/// <returns></returns>
public static List<string> GetPathAllFiles(string path, string filesType)
{
if (!Directory.Exists(path))
{
Debug.Log("未找到路径" + path);
return new List<string>();
}
List<string> filesPath = new List<string>();
string[] videotypeArr = filesType.Replace(" ", "").Split('|');
for (int i = 0; i < videotypeArr.Length; i++)
{
string[] dirs = Directory.GetFiles(@path, videotypeArr[i]);
for (int j = 0; j < dirs.Length; j++)
{
filesPath.Add(dirs[j]);
}
}
return filesPath;
}
/// <summary>
/// 获取指定目录下 所有指定类型的文件路径,会查找子目录
/// 例如 *.BMP|*.JPG|*.GIF|*.PNG 所有文件 *.*
/// </summary>
/// <param name="path"></param>
/// <param name="filesType"></param>
/// <returns></returns>
public static List<string> GetPathAllFilesRoot(string path, string filesType)
{
List<string> filesPath = new List<string>();
if (!Directory.Exists(path))
{
Debug.Log("未找到路径" + path);
}
else
{
filesPath = GetPathAllFilesRootPrivate(path, filesType);
}
return filesPath;
}
private static List<string> GetPathAllFilesRootPrivate(string path, string filesType)
{
List<string> filesPath = new List<string>();
string[] videotypeArr = filesType.Replace(" ", "").Split('|');
for (int i = 0; i < videotypeArr.Length; i++)
{
string[] dirs = Directory.GetFiles(@path, videotypeArr[i]);
for (int j = 0; j < dirs.Length; j++)
{
filesPath.Add(dirs[j]);
}
}
string[] childDirs = Directory.GetDirectories(path);
foreach (var childDir in childDirs)
{
filesPath.AddRange(GetPathAllFilesRootPrivate(childDir, filesType));
}
return filesPath;
}
/// <summary>
/// 读取图片转成texture2d
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static Texture2D GetTexture(string path)
{
if (!File.Exists(path))
{
Debug.LogError("未找到路径" + path);
return null;
}
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
fs.Seek(0, SeekOrigin.Begin);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int)fs.Length);
fs.Close();
fs.Dispose();
fs = null;
Texture2D t = new Texture2D(1, 1);
t.LoadImage(bytes);
t.name = Path.GetFileNameWithoutExtension(path);
return t;
}
/// <summary>
/// 读取路径下所有图片转成texture2d列表
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static List<Texture2D> GetTextures(string path, string filesType = "*.jpg|*.png")
{
if (!Directory.Exists(path))
{
Debug.LogError("未找到路径" + path);
return new List<Texture2D>();
}
List<string> files = GetPathAllFiles(path, filesType);
if (files.Count == 0)
{
Debug.LogError("未找到图片" + path);
return null;
}
List<Texture2D> res = new List<Texture2D>();
foreach (var item in files)
{
res.Add(GetTexture(item));
}
return res;
}
/// <summary>
/// 读取txt转成string
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string GetTxt(string path)
{
if (!File.Exists(path))
{
Debug.LogError("未找到路径" + path);
return null;
}
StreamReader r = new StreamReader(path, Encoding.UTF8);
string s = r.ReadToEnd();
r.Close();
r.Dispose();
return s;
}
public static List<string> GetTxtLine(string path)
{
if (!File.Exists(path))
{
Debug.LogError("未找到路径" + path);
return new List<string>();
}
List<string> temp = new List<string>();
StreamReader r = new StreamReader(path, Encoding.UTF8);
string s;
while ((s = r.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(s))
{
temp.Add(s);
}
}
r.Close();
r.Dispose();
return temp;
}
public static void DeleteDirectory(string path)
{
if (!Directory.Exists(path))
return;
string[] files = Directory.GetFiles(path);
for (int i = 0; i < files.Length; i++)
{
File.Delete(files[i]);
}
string[] dirs = Directory.GetDirectories(path);
for (int i = 0; i < dirs.Length; i++)
{
DeleteDirectory(dirs[i]);
}
Directory.Delete(path);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 3f64d354b5ded66469513422ee869699
timeCreated: 1605062281
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class FileWriter
{
public static void WriteFile(byte[] data, string path)
{
if (File.Exists(path))
File.Delete(path);
string dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
FileStream fs = new FileStream(path, FileMode.Create);
StreamWriter streamWrite = new StreamWriter(fs);
fs.Write(data, 0, data.Length);
fs.Flush();
fs.Close();
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: a177afac2c50f30429f05df16c1c915b
timeCreated: 1617951106
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,188 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System;
namespace GeneralTools
{
public class IniFile
{
protected static Dictionary<string, Dictionary<string, Dictionary<string, string>>> dataDict = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath)
{
return Read(Section, Key, NoText, iniFilePath);
}
public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath)
{
return Write(Section, Key, Value, iniFilePath);
}
public static void ClearCache(string iniFilePath)
{
if (string.IsNullOrWhiteSpace(iniFilePath))
{
return;
}
dataDict.Remove(iniFilePath);
try
{
dataDict.Remove(Path.GetFullPath(iniFilePath));
}
catch (Exception)
{
// 忽略路径规范化失败,原始键已尝试清理。
}
}
public static T GetTypeValue<T>(string section, string key, T defultValue, string iniFilePath) where T : IComparable
{
string s = ReadIniData(section, key, "", iniFilePath);
object obj;
try
{
obj = (T)Convert.ChangeType(s, typeof(T));
}
catch (Exception)
{
obj = defultValue;
}
return (T)obj;
}
#if UNITY_STANDALONE_WIN
[DllImport("kernel32", CharSet = CharSet.Auto)]
private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32", CharSet = CharSet.Auto)]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
public static string Read(string Section, string Key, string NoText, string iniFilePath)
{
if (File.Exists(iniFilePath))
{
StringBuilder temp = new StringBuilder(1024);
GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
return temp.ToString();
}
else
{
return string.Empty;
}
}
public static bool Write(string Section, string Key, string Value, string iniFilePath)
{
if (!File.Exists(iniFilePath))
{
using (File.Create(iniFilePath)) { }
}
long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
return OpStation != 0;
}
#else
private static string Read(string Section, string Key, string NoText, string iniFilePath)
{
iniFilePath = Path.GetFullPath(iniFilePath);
if (File.Exists(iniFilePath))
{
return GetValue(Section, Key, NoText, iniFilePath);
}
else
{
return NoText;
}
}
private static bool Write(string Section, string Key, string Value, string iniFilePath)
{
iniFilePath = Path.GetFullPath(iniFilePath);
if (!File.Exists(iniFilePath))
{
using (File.Create(iniFilePath)) { }
}
SetValue(Section, Key, Value, iniFilePath);
WriteIni(iniFilePath);
dataDict[iniFilePath] = ReadIniFile(iniFilePath);
return true;
}
#endif
private static string GetValue(string Section, string Key, string NoText, string iniFilePath)
{
if (!dataDict.ContainsKey(iniFilePath))
{
dataDict[iniFilePath] = ReadIniFile(iniFilePath);
}
if (!dataDict[iniFilePath].ContainsKey(Section))
{
return NoText;
}
else if (!dataDict[iniFilePath][Section].ContainsKey(Key))
{
return NoText;
}
return dataDict[iniFilePath][Section][Key];
}
private static Dictionary<string, Dictionary<string, string>> SetValue(string Section, string Key, string Value, string iniFilePath)
{
Dictionary<string, Dictionary<string, string>> groupDict = new Dictionary<string, Dictionary<string, string>>();
if (!dataDict.ContainsKey(iniFilePath))
{
dataDict[iniFilePath] = ReadIniFile(iniFilePath);
}
groupDict = dataDict[iniFilePath];
if (!groupDict.ContainsKey(Section))
{
groupDict[Section] = new Dictionary<string, string>();
}
groupDict[Section][Key] = Value;
return groupDict;
}
private static void WriteIni(string iniFilePath)
{
if (!dataDict.ContainsKey(iniFilePath))
return;
Dictionary<string, Dictionary<string, string>> groupDict = dataDict[iniFilePath];
string waitWriteStr = "";
foreach (var group in groupDict)
{
waitWriteStr += $"[{group.Key}]" + "\r\n";
foreach (var kw in group.Value)
{
waitWriteStr += $"{kw.Key}={kw.Value}" + "\r\n";
}
}
File.WriteAllText(iniFilePath, waitWriteStr, Encoding.UTF8);
}
private static Dictionary<string, Dictionary<string, string>> ReadIniFile(string iniFilePath)
{
Dictionary<string, Dictionary<string, string>> groupDict = new Dictionary<string, Dictionary<string, string>>();
string[] textArr = File.ReadAllLines(iniFilePath);
string nowGroupName = "";
for (int i = 0; i < textArr.Length; i++)
{
textArr[i] = textArr[i].Trim();
if (textArr[i].StartsWith(";") || textArr[i].StartsWith("") || textArr[i].StartsWith("#") || textArr[i].StartsWith("-") || textArr[i].StartsWith(""))
{
continue;
}
if (textArr[i].Contains("=") && groupDict.ContainsKey(nowGroupName))
{
string[] kw = textArr[i].Split('=');
groupDict[nowGroupName][kw[0]] = kw[1];
}
else if (textArr[i].StartsWith("[") && textArr[i].EndsWith("]"))
{
//表示是组
string groupName = textArr[i].TrimStart('[').TrimEnd(']');
nowGroupName = groupName;
groupDict[groupName] = new Dictionary<string, string>();
}
}
return groupDict;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 11ca85924f8962146bad56814d6f9937
timeCreated: 1615131778
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,118 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Linq;
namespace GeneralTools
{
public class FileDebug : SingletonBaseAttribute<FileDebug>
{
FileStream fileStream_log;
StreamWriter streamWrite_log;
Queue<LogItem> logQue = new Queue<LogItem>();
string dirPath = "";
public override void IAwake()
{
if (ConfigHelper.saveLog)
{
CreateTxt();
Application.logMessageReceived += LogHandler;
}
}
private void CreateTxt()
{
dirPath = DevicePath.CurrentDirectory + "/Log";
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
string fileName_log = dirPath + "/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "----" + "log" + ".txt";
fileStream_log = new FileStream(fileName_log, FileMode.OpenOrCreate, FileAccess.ReadWrite);
streamWrite_log = new StreamWriter(fileStream_log);
CheckLogFileNum(dirPath, 20);
}
public override void IOnApplicationQuit()
{
if (ConfigHelper.saveLog)
{
streamWrite_log.Close();
fileStream_log.Close();
Application.logMessageReceived -= LogHandler;
}
}
private void LogHandler(string condition, string stackTrace, LogType type)
{
logQue.Enqueue(new LogItem()
{
messageString = condition,
stackTrace = stackTrace,
logType = type,
time = DateTime.Now
});
}
private void FixedUpdate()
{
if (logQue.Count > 0)
{
try
{
var item = logQue.Peek(); // 取队首元素但先不移除
var timeStr = item.time.ToString("HH:mm:ss.ff");
var logStr = string.Format("{0}-[{1}]{2}======>{3}", timeStr, item.logType, item.messageString, item.stackTrace);
streamWrite_log.WriteLine(logStr);
streamWrite_log.Flush();
logQue.Dequeue(); // 成功执行了再移除队首元素
}
catch (IOException ex)
{
Debug.Log(ex.Message);
}
}
}
/// <summary>
/// 删除多余的Log
/// </summary>
/// <param name="path"></param>
/// <param name="maxNum"></param>
protected void CheckLogFileNum(string path, int maxNum)
{
List<string> pathList = Directory.GetFiles(path).ToList();
int deleteNum = pathList.Count - maxNum;
if (deleteNum > 0)
{
for (int i = 0; i < deleteNum; i++)
{
File.Delete(pathList[i]);
}
}
}
}
}
public struct LogItem
{
/// <summary>
/// 日志内容
/// </summary>
public string messageString;
/// <summary>
/// 调用堆栈
/// </summary>
public string stackTrace;
/// <summary>
/// 日志类型
/// </summary>
public LogType logType;
/// <summary>
/// 记录时间
/// </summary>
public DateTime time;
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: f9035f7e0929cc6499cb8dc9b35596d5
timeCreated: 1565852970
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b3126402cd333214abc1258e7551c1ea
folderAsset: yes
timeCreated: 1628585739
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,174 @@
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
using System.IO;
namespace GeneralTools
{
/// <summary>
/// 序列帧动画播放器
/// 支持UGUI的Image和Unity2D的SpriteRenderer
/// </summary>
public class FrameAnimator : MonoBehaviour
{
//目标Image组件
private RawImage image;
/// <summary>
/// 序列帧
/// </summary>
private List<Texture> frames = null;
/// <summary>
/// 帧率
/// </summary>
private float framerate = 24.0f;
/// <summary>
/// 是否忽略timeScale
/// </summary>
private bool ignoreTimeScale = true;
/// <summary>
/// 是否循环
/// </summary>
private bool loop = true;
/// <summary>
/// 是否允许播放
/// </summary>
private bool isAllowPlay = false;
/// <summary>
/// 结束事件
/// 在每次播放完一个周期时触发
/// 在循环模式下触发此事件时,当前帧不一定为结束帧
/// </summary>
public event Action OnFinishEvent;
//当前帧索引
private int currentFrameIndex = 0;
//下一次更新时间
private float timer = 0.0f;
public FrameAnimator Init(List<Texture> _frames, bool _loop, float _framerate = 24)
{
Stop();
image = GetComponent<RawImage>();
if (image == null)
{
Debug.LogError("未找到RawImage", gameObject);
}
frames = _frames;
loop = _loop;
framerate = _framerate;
image.texture = _frames[0];
OnFinishEvent = null;
return this;
}
public void Play()
{
isAllowPlay = true;
gameObject.SetActive(true);
}
public void Pause()
{
isAllowPlay = false;
}
public void Stop()
{
isAllowPlay = false;
ResetIndex();
}
public void Hide()
{
Stop();
gameObject.SetActive(false);
}
public void RePlay()
{
isAllowPlay = false;
ResetIndex();
if (frames.Count > 0)
{
image.texture = frames[currentFrameIndex];
}
Play();
}
public void SetLoop(bool _loop)
{
loop = _loop;
}
/// <summary>
/// 重设动画索引
/// </summary>
private int ResetIndex()
{
currentFrameIndex = framerate > 0 ? 0 : frames.Count - 1;
return currentFrameIndex;
}
void FixedUpdate()
{
//帧数据无效,禁用脚本
if (frames == null || frames.Count == 0 || image == null || frames.Count == 1 || framerate == 0)
{
return;
}
else
{
//是否允许播放
if (!isAllowPlay) return;
//获取当前时间
float time = ignoreTimeScale ? Time.unscaledTime : Time.time;
//计算帧间隔时间
float interval = Mathf.Abs(1.0f / framerate);
//满足更新条件,执行更新操作
if (time - timer > interval)
{
//执行更新操作
DoUpdate();
}
}
}
//具体更新操作
private void DoUpdate()
{
//计算新的索引
int nextIndex = currentFrameIndex + (framerate > 0 ? 1 : -1);
//索引越界,表示已经到结束帧
if (nextIndex < 0 || nextIndex >= frames.Count)
{
//非循环,模式结束
if (loop == false)
{
isAllowPlay = false;
//播放结束事件
OnFinishEvent?.Invoke();
nextIndex = frames.Count - 1;
}
else
{
nextIndex = ResetIndex();
}
}
//钳制索引
currentFrameIndex = Mathf.Clamp(nextIndex, 0, frames.Count - 1);
//更新图片
RefreshTexture(currentFrameIndex);
//设置计时器为当前时间
timer = ignoreTimeScale ? Time.unscaledTime : Time.time;
}
private void RefreshTexture(int index)
{
image.texture = frames[index];
}
//正向手动刷新
public void ManualUpdatePositive()
{
DoUpdate();
}
//反向手动刷新
public void ManualUpdateReverse()
{
framerate *= -1;
DoUpdate();
framerate *= -1;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d3ca7c741b7b76a44bffeeacd12de0e8
timeCreated: 1588750370
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,305 @@
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace GeneralTools
{
/// <summary>
/// 序列帧动画播放器
/// 支持UGUI的Image和Unity2D的SpriteRenderer
/// </summary>
public class FramesAnimator : MonoBehaviour
{
//目标Image组件
private RawImage image;
private List<FramesAttribute> framesList;
/// <summary>
/// 全部结束事件
/// </summary>
public event Action OnAllFinishEvent;
//是否允许播放
private bool isAllowPlay = true;
//当前帧索引
private int currentFrameIndex = 0;
//当前动画序号索引
private int currentAnimationIndex = 0;
//下一次更新时间
private float timer = 0.0f;
public FramesAnimator Init(List<FramesAttribute> frameAttritubes)
{
Stop();
image = GetComponent<RawImage>();
if (image == null)
{
Debug.LogError("未找到RawImage", gameObject);
}
framesList = frameAttritubes;
OnAllFinishEvent = null;
return this;
}
public FramesAnimator Init(params List<Texture>[] texArr)
{
List<FramesAttribute> temp = new List<FramesAttribute>();
for (int i = 0; i < texArr.Length; i++)
{
FramesAttribute newFM = new FramesAttribute(texArr[i], i == texArr.Length - 1);
temp.Add(newFM);
}
return Init(temp);
}
public FramesAnimator Init(List<List<Texture>> texList, List<bool> loopList, List<Action> finishEventList = null)
{
List<FramesAttribute> temp = new List<FramesAttribute>();
if (finishEventList == null)
finishEventList = new List<Action>();
for (int i = 0; i < texList.Count; i++)
{
bool il = i < loopList.Count ? loopList[i] : false;
FramesAttribute newFM = new FramesAttribute(texList[i], il);
newFM.OnFinishEvent += i < finishEventList.Count ? finishEventList[i] : null;
temp.Add(newFM);
}
return Init(temp);
}
public void Play()
{
isAllowPlay = true;
gameObject.SetActive(true);
}
public void Pause()
{
isAllowPlay = false;
}
public void Stop()
{
isAllowPlay = false;
ResetIndex();
}
public void Hide()
{
Stop();
gameObject.SetActive(false);
}
public void RePlay()
{
isAllowPlay = false;
ResetIndex();
if (framesList.Count > 0)
{
if (framesList[0].framesList.Count > 0)
{
image.texture = framesList[0].framesList[currentFrameIndex];
}
}
Play();
}
public void PlayIndex(int index)
{
if (framesList == null)
return;
if (index < 0 || index >= framesList.Count)
return;
isAllowPlay = false;
currentAnimationIndex = index;
currentFrameIndex = framesList[currentAnimationIndex].framerate > 0 ? 0 : framesList[currentAnimationIndex].framesList.Count - 1;
if (framesList[currentAnimationIndex].framesList.Count > 0)
{
image.texture = framesList[currentAnimationIndex].framesList[currentFrameIndex];
}
Play();
}
/// <summary>
/// 改变一个索引的临时loop
/// </summary>
public void SetLoopOfIndex(int index, bool loop)
{
if (index >= 0 && index < framesList.Count)
{
framesList[index].loop = loop;
}
}
/// <summary>
/// 改变一个索引的永久loop
/// </summary>
public void SetLoopOfIndexForever(int index, bool loop)
{
if (index >= 0 && index < framesList.Count)
{
framesList[index].InitialLoop = loop;
}
}
/// <summary>
/// 获得当前动画索引
/// </summary>
public int GetCurrentAnimationIndex()
{
return currentAnimationIndex;
}
/// <summary>
/// 改变当前索引的临时loop
/// </summary>
public void SetCurrentAnimationLoop(bool loop)
{
SetLoopOfIndex(currentAnimationIndex, loop);
}
/// <summary>
/// 动画全部设置为不循环,播放完销毁自身
/// </summary>
public void GoDestroy()
{
for (int i = 0; i < framesList.Count; i++)
{
SetLoopOfIndexForever(i, false);
}
OnAllFinishEvent += () =>
{
Destroy(gameObject);
};
}
/// <summary>
/// 重设动画索引
/// </summary>
private int ResetIndex()
{
currentAnimationIndex = 0;
//重置Loop
if (framesList != null)
{
for (int i = 0; i < framesList.Count; i++)
{
framesList[i].ReSetLoop();
}
currentFrameIndex = framesList[currentAnimationIndex].framerate > 0 ? 0 : framesList[currentAnimationIndex].framesList.Count - 1;
}
return currentFrameIndex;
}
void FixedUpdate()
{
if (framesList == null || framesList.Count == 0 || image == null)
{
return;
}
else
{
//是否允许播放
if (!isAllowPlay) return;
PlayOneFrame(framesList[currentAnimationIndex]);
}
}
private void PlayOneFrame(FramesAttribute fm)
{
if (fm == null || fm.framesList.Count == 0 || fm.framerate == 0)
{
return;
}
//获取当前时间
float time = fm.ignoreTimeScale ? Time.unscaledTime : Time.time;
//计算帧间隔时间
float interval = Mathf.Abs(1.0f / fm.framerate);
//满足更新条件,执行更新操作
if (time - timer > interval)
{
//执行更新操作
DoUpdate(fm);
}
}
//具体更新操作
private void DoUpdate(FramesAttribute fm)
{
//计算新的索引
int nextIndex = currentFrameIndex + (fm.framerate > 0 ? 1 : -1);
//索引越界,表示已经到结束帧
if (nextIndex < 0 || nextIndex >= fm.framesList.Count)
{
nextIndex = 0;
//不循环,整体动画索引+1
if (fm.loop == false)
{
//播放结束事件
fm.OnFinish();
currentAnimationIndex += 1;
if (currentAnimationIndex >= framesList.Count)
{
//全部播放完毕,帧索引不归零
isAllowPlay = false;
OnAllFinishEvent?.Invoke();
currentAnimationIndex = framesList.Count - 1;
nextIndex = fm.framesList.Count - 1;
}
else
{
//未结束,指向下一个动画,帧索引归零
fm = framesList[currentAnimationIndex];
nextIndex = fm.framerate > 0 ? 0 : fm.framesList.Count - 1;
}
}
else
{
//循环,帧索引归零
nextIndex = fm.framerate > 0 ? 0 : fm.framesList.Count - 1;
}
}
//钳制索引
currentFrameIndex = Mathf.Clamp(nextIndex, 0, fm.framesList.Count - 1);
//更新图片
RefreshTexture(fm, currentFrameIndex);
//设置计时器为当前时间
timer = fm.ignoreTimeScale ? Time.unscaledTime : Time.time;
}
private void RefreshTexture(FramesAttribute fm, int index)
{
image.texture = fm.framesList[index];
}
public void ManualUpdatePositive()
{
FramesAttribute fm = framesList[currentAnimationIndex];
DoUpdate(fm);
}
//反向手动刷新
public void ManualUpdateReverse()
{
FramesAttribute fm = framesList[currentAnimationIndex];
fm.framerate *= -1;
DoUpdate(fm);
fm.framerate *= -1;
}
}
public class FramesAttribute
{
public List<Texture> framesList;
public bool loop;
public bool InitialLoop { get { return initialLoop; } set { loop = value; initialLoop = value; } }
private bool initialLoop;
public event Action OnFinishEvent;
public float framerate = 24.0f;
public bool ignoreTimeScale = true;
public FramesAttribute()
{
}
public FramesAttribute(List<Texture> _framesList, bool _loop)
{
framesList = _framesList;
InitialLoop = _loop;
OnFinishEvent = null;
}
public void ReSetLoop()
{
InitialLoop = InitialLoop;
}
public void OnFinish()
{
OnFinishEvent?.Invoke();
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: a54aa2fd9271a774eaaca0bc9aa8158e
timeCreated: 1611841608
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,118 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace GeneralTools
{
public class KeyDownManager : SingletonBaseAttribute<KeyDownManager>
{
public List<KeyDownActionClass> actionList = new List<KeyDownActionClass>();
int keyDownActionLevel = 0;
public override void IAwake()
{
actionList = new List<KeyDownActionClass>();
keyDownActionLevel = ConfigHelper.keyDownActionLevel;
}
public override void IStart()
{
AddKeyDownAction(KeyCode.F2, () => { ShowKeyAction(); }, "显示所有绑定的按键指令", false, 5);
}
private void AddAction(KeyCode _code, Action _action, string _summary, bool _continuousPress, int _level)
{
if (_action == null)
{
Debug.Log("设置的" + _code + "action为空");
return;
}
KeyDownActionClass newAct = new KeyDownActionClass();
newAct.code = _code;
newAct.action = _action;
newAct.summary = string.IsNullOrEmpty(_summary) ? _action.Target.ToString() : _summary;
newAct.continuousPress = _continuousPress;
newAct.level = _level >= 0 ? _level : 0;
actionList.Add(newAct);
}
private void AddKeyDownAction(KeyDownActionClass action)
{
if (action != null)
{
actionList.Add(action);
}
}
/// <summary>
/// 设置按键 等级默认0 常规常驻5以上
/// </summary>
/// <param 按键="_code"></param>
/// <param atcion="_action"></param>
/// <param 连按="continuousPress"></param>
/// <param 按键等级="_level"></param>
public void AddKeyDownAction(KeyCode _code, Action _action, bool _continuousPress = false, int _level = 0)
{
AddAction(_code, _action, null, _continuousPress, _level);
}
/// <summary>
/// 设置按键
/// </summary>
/// <param 按键="_code"></param>
/// <param atcion="_action"></param>
/// <param 简介="_summary"></param>
/// <param 连按="continuousPress"></param>
/// <param 按键等级="_level"></param>
public void AddKeyDownAction(KeyCode _code, Action _action, string _summary, bool _continuousPress = false, int _level = 0)
{
AddAction(_code, _action, _summary, _continuousPress, _level);
}
private void ShowKeyAction()
{
for (int i = 0; i < actionList.Count; i++)
{
string showlog = actionList[i].code + " ---->" + actionList[i].summary + "-----LV:" + actionList[i].level;
switch (ConfigHelper.logType)
{
case 0:
Debug.Log(showlog);
break;
case 1:
Debug.LogWarning(showlog);
break;
case 2:
Debug.LogError(showlog);
break;
case 3:
Debug.LogError(showlog);
break;
default:
Debug.Log(showlog);
break;
}
}
}
private void Update()
{
for (int i = 0; i < actionList.Count; i++)
{
if (!actionList[i].continuousPress && Input.GetKeyDown(actionList[i].code) && actionList[i].level >= keyDownActionLevel && actionList[i].level >= 0)
{
actionList[i].action();
}
if (actionList[i].continuousPress && Input.GetKey(actionList[i].code) && actionList[i].level >= keyDownActionLevel && actionList[i].level >= 0)
{
actionList[i].action();
}
}
}
}
}
public class KeyDownActionClass
{
public KeyCode code;
public Action action;
/// <summary>
/// 触发等级
/// </summary>
public int level;
public string summary;
public bool continuousPress;
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b94ffd7941907694892b750ce893b064
timeCreated: 1565860252
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.IO;
namespace GeneralTools
{
public class LoadingManager : SingletonBaseAttribute<LoadingManager>
{
protected bool canAddAction = true;
public event Action LoadingFinshedListeners;
public override void IAwake()
{
canAddAction = true;
}
public override void IStart()
{
StartCoroutine(WaitRegister());
}
IEnumerator WaitRegister()
{
MessageBox.Instance.ShowNotice("正在加载中", "等待组件注册");
yield return new WaitForSeconds(3);
canAddAction = false;
List<Action> loadingListeners = WaitLoadResources.loadingListeners;
float progress = 0;
int loadNum = loadingListeners.Count;
MessageBox.Instance.HideNotice();
//加载注册事件
for (int i = 0; i < loadingListeners.Count; i++)
{
float p = progress / loadNum;
MessageBox.Instance.ShowProgressBar("正在加载中", (p * 100).ToString("F1") + "%", p);
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
loadingListeners[i]();
progress += 1;
yield return new WaitForEndOfFrame();
}
MessageBox.Instance.ShowProgressBar("加载完成", "加载完成", 1);
yield return new WaitForSeconds(2.0f);
MessageBox.Instance.HideProgressBar();
LoadingFinshedListeners?.Invoke();
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 02ceee8fb354e8842a64671c8ddd211d
timeCreated: 1588752832
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 15051421fac115c4f9c70eae9daffd1f
folderAsset: yes
timeCreated: 1588834362
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,130 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace GeneralTools
{
/// <summary>
/// 3.10更新 GUI改成UGUI CANVAS预设
/// </summary>
public class MessageBox : SingletonBaseAttribute<MessageBox>
{
protected SetMessageShow messageShow;
protected SetNoticeShow noticeShow;
protected SetProgressBarShow progressBarShow;
static List<MessageShowClass> messageShowList = new List<MessageShowClass>();
public override void IAwake()
{
base.IAwake();
if(messageShow==null)
{
messageShow = UtilityTool.FindChild<SetMessageShow>(transform, "MessageShowCanvas");
messageShow.Hide();
}
if (noticeShow == null)
{
noticeShow = UtilityTool.FindChild<SetNoticeShow>(transform, "NoticeShow");
noticeShow.Hide();
}
if (progressBarShow == null)
{
progressBarShow = UtilityTool.FindChild<SetProgressBarShow>(transform, "ProgressBarShow");
progressBarShow.Hide();
}
}
public void Show(string tittleStr, string messageStr, string buttonStr, Action action, string messageName = "通用")
{
AddMessageToList(tittleStr, messageStr, buttonStr, action, messageName);
}
public void Show(string messageStr, string buttonStr, Action action, string messageName = "通用")
{
AddMessageToList("提示", messageStr, buttonStr, action, messageName);
}
public void Show(string messageStr, Action action, string messageName = "通用")
{
AddMessageToList("提示", messageStr, "确认", action, messageName);
}
public void Show(string tittleStr, string messageStr, string messageName = "通用")
{
AddMessageToList(tittleStr, messageStr, "确认", Hide, messageName);
}
public void Show(string messageStr)
{
AddMessageToList("提示", messageStr, "确认", Hide, "通用");
}
public void Hide()
{
int removeIndex = messageShowList.Count - 1;
if (removeIndex >= 0)
messageShowList.RemoveAt(removeIndex);
int maxIndex = messageShowList.Count - 1;
if (maxIndex < 0)
{
messageShow.Hide();
}
else
{
MessageShowClass m = messageShowList[maxIndex];
messageShow.Show(m, Hide);
}
}
public void Hide(string messageName)
{
messageShowList.RemoveAll(m => m.messageName == messageName);
int maxIndex = messageShowList.Count - 1;
if (maxIndex < 0)
{
messageShow.Hide();
}
else
{
MessageShowClass m = messageShowList[maxIndex];
messageShow.Show(m, Hide);
}
}
public void ShowNotice(string tittleStr, string messageStr)
{
noticeShow.Show(tittleStr, messageStr);
}
public void HideNotice()
{
noticeShow.Hide();
}
public void ShowProgressBar(string tittleStr, string numStr, float progress)
{
progressBarShow.Show(tittleStr, numStr, progress);
}
public void HideProgressBar()
{
progressBarShow.Hide();
}
private void AddMessageToList(string tittleStr, string messageStr, string buttonStr, Action action, string messageName)
{
MessageShowClass newMessage = new MessageShowClass(tittleStr, messageStr, buttonStr, action, messageName);
messageShowList.Add(newMessage);
messageShow.Show(newMessage, Hide);
}
}
public class MessageShowClass
{
public string tittleStr;
public string messageStr;
public string buttonStr;
public Action action;
public string messageName;
public MessageShowClass()
{
}
public MessageShowClass(string _tittleStr, string _messageStr, string _buttonStr, Action _action, string _messageName)
{
tittleStr = _tittleStr;
messageStr = _messageStr;
buttonStr = _buttonStr;
action = _action;
messageName = _messageName;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 908cdaaae8ff7f24abd11c9c1a4a845b
timeCreated: 1566046250
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace GeneralTools
{
public class SetMessageShow : MonoBehaviour
{
public Button closeBtn;
public Button confirmBtn;
public Text buttonText;
public Text tittleText;
public Text showText;
public void Show(string tittleStr, string messageStr, string buttonStr, Action action, Action closeAction)
{
closeBtn.gameObject.SetActive(false);
closeBtn.onClick.RemoveAllListeners();
confirmBtn.onClick.RemoveAllListeners();
closeBtn.onClick.AddListener(() => { closeAction(); });
confirmBtn.onClick.AddListener(() => { action(); });
buttonText.text = buttonStr;
tittleText.text = tittleStr;
showText.text = messageStr;
gameObject.SetActive(true);
}
public void Show(MessageShowClass message, Action closeAction)
{
Show(message.tittleStr, message.messageStr, message.buttonStr, message.action, closeAction);
}
public void Hide()
{
gameObject.SetActive(false);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: babac815c8b0cdd4998dd5256f0078b6
timeCreated: 1583828049
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace GeneralTools
{
public class SetNoticeShow : MonoBehaviour
{
public Text tittleText;
public Text showText;
public void Show(string tittleStr, string messageStr)
{
tittleText.text = tittleStr;
showText.text = messageStr;
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ee5a127499fadcc4eb8a1fe903dc2d0b
timeCreated: 1588772716
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace GeneralTools
{
public class SetProgressBarShow : MonoBehaviour
{
public Text tittleText;
public Text numText;
public Slider slider;
public void Show(string tittleStr, string numStr, float progress)
{
tittleText.text = tittleStr;
numText.text = numStr;
slider.value = progress;
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 84e50d1fe096c5b4bbb5f303abb4952b
timeCreated: 1588834861
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using ZXing;
using ZXing.Common;
using ZXing.QrCode;
using ZXing.QrCode.Internal;
namespace GeneralTools
{
public class QRTool
{
///// <summary>
///// 将内容转换到二维码并写入文件
///// </summary>
///// <param name="path"></param>
//public static void WriteToFile(string path, TexStyle style, string content, int qrWidth, int qrHeight, Texture2D middleTex = null)
//{
// byte[] bytes = TexConvertBytes(GeneQRwithString2(content, qrWidth, qrHeight, middleTex), style);
// using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
// {
// fs.Write(bytes, 0, bytes.Length);
// }
//}
/// <summary>
/// 创建二维码,不能添加小图片,不需要图标时推荐
/// </summary>
/// <param name="content">二维码的内容</param>
/// <param name="qrWidth">二维码的宽度</param>
/// <param name="qrHeight">二维码的高度</param>
/// <returns>二维码生成的Texture2D</returns>
public static Texture2D GeneQRwithString1(string content, int qrWidth, int qrHeight)
{
// 创建 BarcodeWriter 并设置条件
QrCodeEncodingOptions options = new QrCodeEncodingOptions()
{
CharacterSet = "UTF-8",
Width = qrWidth,
Height = qrHeight,
// 边缘宽度
Margin = 2,
};
BarcodeWriter barcodeWriter = new BarcodeWriter()
{
Format = BarcodeFormat.QR_CODE,
Options = options
};
Color32[] colors = barcodeWriter.Write(content);
// 创建一张和二维码一样像素的 Texture2D
Texture2D tex = new Texture2D(qrWidth, qrHeight);
tex.SetPixels32(colors);
tex.Apply();
return tex;
}
/// <summary>
/// 创建二维码,添加小图标,可以不添加
/// </summary>
/// <param name="content">二维码的内容</param>
/// <param name="qrWidth">二维码的宽度</param>
/// <param name="qrHeight">二维码的高度</param>
/// <param name="middleTex">添加的小图标</param>
/// <returns>二维码生成的Texture2D</returns>
public static Texture2D GeneQRwithString2(string content, int qrWidth, int qrHeight, Texture2D middleTex = null)
{
// 将 content 编码成 bit矩阵
Dictionary<EncodeHintType, object> hints = new Dictionary<EncodeHintType, object>();
hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8"); // 编码
hints.Add(EncodeHintType.MARGIN, 2); // 边缘距离
hints.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错方式
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, qrWidth, qrHeight, hints); // bit 矩阵
Texture2D tex = new Texture2D(qrWidth, qrHeight);
for (int y = 0; y < qrHeight; y++)
{
for (int x = 0; x < qrWidth; x++)
{
if (bitMatrix[x, y])
{
tex.SetPixel(x, y, Color.black); // true 的地方 不能用白色
}
else
{
tex.SetPixel(x, y, Color.white); // false 的位置 不能用黑色
}
}
}
// 在 Tex2D的中间添加图片是不会影响检测的
if (middleTex != null)
{
AddTex(middleTex, tex.width / 2f, tex.height / 2f, tex);
}
tex.Apply();
return tex;
}
/// <summary>
/// 在二维码中插入小图标
/// 在 Tex2D的中间添加小的图片是不会影响检测的
/// </summary>
/// <param name="addTex">添加的Texture2D</param>
/// <param name="centerX">添加的图的中心点 ==> 大图左下角为起始点</param>
/// <param name="centerY">添加的图的中心点 ==> 大图左下角为起始点</param>
/// <param name="qrTex">源二维码的图片</param>
private static void AddTex(Texture2D addTex, float centerX, float centerY, Texture2D qrTex)
{
float addTexWidth = addTex.width;
float addTexHeight = addTex.height;
// 小图片左下角 在 大图中的坐标(因为 Texture2D的坐标原点在左下角 )
Vector2 localAddTexOriginal = new Vector2((int)(centerX - addTexWidth / 2f), (int)(centerY - addTexHeight / 2));
for (int x = 0; x < qrTex.width; x++)
{
for (int y = 0; y < qrTex.height; y++)
{
// 坐标在 添加的图内部,就改成添加图的像素信息
if (Mathf.Abs(x - centerX) <= addTexWidth / 2 && Mathf.Abs(y - centerY) <= addTexHeight / 2)
{
// 获取添加图的像素
Vector2 local = new Vector2(x, y) - localAddTexOriginal; // x,y 相对于下图左下角的向量(坐标)
Color color = addTex.GetPixel((int)local.x, (int)local.y);
// 将像素赋给二维码图像
qrTex.SetPixel(x, y, color);
}
}
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1c6682002b1fb9e4eac6cbbf63620878
timeCreated: 1567504202
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,58 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GeneralTools
{
/// <summary>
/// 所有释放资源的方法放这里
/// </summary>
public class ReleaseResources : SingletonBaseAttribute<ReleaseResources>
{
private int releaseTime = 30;
private event Action ReleaseActionListeners;
public override void IAwake()
{
ReleaseActionListeners += ResoucesUnLoad;
ReleaseActionListeners += GCCollect;
}
public override void IStart()
{
releaseTime = ConfigHelper.releaseTime;
if (releaseTime > 0)
{
StartCoroutine(Release());
}
}
/// <summary>
/// 添加一个释放资源方法
/// </summary>
/// <param name="action"></param>
public void AddReleaseAction(Action action)
{
if (action != null)
{
ReleaseActionListeners += action;
}
}
private void ResoucesUnLoad()
{
Resources.UnloadUnusedAssets();
}
private void GCCollect()
{
GC.Collect();
}
IEnumerator Release()
{
while (true)
{
yield return new WaitForSeconds(releaseTime);
if (ReleaseActionListeners != null)
ReleaseActionListeners();
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: faeaa6a84c467734ca31a2ea1807b016
timeCreated: 1566033212
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace GeneralTools
{
public class ResourcesStore
{
public static Dictionary<string, List<object>> resourceDict = new Dictionary<string, List<object>>();
public static void AddResource(string key, bool cover, params object[] resource)
{
key = Path.GetFullPath(key);
if (!cover && resourceDict.ContainsKey(key))
{
}
else
{
resourceDict[key] = new List<object>(resource);
}
}
public static List<object> GetResource(string key)
{
key = Path.GetFullPath(key);
if (resourceDict.ContainsKey(key))
{
return resourceDict[key];
}
else
{
return new List<object>();
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 94f2a48181adcff48913d6b2c2879cb0
timeCreated: 1605513992
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace GeneralTools
{
public class ScriptManager : MonoBehaviour
{
/// <summary>
/// 自动获取子物体上的脚本
/// </summary>
protected List<BaseAttribute> scriptList = new List<BaseAttribute>();
protected BaseAttribute gameManager;
protected LoadingManager loadManager;
private void Awake()
{
ConfigHelper.Init(DevicePath.StreamingAssetsPath + "/config.ini");
DontDestroyOnLoad(gameObject);
CollectScript();
ScriptAwake();
}
private void Start()
{
ScriptStart();
}
private void OnApplicationQuit()
{
ScriptApplicationQuit();
}
void ScriptAwake()
{
for (int i = 0; i < scriptList.Count; i++)
{
if (scriptList[i] != null)
{
scriptList[i].IAwake();
}
}
}
void ScriptStart()
{
for (int i = 0; i < scriptList.Count; i++)
{
if (scriptList[i] != null)
{
scriptList[i].IStart();
}
}
if (loadManager == null && gameManager!=null)
{
//有加载事件时不运行GameStart
gameManager.GameStart();
}
}
void ScriptApplicationQuit()
{
for (int i = 0; i < scriptList.Count; i++)
{
if (scriptList[i] != null)
{
scriptList[i].IOnApplicationQuit();
}
}
}
void CollectScript()
{
scriptList.Clear();
scriptList = UtilityTool.CollectComponent<BaseAttribute>(transform);
loadManager = UtilityTool.FindChild<LoadingManager>(transform, "LoadingManager");
gameManager = UtilityTool.FindChild<BaseAttribute>(transform, "GameManager");
if (gameManager == null)
{
//Debug.LogError("缺少GameManager");
}
if (loadManager != null)
{
loadManager.LoadingFinshedListeners += gameManager.GameStart;
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 616bf07501e300747be04a38c6e81017
timeCreated: 1564814469
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GeneralTools
{
public class ShowMousePosition : SingletonBaseAttribute<ShowMousePosition>
{
private bool isShow = false;
public override void IStart()
{
KeyDownManager.Instance.AddKeyDownAction(KeyCode.RightControl, () => { isShow = !isShow; }, "显示/隐藏 鼠标位置信息", false, 5);
}
private void OnGUI()
{
if (isShow)
{
float x = Input.mousePosition.x;
float y = Screen.height - Input.mousePosition.y;
float showX = x;
float showY = y;
float showWidth = Screen.width / 19;
float showHeight = Screen.height / 18;
if (showX + showWidth > Screen.width)
showX -= showWidth;
if (showY + showHeight > Screen.height)
showY -= showHeight;
GUIStyle bb = new GUIStyle();
bb.normal.textColor = Color.white;
bb.fontSize = Screen.height / 54;
GUI.Label(new Rect(showX, showY, showWidth, showHeight), " 鼠标位置", bb);
GUI.Label(new Rect(showX, showY + Screen.height / 54, showWidth, showHeight), " x:" + x.ToString("F2"), bb);
GUI.Label(new Rect(showX, showY + Screen.height / 27, showWidth, showHeight), " y:" + y.ToString("F2"), bb);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More