TEngine Commit 1.0.0

TEngine Commit 1.0.0
This commit is contained in:
ALEXTANG
2022-05-20 23:19:50 +08:00
parent ea8c79aa6d
commit 90ae4874a9
474 changed files with 110489 additions and 0 deletions

8
Assets/ConfigStruct.meta Normal file
View File

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

View File

@@ -0,0 +1,16 @@
//
// Auto Generated Code By excel2json
// https://neil3d.gitee.io/coding/excel2json.html
// 1. 每个 Sheet 形成一个 Struct 定义, Sheet 的名称作为 Struct 的名称
// 2. 表格约定:第一行是变量名称,第二行是变量类型
// Generate From AttrReg.xlsx
public class AttrConfig
{
public int ID; // ID
public string Name; // 名称
}
// End of Auto Generated Code

View File

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

View File

@@ -0,0 +1,21 @@
//
// Auto Generated Code By excel2json
// https://neil3d.gitee.io/coding/excel2json.html
// 1. 每个 Sheet 形成一个 Struct 定义, Sheet 的名称作为 Struct 的名称
// 2. 表格约定:第一行是变量名称,第二行是变量类型
// Generate From BuffConfig.xlsx
public class BuffConfig
{
public int BuffID; // BuffID
public int BuffType; // BuffType
public float BuffValue; // Buff数值
public float BuffValue2; // Buff数值2
public string BuffName; // Buff名称
public int HandleState; // 生效阶段
public int CanAddBuff; // 可否叠加
}
// End of Auto Generated Code

View File

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

View File

@@ -0,0 +1,23 @@
//
// Auto Generated Code By excel2json
// https://neil3d.gitee.io/coding/excel2json.html
// 1. 每个 Sheet 形成一个 Struct 定义, Sheet 的名称作为 Struct 的名称
// 2. 表格约定:第一行是变量名称,第二行是变量类型
// Generate From FeatureConfig.xlsx
public class FeatureConfig
{
public int ID; // 特性ID
public string Name; // 特性名称
public int[] BuffIDArray; // BuffID数组
public int Type; // 类型
public int OnlyOne; // 是否唯一
public int UseColor; // 使用颜色
public string ColorStr; // 颜色Str
public float Rate; // 概率
public string Desc; // 特性描述
}
// End of Auto Generated Code

View File

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

View File

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

View File

@@ -0,0 +1,3 @@
{
"name": "GameLogic"
}

View File

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

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GameLogic
{
public class GameMain
{
public void RunMain()
{
}
public void Update()
{
}
}
}

View File

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

8
Assets/Scene.meta Normal file
View File

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

View File

@@ -0,0 +1,249 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &78470599
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 78470602}
- component: {fileID: 78470601}
- component: {fileID: 78470600}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &78470600
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 78470599}
m_Enabled: 1
--- !u!20 &78470601
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 78470599}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &78470602
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 78470599}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1297425162
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1297425163}
- component: {fileID: 1297425164}
m_Layer: 0
m_Name: TEngine
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1297425163
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1297425162}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1297425164
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1297425162}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 869b1b77e2356f14a86cbb2646bc4032, type: 3}
m_Name:
m_EditorClassIdentifier:

View File

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

8
Assets/TEngine.meta Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ExcelDataReader.DataSet</name>
</assembly>
<members>
<member name="T:ExcelDataReader.ExcelDataReaderExtensions">
<summary>
ExcelDataReader DataSet extensions
</summary>
</member>
<member name="M:ExcelDataReader.ExcelDataReaderExtensions.AsDataSet(ExcelDataReader.IExcelDataReader,ExcelDataReader.ExcelDataSetConfiguration)">
<summary>
Converts all sheets to a DataSet
</summary>
<param name="self">The IExcelDataReader instance</param>
<param name="configuration">An optional configuration object to modify the behavior of the conversion</param>
<returns>A dataset with all workbook contents</returns>
</member>
<member name="T:ExcelDataReader.ExcelDataSetConfiguration">
<summary>
Processing configuration options and callbacks for IExcelDataReader.AsDataSet().
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataSetConfiguration.UseColumnDataType">
<summary>
Gets or sets a value indicating whether to set the DataColumn.DataType property in a second pass.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataSetConfiguration.ConfigureDataTable">
<summary>
Gets or sets a callback to obtain configuration options for a DataTable.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataSetConfiguration.FilterSheet">
<summary>
Gets or sets a callback to determine whether to include the current sheet in the DataSet. Called once per sheet before ConfigureDataTable.
</summary>
</member>
<member name="T:ExcelDataReader.ExcelDataTableConfiguration">
<summary>
Processing configuration options and callbacks for AsDataTable().
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataTableConfiguration.EmptyColumnNamePrefix">
<summary>
Gets or sets a value indicating the prefix of generated column names.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataTableConfiguration.UseHeaderRow">
<summary>
Gets or sets a value indicating whether to use a row from the data as column names.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataTableConfiguration.ReadHeaderRow">
<summary>
Gets or sets a callback to determine which row is the header row. Only called when UseHeaderRow = true.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataTableConfiguration.FilterRow">
<summary>
Gets or sets a callback to determine whether to include the current row in the DataTable.
</summary>
</member>
<member name="P:ExcelDataReader.ExcelDataTableConfiguration.FilterColumn">
<summary>
Gets or sets a callback to determine whether to include the specific column in the DataTable. Called once per column after reading the headers.
</summary>
</member>
</members>
</doc>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
</configuration>

View File

@@ -0,0 +1,15 @@
@SET EXCEL_FOLDER=xls
@SET JSON_FOLDER=..\..\TResources\Config
@SET EXE= Tools\excel2json\excel2json.exe
@SET CsharpPath=..\..\ConfigStruct
@ECHO Del old Config...
del %JSON_FOLDER% /S /Q
del %CsharpPath% /S /Q
@ECHO Converting excel files in folder %EXCEL_FOLDER% ...
for /f "delims=" %%i in ('dir /b /a-d /s %EXCEL_FOLDER%\*.xlsx') do (
@echo processing %%~nxi
@CALL %EXE% --excel %EXCEL_FOLDER%\%%~nxi --json %JSON_FOLDER%\%%~ni.json --p %CsharpPath%\%%~ni.cs --header 3 --cell_json true --exclude_prefix #
)
pause

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

@@ -0,0 +1,405 @@
using System;
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using LitJson;
namespace TEngine.Editor
{
public class PackageManagerInternal : EditorWindow
{
[MenuItem("TEngine/Package Manager Internal", priority = 1500)]
private static void Open()
{
var window = GetWindow<PackageManagerInternal>("TEngine Manager Internal");
window.minSize = new Vector2(600f, 400f);
window.Show();
}
/// <summary>
/// 资源包数据结构
/// </summary>
[Serializable]
private class PackageTemplate
{
/// <summary>
/// 名称
/// </summary>
public string name;
/// <summary>
/// 作者
/// </summary>
public string author;
/// <summary>
/// 版本
/// </summary>
public string version;
/// <summary>
/// 发布日期
/// </summary>
public string releasedDate;
/// <summary>
/// 简介
/// </summary>
public string description;
/// <summary>
/// 依赖项
/// </summary>
public string[] dependencies;
}
//资源包信息列表
private List<List<PackageTemplate>> packages;
//折叠状态
private Dictionary<string, bool> foldoutDic;
//列表滚动视图
private Vector2 listScroll;
//最后更新日期
private string lastUpdateDate;
//当前选中的资源包信息
private PackageTemplate currentSelected;
//搜索内容
private string searchContent;
private void OnEnable()
{
packages = new List<List<PackageTemplate>>();
foldoutDic = new Dictionary<string, bool>();
}
private void OnGUI()
{
//水平布局
GUILayout.BeginHorizontal("Toolbar");
{
//搜索
OnSearchGUI();
}
GUILayout.EndHorizontal();
//水平布局
GUILayout.BeginHorizontal(GUILayout.ExpandHeight(true));
{
//垂直布局 设置左侧列表宽度
GUILayout.BeginVertical(GUILayout.Width(200f));
{
//绘制列表
OnListGUI();
}
GUILayout.EndVertical();
//分割线
GUILayout.Box(string.Empty, "EyeDropperVerticalLine", GUILayout.ExpandHeight(true), GUILayout.Width(1f));
//垂直布局
GUILayout.BeginVertical(GUILayout.ExpandHeight(true));
{
//绘制详情
OnDetailGUI();
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
private void OnSearchGUI()
{
var newSearchContent = GUILayout.TextField(searchContent, "SearchTextField");
if (newSearchContent != searchContent)
{
searchContent = newSearchContent;
currentSelected = null;
Repaint();
}
if (UnityEngine.Event.current.type == EventType.MouseDown && !GUILayoutUtility.GetLastRect().Contains(UnityEngine.Event.current.mousePosition))
{
GUI.FocusControl(null);
}
}
private void OnListGUI()
{
//滚动视图
listScroll = GUILayout.BeginScrollView(listScroll);
{
GUIStyle versionStyle = new GUIStyle(GUI.skin.label) { fontStyle = FontStyle.Italic };
for (int i = 0; i < packages.Count; i++)
{
List<PackageTemplate> list = packages[i];
PackageTemplate first = list[0];
if (!string.IsNullOrEmpty(searchContent) && !first.name.ToLower().Contains(searchContent.ToLower())) continue;
if (foldoutDic[first.name])
{
foldoutDic[first.name] = EditorGUILayout.Foldout(foldoutDic[first.name], first.name);
for (int n = 0; n < list.Count; n++)
{
GUILayout.BeginHorizontal(currentSelected == list[n] ? "SelectionRect" : "IN Title");
GUILayout.FlexibleSpace();
GUILayout.Label(list[n].version, versionStyle);
GUILayout.Space(30f);
GUILayout.EndHorizontal();
if (GUILayoutUtility.GetLastRect().Contains(UnityEngine.Event.current.mousePosition) && UnityEngine.Event.current.type == EventType.MouseDown)
{
currentSelected = list[n];
UnityEngine.Event.current.Use();
}
}
}
else
{
GUILayout.BeginHorizontal(currentSelected == first ? "SelectionRect" : "Toolbar");
{
foldoutDic[first.name] = EditorGUILayout.Foldout(foldoutDic[first.name], first.name);
GUILayout.FlexibleSpace();
GUILayout.Label(first.version, versionStyle);
}
GUILayout.EndHorizontal();
//鼠标点击选中
if (GUILayoutUtility.GetLastRect().Contains(UnityEngine.Event.current.mousePosition) && UnityEngine.Event.current.type == EventType.MouseDown)
{
currentSelected = first;
UnityEngine.Event.current.Use();
}
}
}
}
GUILayout.EndScrollView();
//分割线
GUILayout.Box(string.Empty, "EyeDropperHorizontalLine", GUILayout.ExpandWidth(true), GUILayout.Height(1f));
//水平布局 设置高度
GUILayout.BeginHorizontal(GUILayout.Height(23f));
{
//最后更新日期
GUILayout.Label(lastUpdateDate);
//刷新按钮
if (GUILayout.Button(EditorGUIUtility.IconContent("Refresh"), GUILayout.Width(30f)))
{
//清空当前的资源包信息列表
packages.Clear();
//清空折叠栏信息
foldoutDic.Clear();
//当前选中的资源包设为空
currentSelected = null;
//发起网络请求
EditorCoroutineRunner.StartEditorCoroutine(GetPackagesInfo());
}
}
GUILayout.EndHorizontal();
}
private void OnDetailGUI()
{
if (currentSelected != null)
{
//名称
GUILayout.Label(currentSelected.name, new GUIStyle(GUI.skin.label) { fontSize = 25, fontStyle = FontStyle.Bold });
EditorGUILayout.Space();
//作者
GUILayout.Label(currentSelected.author, new GUIStyle(GUI.skin.label) { fontSize = 12 });
EditorGUILayout.Space();
//版本 + 发布日期
GUILayout.Label($"Version {currentSelected.version} - {currentSelected.releasedDate}", new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = FontStyle.Bold });
EditorGUILayout.Space();
//分割线
GUILayout.Box(string.Empty, GUILayout.ExpandWidth(true), GUILayout.Height(1f));
//简介
GUILayout.Label(currentSelected.description);
}
GUILayout.FlexibleSpace();
//分割线
GUILayout.Box(string.Empty, "EyeDropperHorizontalLine", GUILayout.ExpandWidth(true), GUILayout.Height(1f));
//水平布局 设置高度
GUILayout.BeginHorizontal(GUILayout.Height(21f));
{
GUILayout.FlexibleSpace();
//下载并导入
if (GUILayout.Button("Import", GUILayout.Width(50f)))
{
if (currentSelected != null)
{
EditorCoroutineRunner.StartEditorCoroutine(DownloadPackage(currentSelected));
}
}
}
GUILayout.EndHorizontal();
}
//获取资源包信息
private IEnumerator GetPackagesInfo()
{
string url = "http://1.12.241.46:8081/TEngine/packages.json";
WWW www = new WWW(url);
yield return www;
if (www.error == null)
{
//List<object> list = JsonUtility.FromJson<List<object>>(www.text);
List<PackageTemplate> list = JsonMapper.ToObject<List<PackageTemplate>>(www.text);
for (int i = 0; i < list.Count; i++)
{
var package = list[i] as PackageTemplate;
//查找列表中是否已经存在该资源包其他版本
int index = packages.FindIndex(m => m != null && m.Count > 0 && m[0].name == package.name);
if (index == -1)
{
var newList = new List<PackageTemplate> { package };
packages.Add(newList);
foldoutDic.Add(package.name, false);
}
else
{
packages[index].Add(package);
}
}
//更新最后刷新日期
lastUpdateDate = DateTime.Now.ToString();
}
else
{
Debug.LogError(www.error);
}
}
//下载并导入资源包
private IEnumerator DownloadPackage(PackageTemplate package)
{
string url = $"http://1.12.241.46:8081/TEngine/packages/{package.name}/{package.version}.unitypackage";
WWW www = new WWW(url);
yield return www;
if (www.error == null)
{
byte[] bytes = www.bytes;
string path = $"{Application.dataPath}/{package.name}-{package.version}.unitypackage";
//写入本地
using (FileStream fs = new FileStream(path, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
//导入
AssetDatabase.ImportPackage(path, false);
//删除
File.Delete(path);
}
else
{
Debug.LogError(www.error);
}
}
}
public static class EditorCoroutineRunner
{
private class EditorCoroutine : IEnumerator
{
private Stack<IEnumerator> executionStack;
public EditorCoroutine(IEnumerator iterator)
{
executionStack = new Stack<IEnumerator>();
executionStack.Push(iterator);
}
public bool MoveNext()
{
IEnumerator i = executionStack.Peek();
if (i.MoveNext())
{
object result = i.Current;
if (result != null && result is IEnumerator)
{
executionStack.Push((IEnumerator)result);
}
return true;
}
else
{
if (executionStack.Count > 1)
{
executionStack.Pop();
return true;
}
}
return false;
}
public void Reset()
{
throw new NotSupportedException("This Operation Is Not Supported.");
}
public object Current
{
get { return executionStack.Peek().Current; }
}
public bool Find(IEnumerator iterator)
{
return executionStack.Contains(iterator);
}
}
private static List<EditorCoroutine> editorCoroutineList;
private static List<IEnumerator> buffer;
public static IEnumerator StartEditorCoroutine(IEnumerator iterator)
{
if (editorCoroutineList == null)
{
editorCoroutineList = new List<EditorCoroutine>();
}
if (buffer == null)
{
buffer = new List<IEnumerator>();
}
if (editorCoroutineList.Count == 0)
{
EditorApplication.update += Update;
}
buffer.Add(iterator);
return iterator;
}
private static bool Find(IEnumerator iterator)
{
foreach (EditorCoroutine editorCoroutine in editorCoroutineList)
{
if (editorCoroutine.Find(iterator))
{
return true;
}
}
return false;
}
private static void Update()
{
editorCoroutineList.RemoveAll(coroutine => { return coroutine.MoveNext() == false; });
if (buffer.Count > 0)
{
foreach (IEnumerator iterator in buffer)
{
if (!Find(iterator))
{
editorCoroutineList.Add(new EditorCoroutine(iterator));
}
}
buffer.Clear();
}
if (editorCoroutineList.Count == 0)
{
EditorApplication.update -= Update;
}
}
}
}

View File

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

View File

@@ -0,0 +1,78 @@
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor
{
public class TEngineWindow : EditorWindow
{
public enum ModuleType
{
/// <summary>
/// 存在Package中
/// </summary>
InPackage,
/// <summary>
/// 存在项目中
/// </summary>
InProject
}
public static ModuleType showModuleType;
[MenuItem("TEngine/EditorWindow", priority = 1500)]
private static void Open()
{
var window = GetWindow<TEngineWindow>("EditorWindow");
window.minSize = new Vector2(900, 600);
window.maxSize = new Vector2(900, 600);
window.Show();
}
private void OnEnable()
{
showModuleType = (ModuleType)EditorPrefs.GetInt("showModuleType", 0);
}
private void OnGUI()
{
//水平布局
GUILayout.BeginHorizontal("Toolbar");
{
//搜索
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.EndHorizontal();
//水平布局
GUILayout.BeginHorizontal(GUILayout.ExpandHeight(true));
{
//垂直布局 设置左侧列表宽度
GUILayout.BeginVertical(GUILayout.Width(200f));
{
//绘制列表
}
GUILayout.EndVertical();
//分割线
GUILayout.Box(string.Empty, "EyeDropperVerticalLine", GUILayout.ExpandHeight(true), GUILayout.Width(1f));
//垂直布局
GUILayout.BeginVertical(GUILayout.ExpandHeight(true));
{
//绘制详情
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,34 @@
using System;
using TEngine;
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor
{
[CustomEditor(typeof(AssetTag), true)]
public class AssetTagEditor : UnityEditor.Editor
{
private AssetTag _target;
private void OnEnable()
{
_target = (AssetTag)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.TextField("AssetPath", _target.Path);
if (GUILayout.Button("定位资源", GUILayout.Width(68)))
{
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>($"{AssetConfig.AssetRootPath}/{_target.Path}");
if (obj)
{
EditorGUIUtility.PingObject(obj);
}
}
EditorGUILayout.EndHorizontal();
}
}
}

View File

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

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor
{
public class TEngineEditor
{
#if UNITY_EDITOR
internal class EditorMenus
{
[UnityEditor.MenuItem("TEngine/Open TEngine Document")]
public static void OpenTEngineDocument()
{
Application.OpenURL("http://1.12.241.46:5000/");
}
//[UnityEditor.MenuItem("TEngine/Install TEngineWithToolKits")]
//public static void InstallPackageKit()
//{
// Application.OpenURL("http://1.12.241.46:9000");
//}
}
public static void LoadData(string filePath, ICollection<string> data)
{
try
{
FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate);
StreamReader streamReader = new StreamReader(fileStream);
string content = streamReader.ReadLine();
while (!string.IsNullOrEmpty(content))
{
data.Add(content);
content = streamReader.ReadLine();
}
streamReader.Close();
}
catch (Exception ex)
{
Debug.LogError("读取文件失败:" + ex);
}
}
public static void SaveData(string filePath, ICollection<string> data)
{
try
{
FileStream fileStream = new FileStream(filePath, FileMode.Create);
StreamWriter streamWriter = new StreamWriter(fileStream);
foreach (var content in data)
{
streamWriter.WriteLine(content);
}
streamWriter.Flush();
streamWriter.Close();
AssetDatabase.Refresh();
}
catch (Exception ex)
{
Debug.LogError("写入文件失败:" + ex);
}
}
[MenuItem("Assets/导出Unity资源包", false, 20)]
static void ExportPackage()
{
if (Selection.objects.Length == 0)
{
return;
}
var assetPaths = new string[Selection.objects.Length];
for (var i = 0; i < assetPaths.Length; i++)
{
assetPaths[i] = AssetDatabase.GetAssetPath(Selection.objects[i]);
}
ExportPackage(assetPaths);
}
public static void ExportPackage(string[] assetPaths)
{
var path = EditorUtility.SaveFilePanel("导出Unity资源包", "", "", "unitypackage");
if (string.IsNullOrEmpty(path))
{
return;
}
assetPaths = AssetDatabase.GetDependencies(assetPaths);
AssetDatabase.ExportPackage(assetPaths, path, ExportPackageOptions.Interactive | ExportPackageOptions.Recurse | ExportPackageOptions.IncludeDependencies);
}
#endif
}
}

View File

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

View File

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

View File

@@ -0,0 +1,335 @@
#if UNITY_EDITOR
namespace TEngine.Editor
{
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
public class ScriptGenerator
{
private static string gap = "/";
[MenuItem("GameObject/ScriptGenerator/UIProperty", priority = 49)]
public static void MemberProperty()
{
Generate(false);
}
[MenuItem("GameObject/ScriptGenerator/UIPropertyAndListener", priority = 49)]
public static void MemberPropertyAndListener()
{
Generate(true);
}
[MenuItem("GameObject/ScriptGenerator/UISwitchGroup", priority = 49)]
public static void UISwitchGroup()
{
var root = Selection.activeTransform;
if (root == null)
{
return;
}
var content = SwitchGroupGenerator.Instance.Process(root);
TextEditor te = new TextEditor();
te.text = content;
te.SelectAll();
te.Copy();
}
private static void Generate(bool includeListener)
{
var root = Selection.activeTransform;
if (root != null)
{
StringBuilder strVar = new StringBuilder();
StringBuilder strBind = new StringBuilder();
StringBuilder strOnCreate = new StringBuilder();
StringBuilder strCallback = new StringBuilder();
Ergodic(root, root, ref strVar, ref strBind, ref strOnCreate, ref strCallback);
StringBuilder strFile = new StringBuilder();
if (includeListener)
{
strFile.Append("using TEngine;\n");
strFile.Append("using TEngine;\n");
strFile.Append("using TEngine.Unitity;\n");
strFile.Append("using UnityEngine;\n");
strFile.Append("using UnityEngine.UI;\n\n");
strFile.Append("\tclass " + root.name + " : UIWindow\n");
strFile.Append("\t{\n");
}
// 脚本工具生成的代码
strFile.Append("\t#region 脚本工具生成的代码\n");
strFile.Append(strVar);
strFile.Append("\tprotected override void ScriptGenerator()\n");
strFile.Append("\t{\n");
strFile.Append(strBind);
strFile.Append(strOnCreate);
strFile.Append("\t}\n");
strFile.Append("\t#endregion");
if (includeListener)
{
strFile.Append("\n\n");
// #region 事件
strFile.Append("\t#region 事件\n");
strFile.Append(strCallback);
strFile.Append("\t#endregion\n\n");
strFile.Append("}\n");
}
TextEditor te = new TextEditor();
te.text = strFile.ToString();
te.SelectAll();
te.Copy();
}
}
private static void Ergodic(Transform root, Transform transform, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate, ref StringBuilder strCallback)
{
for (int i = 0; i < transform.childCount; ++i)
{
Transform child = transform.GetChild(i);
WriteScript(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback);
if (child.name.StartsWith("m_item"))
{
// 子 Item 不再往下遍历
continue;
}
Ergodic(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback);
}
}
private static string GetRelativePath(Transform child, Transform root)
{
StringBuilder path = new StringBuilder();
path.Append(child.name);
while (child.parent != null && child.parent != root)
{
child = child.parent;
path.Insert(0, gap);
path.Insert(0, child.name);
}
return path.ToString();
}
private static string GetBtnFuncName(string varName)
{
return "OnClick" + varName.Replace("m_btn", string.Empty) + "Btn";
}
private static string GetToggleFuncName(string varName)
{
return "OnToggle" + varName.Replace("m_toggle", string.Empty) + "Change";
}
public static Dictionary<string, string> dicWidget = new Dictionary<string, string>()
{
{"m_go", "GameObject"},
{"m_item", "GameObject"},
{"m_tf", "Transform"},
{"m_rect","RectTransform"},
{"m_text","Text"},
{"m_richText","RichTextItem"},
{"m_tbtn","TextButtonItem"},
{"m_btn","Button"},
{"m_img","Image"},
{"m_rimg","RawImage"},
{"m_scroll","ScrollRect"},
{"m_input","InputField"},
{"m_grid","GridLayoutGroup"},
{"m_clay","CircleLayoutGroup"},
{"m_hlay","HorizontalLayoutGroup"},
{"m_vlay","VerticalLayoutGroup"},
{"m_slider","Slider"},
{"m_group","ToggleGroup"},
{"m_toggle","Toggle"},
{"m_curve","AnimationCurve"},
};
private static void WriteScript(Transform root, Transform child, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate, ref StringBuilder strCallback)
{
string varName = child.name;
string varType = string.Empty;
foreach (var pair in dicWidget)
{
if (varName.StartsWith(pair.Key))
{
varType = pair.Value;
break;
}
}
if (varType == string.Empty)
{
return;
}
string varPath = GetRelativePath(child, root);
if (!string.IsNullOrEmpty(varName))
{
strVar.Append("\t\tprivate " + varType + " " + varName + ";\n");
switch (varType)
{
case "Transform":
strBind.Append(string.Format("\t\t\t{0} = FindChild(\"{1}\");\n", varName, varPath));
break;
case "GameObject":
strBind.Append(string.Format("\t\t\t{0} = FindChild(\"{1}\").gameObject;\n", varName, varPath));
break;
case "AnimationCurve":
strBind.Append(string.Format("\t\t\t{0} = FindChildComponent<AnimCurveObject>(\"{1}\").m_animCurve;\n", varName, varPath));
break;
case "RichItemIcon":
strBind.Append(string.Format("\t\t\t{0} = CreateWidgetByType<{1}>(\"{2}\");\n", varName, varType, varPath));
break;
case "RedNoteBehaviour":
case "TextButtonItem":
case "SwitchTabItem":
case "UIActorWidget":
case "UIEffectWidget":
strBind.Append(string.Format("\t\t\t{0} = CreateWidget<{1}>(\"{2}\");\n", varName, varType, varPath));
break;
default:
strBind.Append(string.Format("\t\t\t{0} = FindChildComponent<{1}>(\"{2}\");\n", varName, varType, varPath));
break;
}
if (varType == "Button")
{
string varFuncName = GetBtnFuncName(varName);
strOnCreate.Append(string.Format("\t\t\t{0}.onClick.AddListener({1});\n", varName, varFuncName));
strCallback.Append(string.Format("\t\tprivate void {0}()\n", varFuncName));
strCallback.Append("\t\t{\n\t\t}\n");
}
if (varType == "Toggle")
{
string varFuncName = GetToggleFuncName(varName);
strOnCreate.Append(string.Format("\t\t\t{0}.onValueChanged.AddListener({1});\n", varName, varFuncName));
strCallback.Append(string.Format("\t\tprivate void {0}(bool isOn)\n", varFuncName));
strCallback.Append("\t\t{\n\t\t}\n");
}
}
}
public class GeneratorHelper : EditorWindow
{
[MenuItem("GameObject/ScriptGenerator/About", priority = 49)]
public static void About()
{
GeneratorHelper welcomeWindow = (GeneratorHelper)EditorWindow.GetWindow(typeof(GeneratorHelper), false, "About ScriptGenerator");
}
public void Awake()
{
minSize = new Vector2(400, 600);
}
protected void OnGUI()
{
GUILayout.BeginVertical();
foreach (var item in ScriptGenerator.dicWidget)
{
GUILayout.Label(item.Key + "\t" + item.Value);
}
}
}
public class SwitchGroupGeneratorHelper : EditorWindow
{
[MenuItem("GameObject/ScriptGenerator/AboutSwitchGroup", priority = 50)]
public static void About()
{
GetWindow(typeof(SwitchGroupGeneratorHelper), false, "AboutSwitchGroup");
}
public void Awake()
{
minSize = new Vector2(400, 600);
}
protected void OnGUI()
{
GUILayout.BeginVertical();
GUILayout.Label(SwitchGroupGenerator.CONDITION + "\t" + "SwitchTabItem[]");
}
}
public class SwitchGroupGenerator
{
/*
遍历子节点,找到所有名为 m_switchGroup 开始的节点,输出该节点
*/
public const string CONDITION = "m_switchGroup";
public static readonly SwitchGroupGenerator Instance = new SwitchGroupGenerator();
public string Process(Transform root)
{
var sbd = new StringBuilder();
var list = new List<Transform>();
Collect(root, list);
foreach (var node in list)
{
sbd.AppendLine(Process(root, node)).AppendLine();
}
return sbd.ToString();
}
public void Collect(Transform node, List<Transform> nodeList)
{
if (node.name.StartsWith(CONDITION))
{
nodeList.Add(node);
return;
}
var childCnt = node.childCount;
for (var i = 0; i < childCnt; i++)
{
var child = node.GetChild(i);
Collect(child, nodeList);
}
}
public string Process(Transform root, Transform groupTf)
{
var parentPath = GetPath(root, groupTf);
var _name = groupTf.name;
var sbd = new StringBuilder(@"
var _namePath = ""#parentPath"";
var _nameTf = FindChild(_namePath);
var childCnt = _nameTf.childCount;
SwitchTabItem[] _name;
_name = new SwitchTabItem[childCnt];
for (var i = 0; i < childCnt; i++)
{
var child = _nameTf.GetChild(i);
_name[i] = CreateWidget<SwitchTabItem>(_namePath + ""/"" + child.name);
}");
sbd.Replace("_name", _name);
sbd.Replace("#parentPath", parentPath);
return sbd.ToString();
}
public string GetPath(Transform root, Transform childTf)
{
if (childTf == null)
{
return string.Empty;
}
if (childTf == root)
{
return childTf.name;
}
var parentPath = GetPath(root, childTf.parent);
if (parentPath == string.Empty)
{
return childTf.name;
}
return parentPath + "/" + childTf.name;
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,98 @@
//-----------------------------------------------------------------------
// Copyright (c) TEngine. All rights reserved.
// Author: TangXiao
// Date: 2022/5/14 16:29:13
//-----------------------------------------------------------------------
const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
const mime = {
css: "text/css",
gif: "image/gif",
html: "text/html",
ico: "image/x-icon",
jpeg: "image/jpeg",
jpg: "image/jpeg",
js: "text/javascript",
json: "application/json",
pdf: "application/pdf",
png: "image/png",
svg: "image/svg+xml",
swf: "application/x-shockwave-flash",
tiff: "image/tiff",
txt: "text/plain",
wav: "audio/x-wav",
wma: "audio/x-ms-wma",
wmv: "video/x-ms-wmv",
xml: "text/xml",
};
const port = 8081;
const httpServer = http.createServer((request, response) => {
const requestUrl = request.url;
let pathName = url.parse(requestUrl).pathname;
// 对路径解码,防止中文乱码
pathName = decodeURI(pathName);
// 绝对路径
const filePath = path.resolve(__dirname + pathName);
// 扩展名
let ext = path.extname(pathName);
ext = ext ? ext.slice(1) : "unknown";
// 未知的类型一律用"text/plain"类型
const contentType = mime[ext] || "text/plain";
// fs.stat()方法用于判断给定的路径是否存在
fs.stat(filePath, (err, stats) => {
// 路径不存在则返回404
if (err) {
response.writeHead(404, { "content-type": "text/html" });
response.end("<h1>404 Not Found</h1>");
}
// 如果是文件
if (!err && stats.isFile()) {
response.writeHead(200, { "content-type": contentType });
// 建立流对象,读文件
const stream = fs.createReadStream(filePath);
// 错误处理
stream.on("error", function() {
response.writeHead(500, { "content-type": contentType });
response.end("<h1>500 Server Error</h1>");
});
// 读取文件
stream.pipe(response);
//response.end(); // 这个地方有坑,加了会关闭对话,看不到内容了
}
// 如果是路径
if (!err && stats.isDirectory()) {
let html = " <head><meta charset = 'utf-8'/></head>";
// 读取该路径下文件
fs.readdir(filePath, (err, files) => {
if (err) {
response.writeHead(500, { "content-type": contentType });
response.end("<h1>路径读取失败!</h1>");
} else {
for (const file of files) {
if (file === "index.html") {
response.writeHead(200, { "content-type": "text/html" });
response.end(file);
break;
}
html += `<div><a href='${file}'>${file}</a></div>`;
}
response.writeHead(200, { "content-type": "text/html" });
response.end(html);
}
});
}
});
});
httpServer.listen(port, function() {
console.log(`File Service: ${port}`);
});

View File

@@ -0,0 +1 @@
node FileSys.js

View File

@@ -0,0 +1 @@
node FileSys.js

87
Assets/TEngine/README.md Normal file
View File

@@ -0,0 +1,87 @@
# TEngine
TEngine
<p align="center">
<img src="http://1.12.241.46:8081/temp/TEngine512.png" alt="logo" width="256" height="256">
</p>
<h3 align="center">TEngine</h3>
<p align="center">
Unity框架解决方案
<br>
<a style="text-decoration:none">
<img src="https://img.shields.io/badge/Unity%20Ver-2019.4.12++-blue.svg?style=flat-square" alt="status" />
</a>
<a style="text-decoration:none">
<img src="https://img.shields.io/github/license/ALEXTANGXIAO/TEngine" alt="license" />
</a>
<a style="text-decoration:none">
<img src="https://img.shields.io/github/last-commit/ALEXTANGXIAO/TEngine" alt="last" />
</a>
<a style="text-decoration:none">
<img src="https://img.shields.io/github/issues/ALEXTANGXIAO/TEngine" alt="issue" />
</a>
<a style="text-decoration:none">
<img src="https://img.shields.io/github/languages/top/ALEXTANGXIAO/TEngine" alt="topLanguage" />
</a>
<a style="text-decoration:none">
<img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2FJasonXuDeveloper%2FJEngine.svg?type=shield" alt="status" />
</a>
<br>
<br>
<a href="http://1.12.241.46:5000/"><strong>框架文档 »</strong></a>
<br>
·
<br>
<a href="https://github.com/ALEXTANGXIAO/TEngine">框架首页 »</a>
</p>
# TEngine v1.0.0
TEngine
```Json
TEngine项目结构
Assets
├── TResources // TResources资源加载和打包目录
├── ConfigStruct // 生成的配置表结构体
├── TEngine // TEngine
└── Scripts // 脚本资源
com.tx.tengine
├── Tools~ // 常用工具
├── Config~ // 转表工具
├── FileServer~ // 基于Node.js热更服务器有条件用OSS
├── Runtime // TEngine 脚本资源
└── TEnginePackage~ // TEngine 差异化插件如UI、网络、热更等
com.tx.tengine/Runtime
├── ClientSaveData // 本地化储存
├── 3rd // 三方插件Json库、Protobuf
├── Config // Config配置表
├── Editor // Editor
├── Event // Event事件驱动系统
├── ECS // ECS架构
├── FileSystem // FileSystem
├── Json // Json库文件
├── Game // 核心逻辑
├── Unitity // Unitity工具类
├── Res // Res资源加载模块
└── Core // TEngine核心
├── BaseLogicSys // 基础系统模块依赖TEngine实现生命周期
├── MemPoolMgr // 内存缓存池
├── TEngineRedux // DVA/Redux
├── TSingleton // 单例以及单例管理器
└── TEngine // 主入口
可定制化模块
Assets/TEngine/Runtime/UI
├── Editor // 脚本从预制体自动生成UI代码
├── Extend // 转表工具
├── Res // 基于Node.js热更服务器有条件用OSS
//TODO
```

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 577d9725f58264943855b8ac185531fe
folderAsset: yes
timeCreated: 1466788344
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 14f21d7a1e53a8c4e87b25526a7eb63c
folderAsset: yes
timeCreated: 1466788345
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aadad8ac54f29e44583510294ac5c312
timeCreated: 1466788355
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
fileFormatVersion: 2
guid: 6a3c684705042f345975d924f6983e36
timeCreated: 1466788352
licenseType: Store
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
platformData:
Android:
enabled: 1
settings:
CPU: AnyCPU
Any:
enabled: 0
settings: {}
Editor:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
Linux:
enabled: 0
settings:
CPU: x86
Linux64:
enabled: 0
settings:
CPU: x86_64
OSXIntel:
enabled: 0
settings:
CPU: AnyCPU
OSXIntel64:
enabled: 0
settings:
CPU: AnyCPU
SamsungTV:
enabled: 1
settings:
STV_MODEL: STANDARD_13
Tizen:
enabled: 1
settings: {}
WebGL:
enabled: 1
settings: {}
Win:
enabled: 0
settings:
CPU: AnyCPU
Win64:
enabled: 0
settings:
CPU: AnyCPU
WindowsStoreApps:
enabled: 1
settings:
CPU: AnyCPU
DontProcess: False
PlaceholderPath: Assets/JsonDotNet/Assemblies/Standalone/Newtonsoft.Json.dll
SDK: AnySDK
ScriptingBackend: Il2Cpp
iOS:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
tvOS:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 01ef782d02bb1994dbe418b69432552b
folderAsset: yes
timeCreated: 1466788344
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d6807fedb8dcaf04682d2c84f0ab753f
timeCreated: 1466788355
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
fileFormatVersion: 2
guid: 17aef65a15b471f468b5fbeb4ff0c6a1
timeCreated: 1466788349
licenseType: Store
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
platformData:
Android:
enabled: 0
settings:
CPU: AnyCPU
Any:
enabled: 0
settings: {}
Editor:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
Linux:
enabled: 1
settings:
CPU: x86
Linux64:
enabled: 1
settings:
CPU: x86_64
LinuxUniversal:
enabled: 1
settings:
CPU: AnyCPU
OSXIntel:
enabled: 1
settings:
CPU: AnyCPU
OSXIntel64:
enabled: 1
settings:
CPU: AnyCPU
OSXUniversal:
enabled: 1
settings:
CPU: AnyCPU
SamsungTV:
enabled: 0
settings:
STV_MODEL: STANDARD_13
Win:
enabled: 1
settings:
CPU: AnyCPU
Win64:
enabled: 1
settings:
CPU: AnyCPU
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
DontProcess: False
PlaceholderPath:
SDK: AnySDK
ScriptingBackend: Il2Cpp
iOS:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1418141139a6ac443b18cb05c0643a29
folderAsset: yes
timeCreated: 1466788345
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 36f7323c55864364d8bb88c736e4bca6
timeCreated: 1466788355
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
fileFormatVersion: 2
guid: 9b6ba260dada0ea4a871a42011f8b87d
timeCreated: 1466788355
licenseType: Store
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
platformData:
Android:
enabled: 0
settings:
CPU: AnyCPU
Any:
enabled: 0
settings: {}
Editor:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
Linux:
enabled: 0
settings:
CPU: x86
Linux64:
enabled: 0
settings:
CPU: x86_64
OSXIntel:
enabled: 0
settings:
CPU: AnyCPU
OSXIntel64:
enabled: 0
settings:
CPU: AnyCPU
SamsungTV:
enabled: 0
settings:
STV_MODEL: STANDARD_13
Win:
enabled: 0
settings:
CPU: AnyCPU
Win64:
enabled: 0
settings:
CPU: AnyCPU
WindowsStoreApps:
enabled: 1
settings:
CPU: AnyCPU
DontProcess: False
PlaceholderPath: Assets/JsonDotNet/Assemblies/Standalone/Newtonsoft.Json.dll
SDK: AnySDK
ScriptingBackend: DotNet
iOS:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="System">
<type fullname="System.ComponentModel.TypeConverter" preserve="all" />
<!-- <namespace fullname="System.ComponentModel" preserve="all" /> -->
</assembly>
</linker>

View File

@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 06314f49bdda26043963578d60a0a7ee
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: fa22137905c778947a383e10c3a9e800
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
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,8 @@
fileFormatVersion: 2
guid: 2f6ee4c168f3e364ab85faf457f75038
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using System.Collections.Generic;
using LitJson;
using UnityEngine;
namespace TEngine
{
public abstract class BaseClientData
{
private string m_configName;
public void Init(string configName)
{
m_configName = configName;
Load();
}
public void Load()
{
string fullName = GetSaveUniqPrefix() + m_configName;
var jsonString = PlayerPrefs.GetString(fullName);
if (!string.IsNullOrEmpty(jsonString))
{
JsonData json = JsonHelper.Instance.Deserialize(jsonString);
if (json != null)
{
Deserialize(json);
}
}
}
public void Save()
{
string fullName = GetSaveUniqPrefix() + m_configName;
JsonData jsonData = new JsonData();
Serialize(jsonData);
var jsonTex = JsonHelper.Instance.Serialize(jsonData);
if (!string.IsNullOrEmpty(jsonTex))
{
PlayerPrefs.SetString(fullName, jsonTex);
PlayerPrefs.Save();
}
}
protected abstract void Serialize(JsonData json);
protected abstract void Deserialize(JsonData json);
private string GetSaveUniqPrefix()
{
string hashPath = UnityUtil.GetHashCodeByString(Application.dataPath).ToString();
string uniqInstance = SystemInfo.deviceUniqueIdentifier;
string uniqKey = hashPath + uniqInstance;
return uniqKey;
}
}
public class SystemSaveData: BaseClientData
{
public int[] settingParams;
public uint test;
public float m_cameraDistance;
public SystemSaveData()
{
settingParams = new int[(int)SystemSaveType.Max];
settingParams[(int) SystemSaveType.Lod] = 0;
}
public enum SystemSaveType
{
Lod, // 同屏人数
MusicOn, // 打开音乐
SoundOn, // 打开音效
Max,
}
protected override void Serialize(JsonData json)
{
if (json == null)
{
return;
}
}
protected override void Deserialize(JsonData json)
{
if (json == null)
{
return;
}
}
}
public class ClientSaveData : TSingleton<ClientSaveData>
{
private Dictionary<string, BaseClientData> m_dictSaveData = new Dictionary<string, BaseClientData>();
public T GetSaveData<T>() where T : BaseClientData, new()
{
string typeName = typeof(T).Name;
BaseClientData ret;
if (!m_dictSaveData.TryGetValue(typeName, out ret))
{
ret = new T();
ret.Init(typeName);
m_dictSaveData.Add(typeName, ret);
}
return (T)ret;
}
public void SaveAllData()
{
var enumerator = m_dictSaveData.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Value.Save();
}
}
public SystemSaveData CurrentSystemSaveData
{
get
{
return GetSaveData<SystemSaveData>();
}
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace TEngine
{
public class ResConfigUtil
{
private static StringBuilder m_strBuilder = new StringBuilder();
private static readonly string m_split = "_";
#region
public static List<T> ReadConfigListRes<T>(string fileName)
{
string resPath = string.Format("Config/{0}.json",fileName);
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
if (jsonStr == null)
{
TLogger.LogError("读取Json配置数据失败{0}", fileName);
return null;
}
List<T> list = new List<T>();
var jsonData = JsonHelper.Instance.Deserialize<List<T>>(jsonStr.text);
list = jsonData;
return list;
}
public static Dictionary<string, T> ReadConfigRes<T>(string fileName)
{
string resPath = string.Format("Config/{0}.json", fileName);
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
if (jsonStr == null)
{
TLogger.LogError("读取Json配置数据失败{0}", fileName);
return null;
}
Dictionary<string, T> dic = new Dictionary<string, T>();
var jsonData = JsonHelper.Instance.Deserialize<Dictionary<string, T>>(jsonStr.text);
dic = jsonData;
return dic;
}
public static Dictionary<int, T> ReadConfigResIntKey<T>(string fileName)
{
string resPath = string.Format("Config/{0}.json", fileName);
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
if (jsonStr == null)
{
TLogger.LogError("读取Json配置数据失败{0}", fileName);
return null;
}
Dictionary<int, T> dic = new Dictionary<int, T>();
var jsonData = JsonHelper.Instance.Deserialize<Dictionary<int, T>>(jsonStr.text);
dic = jsonData;
return dic;
}
#endregion
public static UInt64 Make64Key(uint key1, uint key2)
{
return (((UInt64)key1) << 32) | key2;
}
public static string MakeStringKey(uint key1, uint key2, uint key3)
{
m_strBuilder.Length = 0;
m_strBuilder.Append(key1);
m_strBuilder.Append(m_split);
m_strBuilder.Append(key2);
m_strBuilder.Append(m_split);
m_strBuilder.Append(key3);
return m_strBuilder.ToString();
}
public static string MakeStringKey(string key1, uint key2)
{
m_strBuilder.Length = 0;
m_strBuilder.Append(key1);
m_strBuilder.Append(m_split);
m_strBuilder.Append(key2);
return m_strBuilder.ToString();
}
public static string MakeStringKey(string key1, string key2)
{
m_strBuilder.Length = 0;
m_strBuilder.Append(key1);
m_strBuilder.Append(m_split);
m_strBuilder.Append(key2);
return m_strBuilder.ToString();
}
}
}
/*
*
===》 example 《===
public class BufferMgr : Singleton<BufferMgr>
{
private Dictionary<string, BuffConfig> m_dictBaseConfig = new Dictionary<string, BuffConfig>();
public BufferMgr()
{
m_dictBaseConfig = ResConfigUtil.ReadConfigRes<BuffConfig>("BuffConfig");
}
public Dictionary<string, BuffConfig> GetBuffConfig()
{
return m_dictBaseConfig;
}
}
*
*/

View File

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

View File

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

View File

@@ -0,0 +1,74 @@
namespace TEngine
{
/// <summary>
/// 基础LogicSys,生命周期由TEngine实现推荐给系统实现
/// 减少多余的Mono保持系统层面只有一个Update
/// 用TEngine的主Mono来驱动LogicSys的生命周期
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseLogicSys<T> : ILogicSys where T : new()
{
private static T m_Instance;
public static bool HasInstance
{
get { return m_Instance != null; }
}
public static T Instance
{
get
{
if (null == m_Instance)
{
m_Instance = new T();
}
return m_Instance;
}
}
#region virtual fucntion
public virtual bool OnInit()
{
if (null == m_Instance)
{
m_Instance = new T();
}
return true;
}
public virtual void OnStart()
{
}
public virtual void OnUpdate()
{
}
public virtual void OnLateUpdate()
{
}
public virtual void OnDestroy()
{
}
public virtual void OnPause()
{
}
public virtual void OnResume()
{
}
public virtual void OnDrawGizmos()
{
}
public virtual void OnMapChanged()
{
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,20 @@
namespace TEngine
{
public interface ILogicSys
{
bool OnInit();
void OnDestroy();
void OnStart();
void OnUpdate();
void OnLateUpdate();
void OnPause();
void OnResume();
}
}

View File

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

View File

@@ -0,0 +1,90 @@
using System.Collections.Generic;
using UnityEngine.Events;
namespace TEngine
{
public static class ListPool<T>
{
private static readonly ObjectPool<List<T>> m_ListPool = new ObjectPool<List<T>>(null, Clear);
static void Clear(List<T> list)
{
list.Clear();
}
public static List<T> Get()
{
return m_ListPool.Get();
}
public static void Release(List<T> toRelease)
{
m_ListPool.Release(toRelease);
}
}
public class ObjectPool<T> where T : new()
{
private readonly Stack<T> m_Stack = new Stack<T>();
private readonly UnityAction<T> m_ActionGet;
private readonly UnityAction<T> m_ActionRelease;
public int CountAll { get; private set; }
public int CountActive
{
get
{
return CountAll - CountInActive;
}
}
public int CountInActive
{
get
{
return m_Stack.Count;
}
}
public ObjectPool()
{
}
public ObjectPool(UnityAction<T> actionGet, UnityAction<T> actionRelease)
{
m_ActionGet = actionGet;
m_ActionRelease = actionRelease;
}
public T Get()
{
T element;
if (m_Stack.Count <= 0)
{
element = new T();
CountAll++;
}
else
{
element = m_Stack.Pop();
}
if (m_ActionGet != null)
{
m_ActionGet.Invoke(element);
}
return element;
}
public void Release(T element)
{
if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element))
{
TLogger.LogError("Internal error. Trying to destroy object that is already released to pool.");
}
m_ActionRelease?.Invoke(element);
m_Stack.Push(element);
}
}
}

View File

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

View File

@@ -0,0 +1,125 @@
using System.Collections.Generic;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
namespace TEngine
{
public interface IMemPoolObject
{
void Init();
void Destroy();
}
public interface MemPoolBase
{
string GetName();
int GetPoolItemCount();
void ClearPool();
}
public class MemPool
{
}
public class MemPoolMgr : TSingleton<MemPoolMgr>
{
List<MemPoolBase> m_listPool = new List<MemPoolBase>();
[Conditional("TEngine_DEBUG")]
public void ShowCount()
{
int totalCnt = 0;
for (int i = 0; i < m_listPool.Count; i++)
{
var pool = m_listPool[i];
totalCnt += pool.GetPoolItemCount();
TLogger.LogInfo("[pool][{0}] [{1}]", pool.GetName(), pool.GetPoolItemCount());
}
TLogger.LogInfo("-------------------------memory pool count: {0}", totalCnt);
}
public void RegMemPool(MemPoolBase pool)
{
m_listPool.Add(pool);
}
public void ClearAllPool()
{
for (int i = 0; i < m_listPool.Count; i++)
{
var pool = m_listPool[i];
pool.ClearPool();
}
}
}
public class GameMemPool<T> : TSingleton<GameMemPool<T>>, MemPoolBase where T : IMemPoolObject, new()
{
private List<T> m_objPool = new List<T>();
public static T Alloc()
{
return GameMemPool<T>.Instance.DoAlloc();
}
public static void Free(T obj)
{
GameMemPool<T>.Instance.DoFree(obj);
}
public GameMemPool()
{
MemPoolMgr.Instance.RegMemPool(this);
}
private T DoAlloc()
{
T newObj;
if (m_objPool.Count > 0)
{
var lastIndex = m_objPool.Count - 1;
newObj = m_objPool[lastIndex];
m_objPool.RemoveAt(lastIndex);
}
else
{
newObj = new T();
}
newObj.Init();
return newObj;
}
private void DoFree(T obj)
{
if (obj == null)
{
return;
}
obj.Destroy();
m_objPool.Add(obj);
}
public void ClearPool()
{
#if UNITY_EDITOR
TLogger.LogInfo("clear memory[{0}] count[{1}]", GetName(), m_objPool.Count);
#endif
m_objPool.Clear();
}
public string GetName()
{
return typeof(T).FullName;
}
public int GetPoolItemCount()
{
return m_objPool.Count;
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
namespace TEngine
{
/// <summary>
/// 通用单例,无需释放和销毁
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> where T : new()
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = new T();
}
return _instance;
}
}
public static T Active()
{
return Instance;
}
}
}

View File

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

View File

@@ -0,0 +1,149 @@
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
/// <summary>
/// 游戏入口派生TEngine实现进入游戏虚函数(override StartGame)
/// </summary>
public class TEngine : UnitySingleton<TEngine>
{
public override void Awake()
{
base.Awake();
TLogger.LogInfo($"DevicePerformanceLevel 设备性能评级:{DevicePerformanceUtil.GetDevicePerformanceLevel()}");
InitLibImp();
RegisterAllSystem();
AfterAwake();
}
/// <summary>
/// 注册实现库
/// </summary>
protected virtual void InitLibImp()
{
}
/// <summary>
/// 注册系统例如BaseLogic/TEngineObject/MonoManger
/// </summary>
protected virtual void RegisterAllSystem()
{
}
protected void SetTargetFrameRate(int targetFrameRate)
{
Application.targetFrameRate = targetFrameRate;
}
//-------------------------------------------------------系统注册--------------------------------------------------------//
private List<ILogicSys> m_LogicMgrList = new List<ILogicSys>();
/// <summary>
/// 系统注册
/// </summary>
/// <param name="logicSys"></param>
/// <returns></returns>
protected bool AddLogicSys(ILogicSys logicSys)
{
if (m_LogicMgrList.Contains(logicSys))
{
TLogger.LogInfo("Repeat add logic system: " + logicSys.GetType().Name);
return false;
}
if (!logicSys.OnInit())
{
TLogger.LogInfo(" Init failed " + logicSys.GetType().Name);
return false;
}
m_LogicMgrList.Add(logicSys);
return true;
}
#region
public void Start()
{
var listLogic = m_LogicMgrList;
var logicCnt = listLogic.Count;
for (int i = 0; i < logicCnt; i++)
{
var logic = listLogic[i];
logic.OnStart();
}
TLogger.LogInfo("TEngine:StartGame");
StartGame();
}
public void Update()
{
var listLogic = m_LogicMgrList;
var logicCnt = listLogic.Count;
for (int i = 0; i < logicCnt; i++)
{
var logic = listLogic[i];
logic.OnUpdate();
}
}
public void LateUpdate()
{
var listLogic = m_LogicMgrList;
var logicCnt = listLogic.Count;
for (int i = 0; i < logicCnt; i++)
{
var logic = listLogic[i];
logic.OnLateUpdate();
}
}
public void OnPause()
{
for (int i = 0; i < m_LogicMgrList.Count; i++)
{
var logicSys = m_LogicMgrList[i];
logicSys.OnPause();
}
}
public void OnResume()
{
for (int i = 0; i < m_LogicMgrList.Count; i++)
{
var logicSys = m_LogicMgrList[i];
logicSys.OnResume();
}
}
protected override void OnDestroy()
{
for (int i = 0; i < m_LogicMgrList.Count; i++)
{
var logicSys = m_LogicMgrList[i];
logicSys.OnDestroy();
}
base.OnDestroy();
SingletonMgr.Release();
}
protected virtual void AfterAwake()
{
}
protected virtual void StartGame()
{
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,880 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
#region Architecture
public interface IArchitecture
{
void RegisterSystem<T>(T system) where T : ISystem;
void RegisterModel<T>(T model) where T : IModel;
void RegisterUtility<T>(T utility) where T : IUtility;
T GetSystem<T>() where T : class, ISystem;
T GetModel<T>() where T : class, IModel;
T GetUtility<T>() where T : class, IUtility;
void SendCommand<T>() where T : ICommand, new();
void SendCommand<T>(T command) where T : ICommand;
TResult SendQuery<TResult>(IQuery<TResult> query);
void SendEvent<T>() where T : new();
void SendEvent<T>(T e);
IUnRegister RegisterEvent<T>(Action<T> onEvent);
void UnRegisterEvent<T>(Action<T> onEvent);
}
public abstract class Architecture<T> : IArchitecture where T : Architecture<T>, new()
{
private bool _Inited = false;
private List<ISystem> _Systems = new List<ISystem>();
private List<IModel> _Models = new List<IModel>();
public static Action<T> OnRegisterPatch = architecture => { };
private static T _Architecture;
public static IArchitecture Interface
{
get
{
if (_Architecture == null)
{
MakeSureArchitecture();
}
return _Architecture;
}
}
static void MakeSureArchitecture()
{
if (_Architecture == null)
{
_Architecture = new T();
_Architecture.Init();
OnRegisterPatch?.Invoke(_Architecture);
foreach (var architectureModel in _Architecture._Models)
{
architectureModel.Init();
}
_Architecture._Models.Clear();
foreach (var architectureSystem in _Architecture._Systems)
{
architectureSystem.Init();
}
_Architecture._Systems.Clear();
_Architecture._Inited = true;
}
}
protected abstract void Init();
private TEngineContainer mContainer = new TEngineContainer();
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
{
system.SetArchitecture(this);
mContainer.Register<TSystem>(system);
if (!_Inited)
{
_Systems.Add(system);
}
else
{
system.Init();
}
}
public void RegisterModel<TModel>(TModel model) where TModel : IModel
{
model.SetArchitecture(this);
mContainer.Register<TModel>(model);
if (!_Inited)
{
_Models.Add(model);
}
else
{
model.Init();
}
}
public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
{
mContainer.Register<TUtility>(utility);
}
public TSystem GetSystem<TSystem>() where TSystem : class, ISystem
{
return mContainer.Get<TSystem>();
}
public TModel GetModel<TModel>() where TModel : class, IModel
{
return mContainer.Get<TModel>();
}
public TUtility GetUtility<TUtility>() where TUtility : class, IUtility
{
return mContainer.Get<TUtility>();
}
public void SendCommand<TCommand>() where TCommand : ICommand, new()
{
var command = new TCommand();
command.SetArchitecture(this);
command.Execute();
}
public void SendCommand<TCommand>(TCommand command) where TCommand : ICommand
{
command.SetArchitecture(this);
command.Execute();
}
public TResult SendQuery<TResult>(IQuery<TResult> query)
{
query.SetArchitecture(this);
return query.Do();
}
private TypeEventSystem mTypeEventSystem = new TypeEventSystem();
public void SendEvent<TEvent>() where TEvent : new()
{
mTypeEventSystem.Send<TEvent>();
}
public void SendEvent<TEvent>(TEvent e)
{
mTypeEventSystem.Send<TEvent>(e);
}
public IUnRegister RegisterEvent<TEvent>(Action<TEvent> onEvent)
{
return mTypeEventSystem.Register<TEvent>(onEvent);
}
public void UnRegisterEvent<TEvent>(Action<TEvent> onEvent)
{
mTypeEventSystem.UnRegister<TEvent>(onEvent);
}
}
public interface IOnEvent<T>
{
void OnEvent(T e);
}
public static class OnGlobalEventExtension
{
public static IUnRegister RegisterEvent<T>(this IOnEvent<T> self) where T : struct
{
return TypeEventSystem.Global.Register<T>(self.OnEvent);
}
public static void UnRegisterEvent<T>(this IOnEvent<T> self) where T : struct
{
TypeEventSystem.Global.UnRegister<T>(self.OnEvent);
}
}
#endregion
#region Controller
public interface IController : IBelongToArchitecture, ICanSendCommand, ICanGetSystem, ICanGetModel,
ICanRegisterEvent, ICanSendQuery
{
}
#endregion
#region System
public interface ISystem : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetUtility,
ICanRegisterEvent, ICanSendEvent, ICanGetSystem
{
void Init();
}
public abstract class AbstractSystem : ISystem
{
private IArchitecture _Architecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return _Architecture;
}
void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
_Architecture = architecture;
}
void ISystem.Init()
{
OnInit();
}
protected abstract void OnInit();
}
#endregion
#region Model
public interface IModel : IBelongToArchitecture, ICanSetArchitecture, ICanGetUtility, ICanSendEvent
{
void Init();
}
public abstract class AbstractModel : IModel
{
private IArchitecture _Architecturel;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return _Architecturel;
}
void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
_Architecturel = architecture;
}
void IModel.Init()
{
OnInit();
}
protected abstract void OnInit();
}
#endregion
#region Utility
public interface IUtility
{
}
#endregion
#region Command
public interface ICommand : IBelongToArchitecture, ICanSetArchitecture, ICanGetSystem, ICanGetModel, ICanGetUtility,
ICanSendEvent, ICanSendCommand, ICanSendQuery
{
void Execute();
}
public abstract class AbstractCommand : ICommand
{
private IArchitecture _Architecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return _Architecture;
}
void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
_Architecture = architecture;
}
void ICommand.Execute()
{
OnExecute();
}
protected abstract void OnExecute();
}
#endregion
#region Query
public interface IQuery<TResult> : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetSystem,
ICanSendQuery
{
TResult Do();
}
public abstract class AbstractQuery<T> : IQuery<T>
{
public T Do()
{
return OnDo();
}
protected abstract T OnDo();
private IArchitecture _Architecture;
public IArchitecture GetArchitecture()
{
return _Architecture;
}
public void SetArchitecture(IArchitecture architecture)
{
_Architecture = architecture;
}
}
#endregion
#region Rule
public interface IBelongToArchitecture
{
IArchitecture GetArchitecture();
}
public interface ICanSetArchitecture
{
void SetArchitecture(IArchitecture architecture);
}
public interface ICanGetModel : IBelongToArchitecture
{
}
public static class CanGetModelExtension
{
public static T GetModel<T>(this ICanGetModel self) where T : class, IModel
{
return self.GetArchitecture().GetModel<T>();
}
}
public interface ICanGetSystem : IBelongToArchitecture
{
}
public static class CanGetSystemExtension
{
public static T GetSystem<T>(this ICanGetSystem self) where T : class, ISystem
{
return self.GetArchitecture().GetSystem<T>();
}
}
public interface ICanGetUtility : IBelongToArchitecture
{
}
public static class CanGetUtilityExtension
{
public static T GetUtility<T>(this ICanGetUtility self) where T : class, IUtility
{
return self.GetArchitecture().GetUtility<T>();
}
}
public interface ICanRegisterEvent : IBelongToArchitecture
{
}
public static class CanRegisterEventExtension
{
public static IUnRegister RegisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent)
{
return self.GetArchitecture().RegisterEvent<T>(onEvent);
}
public static void UnRegisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent)
{
self.GetArchitecture().UnRegisterEvent<T>(onEvent);
}
}
public interface ICanSendCommand : IBelongToArchitecture
{
}
public static class CanSendCommandExtension
{
public static void SendCommand<T>(this ICanSendCommand self) where T : ICommand, new()
{
self.GetArchitecture().SendCommand<T>();
}
public static void SendCommand<T>(this ICanSendCommand self, T command) where T : ICommand
{
self.GetArchitecture().SendCommand<T>(command);
}
}
public interface ICanSendEvent : IBelongToArchitecture
{
}
public static class CanSendEventExtension
{
public static void SendEvent<T>(this ICanSendEvent self) where T : new()
{
self.GetArchitecture().SendEvent<T>();
}
public static void SendEvent<T>(this ICanSendEvent self, T e)
{
self.GetArchitecture().SendEvent<T>(e);
}
}
public interface ICanSendQuery : IBelongToArchitecture
{
}
public static class CanSendQueryExtension
{
public static TResult SendQuery<TResult>(this ICanSendQuery self, IQuery<TResult> query)
{
return self.GetArchitecture().SendQuery(query);
}
}
#endregion
#region TypeEventSystem
public interface IUnRegister
{
void UnRegister();
}
public interface IUnRegisterList
{
List<IUnRegister> UnregisterList { get; }
}
public static class IUnRegisterListExtension
{
public static void AddToUnregisterList(this IUnRegister self, IUnRegisterList unRegisterList)
{
unRegisterList.UnregisterList.Add(self);
}
public static void UnRegisterAll(this IUnRegisterList self)
{
foreach (var unRegister in self.UnregisterList)
{
unRegister.UnRegister();
}
self.UnregisterList.Clear();
}
}
/// <summary>
/// 自定义可注销的类
/// </summary>
public struct CustomUnRegister : IUnRegister
{
/// <summary>
/// 委托对象
/// </summary>
private Action mOnUnRegister { get; set; }
/// <summary>
/// 带参构造函数
/// </summary>
/// <param name="onDispose"></param>
public CustomUnRegister(Action onUnRegsiter)
{
mOnUnRegister = onUnRegsiter;
}
/// <summary>
/// 资源释放
/// </summary>
public void UnRegister()
{
mOnUnRegister.Invoke();
mOnUnRegister = null;
}
}
public class UnRegisterOnDestroyTrigger : MonoBehaviour
{
private readonly HashSet<IUnRegister> mUnRegisters = new HashSet<IUnRegister>();
public void AddUnRegister(IUnRegister unRegister)
{
mUnRegisters.Add(unRegister);
}
public void RemoveUnRegister(IUnRegister unRegister)
{
mUnRegisters.Remove(unRegister);
}
private void OnDestroy()
{
foreach (var unRegister in mUnRegisters)
{
unRegister.UnRegister();
}
mUnRegisters.Clear();
}
}
public static class UnRegisterExtension
{
public static IUnRegister UnRegisterWhenGameObjectDestroyed(this IUnRegister unRegister, GameObject gameObject)
{
var trigger = gameObject.GetComponent<UnRegisterOnDestroyTrigger>();
if (!trigger)
{
trigger = gameObject.AddComponent<UnRegisterOnDestroyTrigger>();
}
trigger.AddUnRegister(unRegister);
return unRegister;
}
}
public class TypeEventSystem
{
private readonly EasyEvents mEvents = new EasyEvents();
public static readonly TypeEventSystem Global = new TypeEventSystem();
public void Send<T>() where T : new()
{
mEvents.GetEvent<EasyEvent<T>>()?.Trigger(new T());
}
public void Send<T>(T e)
{
mEvents.GetEvent<EasyEvent<T>>()?.Trigger(e);
}
public IUnRegister Register<T>(Action<T> onEvent)
{
var e = mEvents.GetOrAddEvent<EasyEvent<T>>();
return e.Register(onEvent);
}
public void UnRegister<T>(Action<T> onEvent)
{
var e = mEvents.GetEvent<EasyEvent<T>>();
if (e != null)
{
e.UnRegister(onEvent);
}
}
}
#endregion
#region TEngine
public class TEngineContainer
{
private Dictionary<Type, object> _Instances = new Dictionary<Type, object>();
public void Register<T>(T instance)
{
var key = typeof(T);
if (_Instances.ContainsKey(key))
{
_Instances[key] = instance;
}
else
{
_Instances.Add(key, instance);
}
}
public T Get<T>() where T : class
{
var key = typeof(T);
if (_Instances.TryGetValue(key, out var retInstance))
{
return retInstance as T;
}
return null;
}
}
#endregion
#region BindableProperty
public interface IBindableProperty<T> : IReadonlyBindableProperty<T>
{
new T Value { get; set; }
void SetValueWithoutEvent(T newValue);
}
public interface IReadonlyBindableProperty<T>
{
T Value { get; }
IUnRegister RegisterWithInitValue(Action<T> action);
void UnRegister(Action<T> onValueChanged);
IUnRegister Register(Action<T> onValueChanged);
}
public class BindableProperty<T> : IBindableProperty<T>
{
public BindableProperty(T defaultValue = default)
{
mValue = defaultValue;
}
protected T mValue;
public T Value
{
get => GetValue();
set
{
if (value == null && mValue == null) return;
if (value != null && value.Equals(mValue)) return;
SetValue(value);
mOnValueChanged?.Invoke(value);
}
}
protected virtual void SetValue(T newValue)
{
mValue = newValue;
}
protected virtual T GetValue()
{
return mValue;
}
public void SetValueWithoutEvent(T newValue)
{
mValue = newValue;
}
private Action<T> mOnValueChanged = (v) => { };
public IUnRegister Register(Action<T> onValueChanged)
{
mOnValueChanged += onValueChanged;
return new BindablePropertyUnRegister<T>()
{
BindableProperty = this,
OnValueChanged = onValueChanged
};
}
public IUnRegister RegisterWithInitValue(Action<T> onValueChanged)
{
onValueChanged(mValue);
return Register(onValueChanged);
}
public static implicit operator T(BindableProperty<T> property)
{
return property.Value;
}
public override string ToString()
{
return Value.ToString();
}
public void UnRegister(Action<T> onValueChanged)
{
mOnValueChanged -= onValueChanged;
}
}
public class BindablePropertyUnRegister<T> : IUnRegister
{
public BindableProperty<T> BindableProperty { get; set; }
public Action<T> OnValueChanged { get; set; }
public void UnRegister()
{
BindableProperty.UnRegister(OnValueChanged);
BindableProperty = null;
OnValueChanged = null;
}
}
#endregion
#region EasyEvent
public interface IEasyEvent
{
}
public class EasyEvent : IEasyEvent
{
private Action mOnEvent = () => { };
public IUnRegister Register(Action onEvent)
{
mOnEvent += onEvent;
return new CustomUnRegister(() => { UnRegister(onEvent); });
}
public void UnRegister(Action onEvent)
{
mOnEvent -= onEvent;
}
public void Trigger()
{
mOnEvent?.Invoke();
}
}
public class EasyEvent<T> : IEasyEvent
{
private Action<T> mOnEvent = e => { };
public IUnRegister Register(Action<T> onEvent)
{
mOnEvent += onEvent;
return new CustomUnRegister(() => { UnRegister(onEvent); });
}
public void UnRegister(Action<T> onEvent)
{
mOnEvent -= onEvent;
}
public void Trigger(T t)
{
mOnEvent?.Invoke(t);
}
}
public class EasyEvent<T, K> : IEasyEvent
{
private Action<T, K> mOnEvent = (t, k) => { };
public IUnRegister Register(Action<T, K> onEvent)
{
mOnEvent += onEvent;
return new CustomUnRegister(() => { UnRegister(onEvent); });
}
public void UnRegister(Action<T, K> onEvent)
{
mOnEvent -= onEvent;
}
public void Trigger(T t, K k)
{
mOnEvent?.Invoke(t, k);
}
}
public class EasyEvent<T, K, S> : IEasyEvent
{
private Action<T, K, S> mOnEvent = (t, k, s) => { };
public IUnRegister Register(Action<T, K, S> onEvent)
{
mOnEvent += onEvent;
return new CustomUnRegister(() => { UnRegister(onEvent); });
}
public void UnRegister(Action<T, K, S> onEvent)
{
mOnEvent -= onEvent;
}
public void Trigger(T t, K k, S s)
{
mOnEvent?.Invoke(t, k, s);
}
}
public class EasyEvents
{
private static EasyEvents mGlobalEvents = new EasyEvents();
public static T Get<T>() where T : IEasyEvent
{
return mGlobalEvents.GetEvent<T>();
}
public static void Register<T>() where T : IEasyEvent, new()
{
mGlobalEvents.AddEvent<T>();
}
private Dictionary<Type, IEasyEvent> mTypeEvents = new Dictionary<Type, IEasyEvent>();
public void AddEvent<T>() where T : IEasyEvent, new()
{
mTypeEvents.Add(typeof(T), new T());
}
public T GetEvent<T>() where T : IEasyEvent
{
IEasyEvent e;
if (mTypeEvents.TryGetValue(typeof(T), out e))
{
return (T)e;
}
return default;
}
public T GetOrAddEvent<T>() where T : IEasyEvent, new()
{
var eType = typeof(T);
if (mTypeEvents.TryGetValue(eType, out var e))
{
return (T)e;
}
var t = new T();
mTypeEvents.Add(eType, t);
return t;
}
}
#endregion
}

View File

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

View File

@@ -0,0 +1,341 @@
using System.Diagnostics;
using System.Text;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace TEngine
{
public static class ColorUtils
{
#region ColorStr
public const string White = "FFFFFF";
public const string Black = "000000";
public const string Red = "FF0000";
public const string Green = "00FF18";
public const string Oringe = "FF9400";
public const string Exception = "FF00BD";
#endregion
public static string ToColor(this string str, string color)
{
if (string.IsNullOrEmpty(str))
{
return str;
}
return string.Format("<color=#{0}>{1}</color>", color, str);
}
}
public class TLogger : TSingleton<TLogger>
{
protected override void Init()
{
_outputType = OutputType.EDITOR;
_logToFile = new LogToFile();
_logToFile.Init();
UnityEngine.Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;
}
private LogToFile _logToFile;
private void OnLogMessageReceivedThreaded(string condition, string stackTrace, LogType type)
{
if (!condition.StartsWith("TLogger]"))
{
_stringBuilder.Clear();
_stringBuilder.AppendFormat("[System][{0}][{1}] {2}", type.ToString(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), condition);
if (type == LogType.Warning || type == LogType.Error || type == LogType.Exception)
{
_stringBuilder.AppendLine(stackTrace);
}
string strToWrite = _stringBuilder.ToString();
_logToFile.Write(strToWrite);
}
}
~TLogger()
{
}
public override void Release()
{
Application.logMessageReceivedThreaded -= OnLogMessageReceivedThreaded;
_logToFile.DeInit();
_logToFile = null;
base.Release();
}
private void ChangeOutputChannel(OutputType type)
{
if (type != _outputType)
{
_outputType = type;
}
}
public static void SetFilterLevel(LogLevel filterLevel)
{
Instance._filterLevel = filterLevel;
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_ASSERT")]
public static void LogAssert(bool condition, string logStr)
{
if (!condition)
Instance.Log(LogLevel.ASSERT, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_ASSERT")]
public static void LogAssert(bool condition, string format, params System.Object[] args)
{
if (!condition)
{
string logStr = string.Format(format, args);
Instance.Log(LogLevel.ASSERT, logStr);
}
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_INFO")]
public static void LogInfo(string logStr)
{
Instance.Log(LogLevel.INFO, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_INFO")]
public static void LogInfo(string format, params System.Object[] args)
{
string logStr = string.Format(format, args);
Instance.Log(LogLevel.INFO, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_SUCCESS")]
public static void LogInfoSuccessd(string logStr)
{
Instance.Log(LogLevel.Successd, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_SUCCESS")]
public static void LogInfoSuccessd(string format, params System.Object[] args)
{
string logStr = string.Format(format, args);
Instance.Log(LogLevel.Successd, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_WARNING")]
public static void LogWarning(string logStr)
{
Instance.Log(LogLevel.WARNING, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_WARNING")]
public static void LogWarning(string format, params System.Object[] args)
{
string logStr = string.Format(format, args);
Instance.Log(LogLevel.WARNING, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_ERROR")]
public static void LogError(string logStr)
{
Instance.Log(LogLevel.ERROR, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_ERROR")]
public static void LogError(string format, params System.Object[] args)
{
string logStr = string.Format(format, args);
Instance.Log(LogLevel.ERROR, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_EXCEPTION")]
public static void LogException(string logStr)
{
Instance.Log(LogLevel.EXCEPTION, logStr);
}
[Conditional("UNITY_EDITOR"), Conditional("_DEVELOPMENT_BUILD_"), Conditional("ENABLE_LOG_EXCEPTION")]
public static void LogException(string format, params System.Object[] args)
{
string msg = string.Format(format, args);
Instance.Log(LogLevel.EXCEPTION, msg);
}
private StringBuilder GetFormatedString(LogLevel logLevel, string logString, bool bColor)
{
_stringBuilder.Clear();
switch (logLevel)
{
case LogLevel.Successd:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[TLogger][SUCCESSED][{0}] - <color=#{2}>{1}</color>",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString, ColorUtils.Green);
}
else
{
_stringBuilder.AppendFormat(
bColor ? "[TLogger][INFO][{0}] - <color=gray>{1}</color>" : "[TLogger][SUCCESSED][{0}] - {1}",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString);
}
break;
case LogLevel.INFO:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[TLogger][INFO][{0}] - <color=#{2}>{1}</color>" ,
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString,ColorUtils.Black);
}
else
{
_stringBuilder.AppendFormat(
bColor ? "[TLogger][INFO][{0}] - <color=gray>{1}</color>" : "[TLogger][INFO][{0}] - {1}",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString);
}
break;
case LogLevel.ASSERT:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[TLogger][ASSERT][{0}] - <color=#{2}>{1}</color>",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString,ColorUtils.Exception);
}
else
{
_stringBuilder.AppendFormat(
bColor ? "[TLogger][ASSERT][{0}] - <color=green>{1}</color>" : "[TLogger][ASSERT][{0}] - {1}",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString);
}
break;
case LogLevel.WARNING:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[TLogger][WARNING][{0}] - <color=#{2}>{1}</color>",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString, ColorUtils.Oringe);
}
else
{
_stringBuilder.AppendFormat(
bColor
? "[TLogger][WARNING][{0}] - <color=yellow>{1}</color>"
: "[TLogger][WARNING][{0}] - {1}", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"),
logString);
}
break;
case LogLevel.ERROR:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[ERROR][WARNING][{0}] - <color=#{2}>{1}</color>",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString, ColorUtils.Red);
}
else
{
_stringBuilder.AppendFormat(
bColor ? "[TLogger][ERROR][{0}] - <color=red>{1}</color>" : "[TLogger][ERROR][{0}] - {1}",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString);
}
break;
case LogLevel.EXCEPTION:
if (UseCustomColor)
{
_stringBuilder.AppendFormat("[ERROR][EXCEPTION][{0}] - <color=#{2}>{1}</color>",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString, ColorUtils.Exception);
}
else
{
_stringBuilder.AppendFormat(
bColor
? "[TLogger][EXCEPTION][{0}] - <color=red>{1}</color>"
: "[TLogger][EXCEPTION][{0}] - {1}",
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logString);
}
break;
}
return _stringBuilder;
}
private void Log(LogLevel type, string logString)
{
if (_outputType == OutputType.NONE)
{
return;
}
if (type < _filterLevel)
{
return;
}
StringBuilder infoBuilder = GetFormatedString(type, logString, UseSystemColor);
string logStr = infoBuilder.ToString();
//获取C#堆栈,Warning以上级别日志才获取堆栈
if (type == LogLevel.ERROR || type == LogLevel.WARNING || type == LogLevel.EXCEPTION)
{
StackFrame[] sf = new StackTrace().GetFrames();
for (int i = 0; i < sf.Length; i++)
{
StackFrame frame = sf[i];
string declaringTypeName = frame.GetMethod().DeclaringType.FullName;
string methodName = sf[i].GetMethod().Name;
infoBuilder.AppendFormat("[{0}::{1}\n", declaringTypeName, methodName);
}
}
if (type == LogLevel.INFO || type == LogLevel.Successd)
{
Debug.Log(logStr);
}
else if (type == LogLevel.WARNING)
{
Debug.LogWarning(logStr);
}
else if (type == LogLevel.ASSERT)
{
Debug.LogAssertion(logStr);
}
else if (type == LogLevel.ERROR)
{
Debug.LogError(logStr);
}
else if (type == LogLevel.EXCEPTION)
{
Debug.LogError(logStr);
}
}
#region Properties
public bool UseCustomColor = false;
public bool UseSystemColor = true;
public enum LogLevel
{
INFO,
Successd,
ASSERT,
WARNING,
ERROR,
EXCEPTION,
}
[System.Flags]
public enum OutputType
{
NONE = 0,
EDITOR = 0x1,
GUI = 0x2,
FILE = 0x4
}
private LogLevel _filterLevel = LogLevel.INFO;
private OutputType _outputType = OutputType.EDITOR;
private StringBuilder _stringBuilder = new StringBuilder();
#endregion
}
}

View File

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

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