This commit is contained in:
SepComet 2026-02-26 13:21:43 +08:00
parent a118803f1a
commit 4daefa17d5
1259 changed files with 290021 additions and 1 deletions

6
.gitignore vendored
View File

@ -81,7 +81,6 @@ InitTestScene*.unity*
# Addressables default ignores, before user customizations # Addressables default ignores, before user customizations
/ServerData /ServerData
/[Aa]ssets/StreamingAssets/aa*
/[Aa]ssets/AddressableAssetsData/link.xml* /[Aa]ssets/AddressableAssetsData/link.xml*
/[Aa]ssets/Addressables_Temp* /[Aa]ssets/Addressables_Temp*
# By default, Addressables content builds will generate addressables_content_state.bin # By default, Addressables content builds will generate addressables_content_state.bin
@ -97,3 +96,8 @@ InitTestScene*.unity*
# Auto-generated scenes by play mode tests # Auto-generated scenes by play mode tests
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity* /[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
/[Aa]ssets/StreamingAssets/
/数据表
/.vscode
AGENTS.md

15
.idea/.idea.GeometryTD/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# Rider 忽略的文件
/modules.xml
/.idea.GeometryTD.iml
/projectSettingsUpdater.xml
/contentModel.xml
# 已忽略包含查询文件的默认文件夹
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

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

View File

@ -0,0 +1,991 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &105264
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 447378}
- 114: {fileID: 11472694}
m_Layer: 0
m_Name: FSM
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &108464
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 432002}
- 114: {fileID: 11497722}
m_Layer: 0
m_Name: Resource
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &109252
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 472962}
- 114: {fileID: 11461470}
m_Layer: 0
m_Name: Localization
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &109548
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 472238}
- 114: {fileID: 11420954}
m_Layer: 0
m_Name: Download
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &110832
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 449550}
- 114: {fileID: 11494652}
m_Layer: 0
m_Name: Entity
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &116470
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 433714}
- 114: {fileID: 11499388}
- 114: {fileID: 11463816}
m_Layer: 0
m_Name: GameFramework
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &118246
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 429090}
- 114: {fileID: 11417814}
m_Layer: 0
m_Name: File System
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &119488
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 404872}
- 114: {fileID: 11402440}
m_Layer: 0
m_Name: Debugger
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &126534
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 450964}
- 114: {fileID: 11447244}
m_Layer: 0
m_Name: Web Request
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &132194
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 490662}
- 114: {fileID: 11459312}
m_Layer: 0
m_Name: Setting
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &137260
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 436184}
- 114: {fileID: 11485274}
m_Layer: 0
m_Name: Config
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &139170
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 407686}
- 114: {fileID: 11405216}
m_Layer: 0
m_Name: Procedure
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &140694
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 463618}
- 114: {fileID: 11413340}
m_Layer: 0
m_Name: Sound
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &151938
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 401796}
- 114: {fileID: 11457798}
m_Layer: 0
m_Name: Event
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &159784
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 431700}
- 114: {fileID: 11402158}
m_Layer: 0
m_Name: Object Pool
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &167768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 430602}
- 114: {fileID: 11454530}
m_Layer: 0
m_Name: UI
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &176370
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 486648}
- 114: {fileID: 11431030}
m_Layer: 0
m_Name: Network
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &178960
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 455962}
- 114: {fileID: 11447582}
m_Layer: 0
m_Name: Data Node
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &179612
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 465000}
- 114: {fileID: 11451924}
m_Layer: 0
m_Name: Data Table
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &180508
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 449996}
- 114: {fileID: 11418144}
m_Layer: 0
m_Name: Scene
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &189908
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 461836}
- 114: {fileID: 11461162}
m_Layer: 0
m_Name: Reference Pool
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &401796
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 151938}
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: 433714}
m_RootOrder: 6
--- !u!4 &404872
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 119488}
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: 433714}
m_RootOrder: 3
--- !u!4 &407686
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 139170}
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: 433714}
m_RootOrder: 12
--- !u!4 &429090
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 118246}
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: 433714}
m_RootOrder: 7
--- !u!4 &430602
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 167768}
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: 433714}
m_RootOrder: 18
--- !u!4 &431700
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 159784}
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: 433714}
m_RootOrder: 11
--- !u!4 &432002
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 108464}
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: 433714}
m_RootOrder: 14
--- !u!4 &433714
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 116470}
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:
- {fileID: 436184}
- {fileID: 455962}
- {fileID: 465000}
- {fileID: 404872}
- {fileID: 472238}
- {fileID: 449550}
- {fileID: 401796}
- {fileID: 429090}
- {fileID: 447378}
- {fileID: 472962}
- {fileID: 486648}
- {fileID: 431700}
- {fileID: 407686}
- {fileID: 461836}
- {fileID: 432002}
- {fileID: 449996}
- {fileID: 490662}
- {fileID: 463618}
- {fileID: 430602}
- {fileID: 450964}
m_Father: {fileID: 0}
m_RootOrder: 0
--- !u!4 &436184
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 137260}
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: 433714}
m_RootOrder: 0
--- !u!4 &447378
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105264}
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: 433714}
m_RootOrder: 8
--- !u!4 &449550
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 110832}
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: 433714}
m_RootOrder: 5
--- !u!4 &449996
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 180508}
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: 433714}
m_RootOrder: 15
--- !u!4 &450964
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 126534}
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: 433714}
m_RootOrder: 19
--- !u!4 &455962
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 178960}
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: 433714}
m_RootOrder: 1
--- !u!4 &461836
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 189908}
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: 433714}
m_RootOrder: 13
--- !u!4 &463618
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 140694}
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: 433714}
m_RootOrder: 17
--- !u!4 &465000
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 179612}
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: 433714}
m_RootOrder: 2
--- !u!4 &472238
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 109548}
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: 433714}
m_RootOrder: 4
--- !u!4 &472962
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 109252}
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: 433714}
m_RootOrder: 9
--- !u!4 &486648
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 176370}
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: 433714}
m_RootOrder: 10
--- !u!4 &490662
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 132194}
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: 433714}
m_RootOrder: 16
--- !u!114 &11402158
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 159784}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1e28a727443c86c40aeb42ff20e0a343, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11402440
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 119488}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f05eaceeebe870a4595e51f998ed518b, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Skin: {fileID: 0}
m_ActiveWindow: 0
m_ShowFullWindow: 0
m_ConsoleWindow:
m_LockScroll: 1
m_MaxLine: 100
m_InfoFilter: 1
m_WarningFilter: 1
m_ErrorFilter: 1
m_FatalFilter: 1
m_InfoColor:
serializedVersion: 2
rgba: 4294967295
m_WarningColor:
serializedVersion: 2
rgba: 4278512639
m_ErrorColor:
serializedVersion: 2
rgba: 4278190335
m_FatalColor:
serializedVersion: 2
rgba: 4281545650
--- !u!114 &11405216
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 139170}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 959bca2b68d03954897f38b1dbb00303, type: 3}
m_Name:
m_EditorClassIdentifier:
m_AvailableProcedureTypeNames: []
m_EntranceProcedureTypeName:
--- !u!114 &11413340
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 140694}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ed5533de69c4e5a4dabc7c23fce1fa98, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnablePlaySoundUpdateEvent: 0
m_EnablePlaySoundDependencyAssetEvent: 0
m_InstanceRoot: {fileID: 0}
m_AudioMixer: {fileID: 0}
m_SoundHelperTypeName: UnityGameFramework.Runtime.DefaultSoundHelper
m_CustomSoundHelper: {fileID: 0}
m_SoundGroupHelperTypeName: UnityGameFramework.Runtime.DefaultSoundGroupHelper
m_CustomSoundGroupHelper: {fileID: 0}
m_SoundAgentHelperTypeName: UnityGameFramework.Runtime.DefaultSoundAgentHelper
m_CustomSoundAgentHelper: {fileID: 0}
m_SoundGroups: []
--- !u!114 &11417814
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 118246}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fc49d78dad061a2418e134fc48856bc9, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FileSystemHelperTypeName: UnityGameFramework.Runtime.DefaultFileSystemHelper
m_CustomFileSystemHelper: {fileID: 0}
--- !u!114 &11418144
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 180508}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b6242b052eb207b40b22e8fe77a315ba, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableLoadSceneUpdateEvent: 1
m_EnableLoadSceneDependencyAssetEvent: 1
--- !u!114 &11420954
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 109548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9259de0854ba2624aa59aca15c6af063, type: 3}
m_Name:
m_EditorClassIdentifier:
m_InstanceRoot: {fileID: 0}
m_DownloadAgentHelperTypeName: UnityGameFramework.Runtime.UnityWebRequestDownloadAgentHelper
m_CustomDownloadAgentHelper: {fileID: 0}
m_DownloadAgentHelperCount: 3
m_Timeout: 30
m_FlushSize: 1048576
--- !u!114 &11431030
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 176370}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7afc859893311c34a8d8c2c426ab192d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11447244
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 126534}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 02988897571ac8b49a59c1a50037bd88, type: 3}
m_Name:
m_EditorClassIdentifier:
m_InstanceRoot: {fileID: 0}
m_WebRequestAgentHelperTypeName: UnityGameFramework.Runtime.UnityWebRequestAgentHelper
m_CustomWebRequestAgentHelper: {fileID: 0}
m_WebRequestAgentHelperCount: 1
m_Timeout: 30
--- !u!114 &11447582
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 178960}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 67038fd9feefc894aa31ae3869a45b72, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11451924
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 179612}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 54066418ab853614483ea44b531049f0, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableLoadDataTableUpdateEvent: 0
m_EnableLoadDataTableDependencyAssetEvent: 0
m_DataTableHelperTypeName: UnityGameFramework.Runtime.DefaultDataTableHelper
m_CustomDataTableHelper: {fileID: 0}
m_CachedBytesSize: 0
--- !u!114 &11454530
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 167768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4a1ef15380caaed42b55022cadc93649, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableOpenUIFormSuccessEvent: 1
m_EnableOpenUIFormFailureEvent: 1
m_EnableOpenUIFormUpdateEvent: 0
m_EnableOpenUIFormDependencyAssetEvent: 0
m_EnableCloseUIFormCompleteEvent: 1
m_InstanceAutoReleaseInterval: 60
m_InstanceCapacity: 16
m_InstanceExpireTime: 60
m_InstancePriority: 0
m_InstanceRoot: {fileID: 0}
m_UIFormHelperTypeName: UnityGameFramework.Runtime.DefaultUIFormHelper
m_CustomUIFormHelper: {fileID: 0}
m_UIGroupHelperTypeName: UnityGameFramework.Runtime.DefaultUIGroupHelper
m_CustomUIGroupHelper: {fileID: 0}
m_UIGroups: []
--- !u!114 &11457798
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 151938}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d7daf8320a3d04046b4bbd7c47307914, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11459312
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 132194}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3c6e05d8d843cd94bb9aa026ed5dc517, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SettingHelperTypeName: UnityGameFramework.Runtime.DefaultSettingHelper
m_CustomSettingHelper: {fileID: 0}
--- !u!114 &11461162
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 189908}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8ae4d40d7e878bc498492dc9c410d071, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableStrictCheck: 0
--- !u!114 &11461470
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 109252}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 706e6317a59f61044b2805be79f6b284, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableLoadDictionaryUpdateEvent: 0
m_EnableLoadDictionaryDependencyAssetEvent: 0
m_LocalizationHelperTypeName: UnityGameFramework.Runtime.DefaultLocalizationHelper
m_CustomLocalizationHelper: {fileID: 0}
m_CachedBytesSize: 0
--- !u!114 &11463816
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 116470}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c26ec20b78ec32048bfb6c0ff875d8cd, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableCachedAssets: 1
m_LoadAssetCountPerFrame: 1
m_MinLoadAssetRandomDelaySeconds: 0
m_MaxLoadAssetRandomDelaySeconds: 0
--- !u!114 &11472694
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105264}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ac872c3ce4121bb46a74927b35780534, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11485274
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 137260}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3e847b2b3e22e9b4792ca7ea6e1714c6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableLoadConfigUpdateEvent: 0
m_EnableLoadConfigDependencyAssetEvent: 0
m_ConfigHelperTypeName: UnityGameFramework.Runtime.DefaultConfigHelper
m_CustomConfigHelper: {fileID: 0}
m_CachedBytesSize: 0
--- !u!114 &11494652
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 110832}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58aa63e99dabf9c4fb61a9ec4ac4d8ca, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EnableShowEntityUpdateEvent: 0
m_EnableShowEntityDependencyAssetEvent: 0
m_InstanceRoot: {fileID: 0}
m_EntityHelperTypeName: UnityGameFramework.Runtime.DefaultEntityHelper
m_CustomEntityHelper: {fileID: 0}
m_EntityGroupHelperTypeName: UnityGameFramework.Runtime.DefaultEntityGroupHelper
m_CustomEntityGroupHelper: {fileID: 0}
m_EntityGroups: []
--- !u!114 &11497722
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 108464}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7eff66e40586ec14d8a301d416f17f1e, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ResourceMode: 1
m_ReadWritePathType: 0
m_MinUnloadUnusedAssetsInterval: 60
m_MaxUnloadUnusedAssetsInterval: 300
m_AssetAutoReleaseInterval: 60
m_AssetCapacity: 64
m_AssetExpireTime: 60
m_AssetPriority: 10000
m_ResourceAutoReleaseInterval: 60
m_ResourceCapacity: 16
m_ResourceExpireTime: 60
m_ResourcePriority: 20000
m_UpdatePrefixUri:
m_GenerateReadWriteVersionListLength: 1048576
m_UpdateRetryCount: 3
m_InstanceRoot: {fileID: 0}
m_ResourceHelperTypeName: UnityGameFramework.Runtime.DefaultResourceHelper
m_CustomResourceHelper: {fileID: 0}
m_LoadResourceAgentHelperTypeName: UnityGameFramework.Runtime.DefaultLoadResourceAgentHelper
m_CustomLoadResourceAgentHelper: {fileID: 0}
m_LoadResourceAgentHelperCount: 3
--- !u!114 &11499388
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 116470}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f98acd7d3bd2bf54dadf9644f60e5cb9, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EditorResourceMode: 1
m_EditorLanguage: 0
m_TextHelperTypeName: UnityGameFramework.Runtime.DefaultTextHelper
m_VersionHelperTypeName: UnityGameFramework.Runtime.DefaultVersionHelper
m_LogHelperTypeName: UnityGameFramework.Runtime.DefaultLogHelper
m_CompressionHelperTypeName: UnityGameFramework.Runtime.DefaultCompressionHelper
m_JsonHelperTypeName: UnityGameFramework.Runtime.DefaultJsonHelper
m_FrameRate: 30
m_GameSpeed: 1
m_RunInBackground: 1
m_NeverSleep: 1
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 116470}
m_IsPrefabParent: 1

View File

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

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-2021 Jiang Yin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

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

View File

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

Binary file not shown.

View File

@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 535b3169b00c6744aaef208fc713a195
PluginImporter:
externalObjects: {}
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
platformData:
Any:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: bc9c7e2be608ffb4f900d02be002262e
PluginImporter:
externalObjects: {}
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
platformData:
Any:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<linker>
<assembly fullname="GameFramework" preserve="all" />
<assembly fullname="UnityGameFramework.Runtime" preserve="all" />
</linker>
<!--
Unity 2017.3(不含)以前的版本,请删除以上内容,并使用以下内容。
For versions before Unity 2017.3 (excluded), please delete the above contents and use the following contents.
<?xml version="1.0" encoding="UTF-8"?>
<linker>
<assembly fullname="GameFramework">
<namespace fullname="GameFramework" preserve="all" />
<namespace fullname="GameFramework.Config" preserve="all" />
<namespace fullname="GameFramework.DataNode" preserve="all" />
<namespace fullname="GameFramework.DataTable" preserve="all" />
<namespace fullname="GameFramework.Debugger" preserve="all" />
<namespace fullname="GameFramework.Download" preserve="all" />
<namespace fullname="GameFramework.Entity" preserve="all" />
<namespace fullname="GameFramework.Event" preserve="all" />
<namespace fullname="GameFramework.FileSystem" preserve="all" />
<namespace fullname="GameFramework.Fsm" preserve="all" />
<namespace fullname="GameFramework.Localization" preserve="all" />
<namespace fullname="GameFramework.Network" preserve="all" />
<namespace fullname="GameFramework.ObjectPool" preserve="all" />
<namespace fullname="GameFramework.Procedure" preserve="all" />
<namespace fullname="GameFramework.Resource" preserve="all" />
<namespace fullname="GameFramework.Scene" preserve="all" />
<namespace fullname="GameFramework.Setting" preserve="all" />
<namespace fullname="GameFramework.Sound" preserve="all" />
<namespace fullname="GameFramework.UI" preserve="all" />
<namespace fullname="GameFramework.WebRequest" preserve="all" />
</assembly>
<assembly fullname="Assembly-CSharp">
<namespace fullname="UnityGameFramework.Runtime" preserve="all" />
</assembly>
</linker>
-->

View File

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

View File

@ -0,0 +1,101 @@
## HOMEPAGE
- **English** - Coming soon.
- **简体中文** - [https://gameframework.cn/](https://gameframework.cn/)
- **QQ 讨论群** 216332935
---
![Game Framework](https://gameframework.cn/image/gameframework.png)
---
## Game Framework 简介
Game Framework 是一个基于 Unity 引擎的游戏框架,主要对游戏开发过程中常用模块进行了封装,很大程度地规范开发过程、加快开发速度并保证产品质量。
在最新的 Game Framework 版本中,包含以下 19 个内置模块,后续我们还将开发更多的扩展模块供开发者使用。
1. **全局配置 (Config)** - 存储一些全局的只读的游戏配置,如玩家初始速度、游戏初始音量等。
2. **数据结点 (Data Node)** - 将任意类型的数据以树状结构的形式进行保存,用于管理游戏运行时的各种数据。
3. **数据表 (Data Table)** - 可以将游戏数据以表格(如 Microsoft Excel的形式进行配置后使用此模块使用这些数据表。数据表的格式是可以自定义的。
4. **调试器 (Debugger)** - 当游戏在 Unity 编辑器中运行或者以 Development 方式发布运行时,将出现调试器窗口,便于查看运行时日志、调试信息等。用户还可以方便地将自己的功能注册到调试器窗口上并使用。
5. **下载 (Download)** - 提供下载文件的功能,支持断点续传,并可指定允许几个下载器进行同时下载。更新资源时会主动调用此模块。
6. **实体 (Entity)** - 我们将游戏场景中,动态创建的一切物体定义为实体。此模块提供管理实体和实体组的功能,如显示隐藏实体、挂接实体(如挂接武器、坐骑,或者抓起另一个实体)等。实体使用结束后可以不立刻销毁,从而等待下一次重新使用。
7. **事件 (Event)** - 游戏逻辑监听、抛出事件的机制。Game Framework 中的很多模块在完成操作后都会抛出内置事件,监听这些事件将大大解除游戏逻辑之间的耦合。用户也可以定义自己的游戏逻辑事件。
8. **文件系统 (File System)** - 虚拟文件系统使用类似磁盘的概念对零散文件进行集中管理,优化资源加载时产生的内存分配,甚至可以对资源进行局部片段加载,这些都将极大提升资源加载时的性能。
9. **有限状态机 (FSM)** - 提供创建、使用和销毁有限状态机的功能,一些适用于有限状态机机制的游戏逻辑,使用此模块将是一个不错的选择。
10. **本地化 (Localization)** - 提供本地化功能也就是我们平时所说的多语言。Game Framework 在本地化方面不但支持文本的本地化还支持任意资源的本地化比如游戏中释放烟花特效也可以做出几个多国语言的版本使得中文版里是“新年好”字样的特效而英文版里是“Happy New Year”字样的特效。
11. **网络 (Network)** - 提供使用 Socket 长连接的功能,当前我们支持 TCP 协议,同时兼容 IPv4 和 IPv6 两个版本。用户可以同时建立多个连接与多个服务器同时进行通信,比如除了连接常规的游戏服务器,还可以连接语音聊天服务器。如果想接入 ProtoBuf 之类的协议库,只要派生自 Packet 类并实现自己的消息包类即可使用。
12. **对象池 (Object Pool)** - 提供对象缓存池的功能,避免频繁地创建和销毁各种游戏对象,提高游戏性能。除了 Game Framework 自身使用了对象池,用户还可以很方便地创建和管理自己的对象池。
13. **流程 (Procedure)** - 是贯穿游戏运行时整个生命周期的有限状态机。通过流程,将不同的游戏状态进行解耦将是一个非常好的习惯。对于网络游戏,你可能需要如检查资源流程、更新资源流程、检查服务器列表流程、选择服务器流程、登录服务器流程、创建角色流程等流程,而对于单机游戏,你可能需要在游戏选择菜单流程和游戏实际玩法流程之间做切换。如果想增加流程,只要派生自 ProcedureBase 类并实现自己的流程类即可使用。
14. **资源 (Resource)** - 为了保证玩家的体验,我们不推荐再使用同步的方式加载资源,由于 Game Framework 自身使用了一套完整的异步加载资源体系因此只提供了异步加载资源的接口。不论简单的数据表、本地化字典还是复杂的实体、场景、界面我们都将使用异步加载。同时Game Framework 提供了默认的内存管理策略(当然,你也可以定义自己的内存管理策略)。多数情况下,在使用 GameObject 的过程中,你甚至可以不需要自行进行 Instantiate 或者是 Destroy 操作。
15. **场景 (Scene)** - 提供场景管理的功能,可以同时加载多个场景,也可以随时卸载任何一个场景,从而很容易地实现场景的分部加载。
16. **配置 (Setting)** - 以键值对的形式存储玩家数据,对 UnityEngine.PlayerPrefs 进行封装,也可以将这些数据直接存储在磁盘上。
17. **声音 (Sound)** - 提供管理声音和声音组的功能,用户可以自定义一个声音的音量、是 2D 声音还是 3D 声音,甚至是直接绑定到某个实体上跟随实体移动。
18. **界面 (UI)** - 提供管理界面和界面组的功能,如显示隐藏界面、激活界面、改变界面层级等。不论是 Unity 内置的 uGUI 还是其它类型的 UI 插件(如 NGUI只要派生自 UIFormLogic 类并实现自己的界面类即可使用。界面使用结束后可以不立刻销毁,从而等待下一次重新使用。
19. **Web 请求 (Web Request)** - 提供使用短连接的功能,可以用 Get 或者 Post 方法向服务器发送请求并获取响应数据,可指定允许几个 Web 请求器进行同时请求。
---
## INTRODUCTION
Game Framework is literally a game framework, based on Unity game engine. It encapsulates commonly used game modules during development, and, to a large degree, standardises the process, enhances the development speed and ensures the product quality.
Game Framework provides the following 19 builtin modules, and more will be developed later for game developers to use.
1. **Config** - saves some global read-only game configurations, such as the player's initial speed, the initial volume of the game, etc.
2. **Data Node** - saves arbitrary types of data within tree structures in order to manage various data during game runtime.
3. **Data Table** - is intended to invoke game data in the form of pre-configured tables (such as Microsoft Excel sheets). The format of the tables can be customised.
4. **Debugger** - displays a debugger window when the game runs in the Unity Editor or in a development build, to facilitate the viewing of runtime logs and debug messages. The user can register their own features to the debugger windows and use them conveniently.
5. **Download** - provides the ability to download files. The user is free to set how many downloaders could be used simultaneously.
6. **Entity** - provides the ability to manage entities and groups of entities, where an entity is defined as any dynamically created objects in the game scene. It shows or hides entities, attach one entity to another (such as weapons, horses or snatching up another entity). Entities could avoid being destroyed instantly after use, and hence be recycled for reuse.
7. **Event** - gives the mechanism for the game logic to fire or observe events. Many modules in the Game Framework fires events after operations, and observing these events will largely decouple game logic modules. The user can define his own game logic events, too.
8. **File System** - the virtual file system, based on the concept of disks, manages scattered files in a centralized way, optimizes memory allocation when resources are loaded, and can even load segments of resources. These will drastically enhance the performance of resource loading.
9. **FSM** - provides the ability to create, use and destroy finite state machines. Itd be a good choice to use this module for some state-machine-like game logic.
10. **Localization** - provides the ability to localise the game. Game Framework not only supports the localisation of texts, but also assets of all kinds. For example, a firework effect in the game can be localised as various versions, so that the player will see a "新年好" - like effect in the Chinese version, while "Happy New Year" - like in the English version.
11. **Network** - provides socket connections where TCP is currently supported and both IPv4 and IPv6 are valid. The user can establish several connections to different servers at the same time. For example, the user can connect to a normal game server, and another server for voice chat. The 'Packet' class is ready for inheritance and implemented if the user wants to take use of protocol libraries such as ProtoBuf.
12. **Object Pool** - provides the ability to cache objects in pools. It avoids frequent creation and destruction operations of game objects, and hence improves the game performance. Game Framework itself uses object pools, and the user could conveniently create and manage his own pools.
13. **Procedure** - is in fact an FSM of the whole lifecycle of the game. Itd be a very good habit to decouple different game states via procedures. For a network game, you probably need procedures of checking resources, updating resources, checking the server list, selecting a server, logging in a server and creating avatars. For a standalone game, you perhaps need to switch between procedures of the menu and the real gameplay. The user could add procedures by simply subclassing and implementing the 'ProcedureBase' class.
14. **Resource** - provides only asynchronous interfaces to load resources. We dont recommend synchronous approaches for better play experience, and Game Framework itself uses a complete system of asynchronous resource loading. We load everything asynchronously, including simple things like data tables and localisation texts, and complex things like entities, scenes and UIs. Meanwhile, Game Framework provides default strategies of memory management (and of course, you could define your own strategies). In most cases, you don't even need to call 'Instantiate' or 'Destroy' when using 'GameObject' instances.
15. **Scene** - provides features to manage scenes. It supports simultaneous loading of multiple scenes, and the user is allowed to unload a scene at any time. Therefore partial loading/unloading of scenes could be easily implemented.
16. **Setting** - stores player data in key-value pairs by either encapsulating UnityEngine.PlayerPrefs or by saving the data directly to the disk.
17. **Sound** - provides features to manage sounds and groups of sounds. The user could set the properties of an audio clip, such as the volume, whether the clip is 2D or 3D, and could even bind the clip to some entity to follow its position.
18. **UI** - provides features to manage user interfaces and groups of UIs, such as showing or hiding, activating or deactivating, and depth changing. No matter the user uses the builtin uGUI in Unity or other UI plugins (NGUI, for example), he only needs to subclass 'UIFormLogic' and implement his own UI logic. The UIs could avoid being destroyed instantly after use, and hence be recycled for reuse.
19. **Web Request** - provides features of short connections, supports GET and POST methods to send requests to the server and acquire the response data, and allows the user to send simultaneous requests to different servers.

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,319 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(BaseComponent))]
internal sealed class BaseComponentInspector : GameFrameworkInspector
{
private const string NoneOptionName = "<None>";
private static readonly float[] GameSpeed = new float[] { 0f, 0.01f, 0.1f, 0.25f, 0.5f, 1f, 1.5f, 2f, 4f, 8f };
private static readonly string[] GameSpeedForDisplay = new string[] { "0x", "0.01x", "0.1x", "0.25x", "0.5x", "1x", "1.5x", "2x", "4x", "8x" };
private SerializedProperty m_EditorResourceMode = null;
private SerializedProperty m_EditorLanguage = null;
private SerializedProperty m_TextHelperTypeName = null;
private SerializedProperty m_VersionHelperTypeName = null;
private SerializedProperty m_LogHelperTypeName = null;
private SerializedProperty m_CompressionHelperTypeName = null;
private SerializedProperty m_JsonHelperTypeName = null;
private SerializedProperty m_FrameRate = null;
private SerializedProperty m_GameSpeed = null;
private SerializedProperty m_RunInBackground = null;
private SerializedProperty m_NeverSleep = null;
private string[] m_TextHelperTypeNames = null;
private int m_TextHelperTypeNameIndex = 0;
private string[] m_VersionHelperTypeNames = null;
private int m_VersionHelperTypeNameIndex = 0;
private string[] m_LogHelperTypeNames = null;
private int m_LogHelperTypeNameIndex = 0;
private string[] m_CompressionHelperTypeNames = null;
private int m_CompressionHelperTypeNameIndex = 0;
private string[] m_JsonHelperTypeNames = null;
private int m_JsonHelperTypeNameIndex = 0;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
BaseComponent t = (BaseComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
m_EditorResourceMode.boolValue = EditorGUILayout.BeginToggleGroup("Editor Resource Mode", m_EditorResourceMode.boolValue);
{
EditorGUILayout.HelpBox("Editor resource mode option is only for editor mode. Game Framework will use editor resource files, which you should validate first.", MessageType.Warning);
EditorGUILayout.PropertyField(m_EditorLanguage);
EditorGUILayout.HelpBox("Editor language option is only use for localization test in editor mode.", MessageType.Info);
}
EditorGUILayout.EndToggleGroup();
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("Global Helpers", EditorStyles.boldLabel);
int textHelperSelectedIndex = EditorGUILayout.Popup("Text Helper", m_TextHelperTypeNameIndex, m_TextHelperTypeNames);
if (textHelperSelectedIndex != m_TextHelperTypeNameIndex)
{
m_TextHelperTypeNameIndex = textHelperSelectedIndex;
m_TextHelperTypeName.stringValue = textHelperSelectedIndex <= 0 ? null : m_TextHelperTypeNames[textHelperSelectedIndex];
}
int versionHelperSelectedIndex = EditorGUILayout.Popup("Version Helper", m_VersionHelperTypeNameIndex, m_VersionHelperTypeNames);
if (versionHelperSelectedIndex != m_VersionHelperTypeNameIndex)
{
m_VersionHelperTypeNameIndex = versionHelperSelectedIndex;
m_VersionHelperTypeName.stringValue = versionHelperSelectedIndex <= 0 ? null : m_VersionHelperTypeNames[versionHelperSelectedIndex];
}
int logHelperSelectedIndex = EditorGUILayout.Popup("Log Helper", m_LogHelperTypeNameIndex, m_LogHelperTypeNames);
if (logHelperSelectedIndex != m_LogHelperTypeNameIndex)
{
m_LogHelperTypeNameIndex = logHelperSelectedIndex;
m_LogHelperTypeName.stringValue = logHelperSelectedIndex <= 0 ? null : m_LogHelperTypeNames[logHelperSelectedIndex];
}
int compressionHelperSelectedIndex = EditorGUILayout.Popup("Compression Helper", m_CompressionHelperTypeNameIndex, m_CompressionHelperTypeNames);
if (compressionHelperSelectedIndex != m_CompressionHelperTypeNameIndex)
{
m_CompressionHelperTypeNameIndex = compressionHelperSelectedIndex;
m_CompressionHelperTypeName.stringValue = compressionHelperSelectedIndex <= 0 ? null : m_CompressionHelperTypeNames[compressionHelperSelectedIndex];
}
int jsonHelperSelectedIndex = EditorGUILayout.Popup("JSON Helper", m_JsonHelperTypeNameIndex, m_JsonHelperTypeNames);
if (jsonHelperSelectedIndex != m_JsonHelperTypeNameIndex)
{
m_JsonHelperTypeNameIndex = jsonHelperSelectedIndex;
m_JsonHelperTypeName.stringValue = jsonHelperSelectedIndex <= 0 ? null : m_JsonHelperTypeNames[jsonHelperSelectedIndex];
}
}
EditorGUILayout.EndVertical();
}
EditorGUI.EndDisabledGroup();
int frameRate = EditorGUILayout.IntSlider("Frame Rate", m_FrameRate.intValue, 1, 120);
if (frameRate != m_FrameRate.intValue)
{
if (EditorApplication.isPlaying)
{
t.FrameRate = frameRate;
}
else
{
m_FrameRate.intValue = frameRate;
}
}
EditorGUILayout.BeginVertical("box");
{
float gameSpeed = EditorGUILayout.Slider("Game Speed", m_GameSpeed.floatValue, 0f, 8f);
int selectedGameSpeed = GUILayout.SelectionGrid(GetSelectedGameSpeed(gameSpeed), GameSpeedForDisplay, 5);
if (selectedGameSpeed >= 0)
{
gameSpeed = GetGameSpeed(selectedGameSpeed);
}
if (gameSpeed != m_GameSpeed.floatValue)
{
if (EditorApplication.isPlaying)
{
t.GameSpeed = gameSpeed;
}
else
{
m_GameSpeed.floatValue = gameSpeed;
}
}
}
EditorGUILayout.EndVertical();
bool runInBackground = EditorGUILayout.Toggle("Run in Background", m_RunInBackground.boolValue);
if (runInBackground != m_RunInBackground.boolValue)
{
if (EditorApplication.isPlaying)
{
t.RunInBackground = runInBackground;
}
else
{
m_RunInBackground.boolValue = runInBackground;
}
}
bool neverSleep = EditorGUILayout.Toggle("Never Sleep", m_NeverSleep.boolValue);
if (neverSleep != m_NeverSleep.boolValue)
{
if (EditorApplication.isPlaying)
{
t.NeverSleep = neverSleep;
}
else
{
m_NeverSleep.boolValue = neverSleep;
}
}
serializedObject.ApplyModifiedProperties();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EditorResourceMode = serializedObject.FindProperty("m_EditorResourceMode");
m_EditorLanguage = serializedObject.FindProperty("m_EditorLanguage");
m_TextHelperTypeName = serializedObject.FindProperty("m_TextHelperTypeName");
m_VersionHelperTypeName = serializedObject.FindProperty("m_VersionHelperTypeName");
m_LogHelperTypeName = serializedObject.FindProperty("m_LogHelperTypeName");
m_CompressionHelperTypeName = serializedObject.FindProperty("m_CompressionHelperTypeName");
m_JsonHelperTypeName = serializedObject.FindProperty("m_JsonHelperTypeName");
m_FrameRate = serializedObject.FindProperty("m_FrameRate");
m_GameSpeed = serializedObject.FindProperty("m_GameSpeed");
m_RunInBackground = serializedObject.FindProperty("m_RunInBackground");
m_NeverSleep = serializedObject.FindProperty("m_NeverSleep");
RefreshTypeNames();
}
private void RefreshTypeNames()
{
List<string> textHelperTypeNames = new List<string>
{
NoneOptionName
};
textHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Text.ITextHelper)));
m_TextHelperTypeNames = textHelperTypeNames.ToArray();
m_TextHelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_TextHelperTypeName.stringValue))
{
m_TextHelperTypeNameIndex = textHelperTypeNames.IndexOf(m_TextHelperTypeName.stringValue);
if (m_TextHelperTypeNameIndex <= 0)
{
m_TextHelperTypeNameIndex = 0;
m_TextHelperTypeName.stringValue = null;
}
}
List<string> versionHelperTypeNames = new List<string>
{
NoneOptionName
};
versionHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Version.IVersionHelper)));
m_VersionHelperTypeNames = versionHelperTypeNames.ToArray();
m_VersionHelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_VersionHelperTypeName.stringValue))
{
m_VersionHelperTypeNameIndex = versionHelperTypeNames.IndexOf(m_VersionHelperTypeName.stringValue);
if (m_VersionHelperTypeNameIndex <= 0)
{
m_VersionHelperTypeNameIndex = 0;
m_VersionHelperTypeName.stringValue = null;
}
}
List<string> logHelperTypeNames = new List<string>
{
NoneOptionName
};
logHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(GameFrameworkLog.ILogHelper)));
m_LogHelperTypeNames = logHelperTypeNames.ToArray();
m_LogHelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_LogHelperTypeName.stringValue))
{
m_LogHelperTypeNameIndex = logHelperTypeNames.IndexOf(m_LogHelperTypeName.stringValue);
if (m_LogHelperTypeNameIndex <= 0)
{
m_LogHelperTypeNameIndex = 0;
m_LogHelperTypeName.stringValue = null;
}
}
List<string> compressionHelperTypeNames = new List<string>
{
NoneOptionName
};
compressionHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Compression.ICompressionHelper)));
m_CompressionHelperTypeNames = compressionHelperTypeNames.ToArray();
m_CompressionHelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_CompressionHelperTypeName.stringValue))
{
m_CompressionHelperTypeNameIndex = compressionHelperTypeNames.IndexOf(m_CompressionHelperTypeName.stringValue);
if (m_CompressionHelperTypeNameIndex <= 0)
{
m_CompressionHelperTypeNameIndex = 0;
m_CompressionHelperTypeName.stringValue = null;
}
}
List<string> jsonHelperTypeNames = new List<string>
{
NoneOptionName
};
jsonHelperTypeNames.AddRange(Type.GetRuntimeTypeNames(typeof(Utility.Json.IJsonHelper)));
m_JsonHelperTypeNames = jsonHelperTypeNames.ToArray();
m_JsonHelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_JsonHelperTypeName.stringValue))
{
m_JsonHelperTypeNameIndex = jsonHelperTypeNames.IndexOf(m_JsonHelperTypeName.stringValue);
if (m_JsonHelperTypeNameIndex <= 0)
{
m_JsonHelperTypeNameIndex = 0;
m_JsonHelperTypeName.stringValue = null;
}
}
serializedObject.ApplyModifiedProperties();
}
private float GetGameSpeed(int selectedGameSpeed)
{
if (selectedGameSpeed < 0)
{
return GameSpeed[0];
}
if (selectedGameSpeed >= GameSpeed.Length)
{
return GameSpeed[GameSpeed.Length - 1];
}
return GameSpeed[selectedGameSpeed];
}
private int GetSelectedGameSpeed(float gameSpeed)
{
for (int i = 0; i < GameSpeed.Length; i++)
{
if (gameSpeed == GameSpeed[i])
{
return i;
}
}
return -1;
}
}
}

View File

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

View File

@ -0,0 +1,74 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(ConfigComponent))]
internal sealed class ConfigComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableLoadConfigUpdateEvent = null;
private SerializedProperty m_EnableLoadConfigDependencyAssetEvent = null;
private SerializedProperty m_CachedBytesSize = null;
private HelperInfo<ConfigHelperBase> m_ConfigHelperInfo = new HelperInfo<ConfigHelperBase>("Config");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
ConfigComponent t = (ConfigComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableLoadConfigUpdateEvent);
EditorGUILayout.PropertyField(m_EnableLoadConfigDependencyAssetEvent);
m_ConfigHelperInfo.Draw();
EditorGUILayout.PropertyField(m_CachedBytesSize);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Config Count", t.Count.ToString());
EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString());
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnableLoadConfigUpdateEvent = serializedObject.FindProperty("m_EnableLoadConfigUpdateEvent");
m_EnableLoadConfigDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadConfigDependencyAssetEvent");
m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize");
m_ConfigHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_ConfigHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,51 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.DataNode;
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(DataNodeComponent))]
internal sealed class DataNodeComponentInspector : GameFrameworkInspector
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
DataNodeComponent t = (DataNodeComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
DrawDataNode(t.Root);
}
Repaint();
}
private void OnEnable()
{
}
private void DrawDataNode(IDataNode dataNode)
{
EditorGUILayout.LabelField(dataNode.FullName, dataNode.ToDataString());
IDataNode[] child = dataNode.GetAllChild();
foreach (IDataNode c in child)
{
DrawDataNode(c);
}
}
}
}

View File

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

View File

@ -0,0 +1,87 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.DataTable;
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(DataTableComponent))]
internal sealed class DataTableComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableLoadDataTableUpdateEvent = null;
private SerializedProperty m_EnableLoadDataTableDependencyAssetEvent = null;
private SerializedProperty m_CachedBytesSize = null;
private HelperInfo<DataTableHelperBase> m_DataTableHelperInfo = new HelperInfo<DataTableHelperBase>("DataTable");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
DataTableComponent t = (DataTableComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableLoadDataTableUpdateEvent);
EditorGUILayout.PropertyField(m_EnableLoadDataTableDependencyAssetEvent);
m_DataTableHelperInfo.Draw();
EditorGUILayout.PropertyField(m_CachedBytesSize);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Data Table Count", t.Count.ToString());
EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString());
DataTableBase[] dataTables = t.GetAllDataTables();
foreach (DataTableBase dataTable in dataTables)
{
DrawDataTable(dataTable);
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnableLoadDataTableUpdateEvent = serializedObject.FindProperty("m_EnableLoadDataTableUpdateEvent");
m_EnableLoadDataTableDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadDataTableDependencyAssetEvent");
m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize");
m_DataTableHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void DrawDataTable(DataTableBase dataTable)
{
EditorGUILayout.LabelField(dataTable.FullName, Utility.Text.Format("{0} Rows", dataTable.Count));
}
private void RefreshTypeNames()
{
m_DataTableHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,68 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(DebuggerComponent))]
internal sealed class DebuggerComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_Skin = null;
private SerializedProperty m_ActiveWindow = null;
private SerializedProperty m_ShowFullWindow = null;
private SerializedProperty m_ConsoleWindow = null;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
DebuggerComponent t = (DebuggerComponent)target;
EditorGUILayout.PropertyField(m_Skin);
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
bool activeWindow = EditorGUILayout.Toggle("Active Window", t.ActiveWindow);
if (activeWindow != t.ActiveWindow)
{
t.ActiveWindow = activeWindow;
}
}
else
{
EditorGUILayout.PropertyField(m_ActiveWindow);
}
EditorGUILayout.PropertyField(m_ShowFullWindow);
if (EditorApplication.isPlaying)
{
if (GUILayout.Button("Reset Layout"))
{
t.ResetLayout();
}
}
EditorGUILayout.PropertyField(m_ConsoleWindow, true);
serializedObject.ApplyModifiedProperties();
}
private void OnEnable()
{
m_Skin = serializedObject.FindProperty("m_Skin");
m_ActiveWindow = serializedObject.FindProperty("m_ActiveWindow");
m_ShowFullWindow = serializedObject.FindProperty("m_ShowFullWindow");
m_ConsoleWindow = serializedObject.FindProperty("m_ConsoleWindow");
}
}
}

View File

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

View File

@ -0,0 +1,156 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(DownloadComponent))]
internal sealed class DownloadComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_DownloadAgentHelperCount = null;
private SerializedProperty m_Timeout = null;
private SerializedProperty m_FlushSize = null;
private HelperInfo<DownloadAgentHelperBase> m_DownloadAgentHelperInfo = new HelperInfo<DownloadAgentHelperBase>("DownloadAgent");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
DownloadComponent t = (DownloadComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_InstanceRoot);
m_DownloadAgentHelperInfo.Draw();
m_DownloadAgentHelperCount.intValue = EditorGUILayout.IntSlider("Download Agent Helper Count", m_DownloadAgentHelperCount.intValue, 1, 16);
}
EditorGUI.EndDisabledGroup();
float timeout = EditorGUILayout.Slider("Timeout", m_Timeout.floatValue, 0f, 120f);
if (timeout != m_Timeout.floatValue)
{
if (EditorApplication.isPlaying)
{
t.Timeout = timeout;
}
else
{
m_Timeout.floatValue = timeout;
}
}
int flushSize = EditorGUILayout.DelayedIntField("Flush Size", m_FlushSize.intValue);
if (flushSize != m_FlushSize.intValue)
{
if (EditorApplication.isPlaying)
{
t.FlushSize = flushSize;
}
else
{
m_FlushSize.intValue = flushSize;
}
}
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Paused", t.Paused.ToString());
EditorGUILayout.LabelField("Total Agent Count", t.TotalAgentCount.ToString());
EditorGUILayout.LabelField("Free Agent Count", t.FreeAgentCount.ToString());
EditorGUILayout.LabelField("Working Agent Count", t.WorkingAgentCount.ToString());
EditorGUILayout.LabelField("Waiting Agent Count", t.WaitingTaskCount.ToString());
EditorGUILayout.LabelField("Current Speed", t.CurrentSpeed.ToString());
EditorGUILayout.BeginVertical("box");
{
TaskInfo[] downloadInfos = t.GetAllDownloadInfos();
if (downloadInfos.Length > 0)
{
foreach (TaskInfo downloadInfo in downloadInfos)
{
DrawDownloadInfo(downloadInfo);
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "Download Task Data.csv", string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[downloadInfos.Length + 1];
data[index++] = "Download Path,Serial Id,Tag,Priority,Status";
foreach (TaskInfo downloadInfo in downloadInfos)
{
data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4}", downloadInfo.Description, downloadInfo.SerialId, downloadInfo.Tag ?? string.Empty, downloadInfo.Priority, downloadInfo.Status);
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export download task CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export download task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
else
{
GUILayout.Label("Download Task is Empty ...");
}
}
EditorGUILayout.EndVertical();
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_DownloadAgentHelperCount = serializedObject.FindProperty("m_DownloadAgentHelperCount");
m_Timeout = serializedObject.FindProperty("m_Timeout");
m_FlushSize = serializedObject.FindProperty("m_FlushSize");
m_DownloadAgentHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void DrawDownloadInfo(TaskInfo downloadInfo)
{
EditorGUILayout.LabelField(downloadInfo.Description, Utility.Text.Format("[SerialId]{0} [Tag]{1} [Priority]{2} [Status]{3}", downloadInfo.SerialId, downloadInfo.Tag ?? "<None>", downloadInfo.Priority, downloadInfo.Status));
}
private void RefreshTypeNames()
{
m_DownloadAgentHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,52 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(EditorResourceComponent))]
internal sealed class EditorResourceComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableCachedAssets = null;
private SerializedProperty m_LoadAssetCountPerFrame = null;
private SerializedProperty m_MinLoadAssetRandomDelaySeconds = null;
private SerializedProperty m_MaxLoadAssetRandomDelaySeconds = null;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
EditorResourceComponent t = (EditorResourceComponent)target;
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Load Waiting Asset Count", t.LoadWaitingAssetCount.ToString());
}
EditorGUILayout.PropertyField(m_EnableCachedAssets);
EditorGUILayout.PropertyField(m_LoadAssetCountPerFrame);
EditorGUILayout.PropertyField(m_MinLoadAssetRandomDelaySeconds);
EditorGUILayout.PropertyField(m_MaxLoadAssetRandomDelaySeconds);
serializedObject.ApplyModifiedProperties();
Repaint();
}
private void OnEnable()
{
m_EnableCachedAssets = serializedObject.FindProperty("m_EnableCachedAssets");
m_LoadAssetCountPerFrame = serializedObject.FindProperty("m_LoadAssetCountPerFrame");
m_MinLoadAssetRandomDelaySeconds = serializedObject.FindProperty("m_MinLoadAssetRandomDelaySeconds");
m_MaxLoadAssetRandomDelaySeconds = serializedObject.FindProperty("m_MaxLoadAssetRandomDelaySeconds");
}
}
}

View File

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

View File

@ -0,0 +1,88 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.Entity;
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(EntityComponent))]
internal sealed class EntityComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableShowEntityUpdateEvent = null;
private SerializedProperty m_EnableShowEntityDependencyAssetEvent = null;
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_EntityGroups = null;
private HelperInfo<EntityHelperBase> m_EntityHelperInfo = new HelperInfo<EntityHelperBase>("Entity");
private HelperInfo<EntityGroupHelperBase> m_EntityGroupHelperInfo = new HelperInfo<EntityGroupHelperBase>("EntityGroup");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
EntityComponent t = (EntityComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableShowEntityUpdateEvent);
EditorGUILayout.PropertyField(m_EnableShowEntityDependencyAssetEvent);
EditorGUILayout.PropertyField(m_InstanceRoot);
m_EntityHelperInfo.Draw();
m_EntityGroupHelperInfo.Draw();
EditorGUILayout.PropertyField(m_EntityGroups, true);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Entity Group Count", t.EntityGroupCount.ToString());
EditorGUILayout.LabelField("Entity Count (Total)", t.EntityCount.ToString());
IEntityGroup[] entityGroups = t.GetAllEntityGroups();
foreach (IEntityGroup entityGroup in entityGroups)
{
EditorGUILayout.LabelField(Utility.Text.Format("Entity Count ({0})", entityGroup.Name), entityGroup.EntityCount.ToString());
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnableShowEntityUpdateEvent = serializedObject.FindProperty("m_EnableShowEntityUpdateEvent");
m_EnableShowEntityDependencyAssetEvent = serializedObject.FindProperty("m_EnableShowEntityDependencyAssetEvent");
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_EntityGroups = serializedObject.FindProperty("m_EntityGroups");
m_EntityHelperInfo.Init(serializedObject);
m_EntityGroupHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_EntityHelperInfo.Refresh();
m_EntityGroupHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,41 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(EventComponent))]
internal sealed class EventComponentInspector : GameFrameworkInspector
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
EventComponent t = (EventComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Event Handler Count", t.EventHandlerCount.ToString());
EditorGUILayout.LabelField("Event Count", t.EventCount.ToString());
}
Repaint();
}
private void OnEnable()
{
}
}
}

View File

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

View File

@ -0,0 +1,73 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.FileSystem;
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(FileSystemComponent))]
internal sealed class FileSystemComponentInspector : GameFrameworkInspector
{
private HelperInfo<FileSystemHelperBase> m_FileSystemHelperInfo = new HelperInfo<FileSystemHelperBase>("FileSystem");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
FileSystemComponent t = (FileSystemComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
m_FileSystemHelperInfo.Draw();
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("File System Count", t.Count.ToString());
IFileSystem[] fileSystems = t.GetAllFileSystems();
foreach (IFileSystem fileSystem in fileSystems)
{
DrawFileSystem(fileSystem);
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_FileSystemHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_FileSystemHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
private void DrawFileSystem(IFileSystem fileSystem)
{
EditorGUILayout.LabelField(fileSystem.FullPath, Utility.Text.Format("{0}, {1} / {2} Files", fileSystem.Access, fileSystem.FileCount, fileSystem.MaxFileCount));
}
}
}

View File

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

View File

@ -0,0 +1,53 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.Fsm;
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(FsmComponent))]
internal sealed class FsmComponentInspector : GameFrameworkInspector
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
FsmComponent t = (FsmComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("FSM Count", t.Count.ToString());
FsmBase[] fsms = t.GetAllFsms();
foreach (FsmBase fsm in fsms)
{
DrawFsm(fsm);
}
}
Repaint();
}
private void OnEnable()
{
}
private void DrawFsm(FsmBase fsm)
{
EditorGUILayout.LabelField(fsm.FullName, fsm.IsRunning ? Utility.Text.Format("{0}, {1:F1} s", fsm.CurrentStateName, fsm.CurrentStateTime) : (fsm.IsDestroyed ? "Destroyed" : "Not Running"));
}
}
}

View File

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

View File

@ -0,0 +1,64 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 游戏框架 Inspector 抽象类。
/// </summary>
public abstract class GameFrameworkInspector : UnityEditor.Editor
{
private bool m_IsCompiling = false;
/// <summary>
/// 绘制事件。
/// </summary>
public override void OnInspectorGUI()
{
if (m_IsCompiling && !EditorApplication.isCompiling)
{
m_IsCompiling = false;
OnCompileComplete();
}
else if (!m_IsCompiling && EditorApplication.isCompiling)
{
m_IsCompiling = true;
OnCompileStart();
}
}
/// <summary>
/// 编译开始事件。
/// </summary>
protected virtual void OnCompileStart()
{
}
/// <summary>
/// 编译完成事件。
/// </summary>
protected virtual void OnCompileComplete()
{
}
protected bool IsPrefabInHierarchy(UnityEngine.Object obj)
{
if (obj == null)
{
return false;
}
#if UNITY_2018_3_OR_NEWER
return PrefabUtility.GetPrefabAssetType(obj) != PrefabAssetType.Regular;
#else
return PrefabUtility.GetPrefabType(obj) != PrefabType.Prefab;
#endif
}
}
}

View File

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

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(LocalizationComponent))]
internal sealed class LocalizationComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableLoadDictionaryUpdateEvent = null;
private SerializedProperty m_EnableLoadDictionaryDependencyAssetEvent = null;
private SerializedProperty m_CachedBytesSize = null;
private HelperInfo<LocalizationHelperBase> m_LocalizationHelperInfo = new HelperInfo<LocalizationHelperBase>("Localization");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
LocalizationComponent t = (LocalizationComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableLoadDictionaryUpdateEvent);
EditorGUILayout.PropertyField(m_EnableLoadDictionaryDependencyAssetEvent);
m_LocalizationHelperInfo.Draw();
EditorGUILayout.PropertyField(m_CachedBytesSize);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Language", t.Language.ToString());
EditorGUILayout.LabelField("System Language", t.SystemLanguage.ToString());
EditorGUILayout.LabelField("Dictionary Count", t.DictionaryCount.ToString());
EditorGUILayout.LabelField("Cached Bytes Size", t.CachedBytesSize.ToString());
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnableLoadDictionaryUpdateEvent = serializedObject.FindProperty("m_EnableLoadDictionaryUpdateEvent");
m_EnableLoadDictionaryDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadDictionaryDependencyAssetEvent");
m_CachedBytesSize = serializedObject.FindProperty("m_CachedBytesSize");
m_LocalizationHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_LocalizationHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.Network;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(NetworkComponent))]
internal sealed class NetworkComponentInspector : GameFrameworkInspector
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
NetworkComponent t = (NetworkComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
foreach (INetworkChannel networkChannel in networkChannels)
{
DrawNetworkChannel(networkChannel);
}
}
Repaint();
}
private void OnEnable()
{
}
private void DrawNetworkChannel(INetworkChannel networkChannel)
{
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount, networkChannel.SentPacketCount));
EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount, networkChannel.ReceivedPacketCount));
EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0:F2} / {1:F2}", networkChannel.HeartBeatElapseSeconds, networkChannel.HeartBeatInterval));
EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
{
if (GUILayout.Button("Disconnect"))
{
networkChannel.Close();
}
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndVertical();
EditorGUILayout.Separator();
}
}
}

View File

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

View File

@ -0,0 +1,138 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.ObjectPool;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(ObjectPoolComponent))]
internal sealed class ObjectPoolComponentInspector : GameFrameworkInspector
{
private readonly HashSet<string> m_OpenedItems = new HashSet<string>();
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
ObjectPoolComponent t = (ObjectPoolComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Object Pool Count", t.Count.ToString());
ObjectPoolBase[] objectPools = t.GetAllObjectPools(true);
foreach (ObjectPoolBase objectPool in objectPools)
{
DrawObjectPool(objectPool);
}
}
Repaint();
}
private void OnEnable()
{
}
private void DrawObjectPool(ObjectPoolBase objectPool)
{
bool lastState = m_OpenedItems.Contains(objectPool.FullName);
bool currentState = EditorGUILayout.Foldout(lastState, objectPool.FullName);
if (currentState != lastState)
{
if (currentState)
{
m_OpenedItems.Add(objectPool.FullName);
}
else
{
m_OpenedItems.Remove(objectPool.FullName);
}
}
if (currentState)
{
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("Name", objectPool.Name);
EditorGUILayout.LabelField("Type", objectPool.ObjectType.FullName);
EditorGUILayout.LabelField("Auto Release Interval", objectPool.AutoReleaseInterval.ToString());
EditorGUILayout.LabelField("Capacity", objectPool.Capacity.ToString());
EditorGUILayout.LabelField("Used Count", objectPool.Count.ToString());
EditorGUILayout.LabelField("Can Release Count", objectPool.CanReleaseCount.ToString());
EditorGUILayout.LabelField("Expire Time", objectPool.ExpireTime.ToString());
EditorGUILayout.LabelField("Priority", objectPool.Priority.ToString());
ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos();
if (objectInfos.Length > 0)
{
EditorGUILayout.LabelField("Name", objectPool.AllowMultiSpawn ? "Locked\tCount\tFlag\tPriority\tLast Use Time" : "Locked\tIn Use\tFlag\tPriority\tLast Use Time");
foreach (ObjectInfo objectInfo in objectInfos)
{
EditorGUILayout.LabelField(string.IsNullOrEmpty(objectInfo.Name) ? "<None>" : objectInfo.Name, objectPool.AllowMultiSpawn ? Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.SpawnCount, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()) : Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.IsInUse, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()));
}
if (GUILayout.Button("Release"))
{
objectPool.Release();
}
if (GUILayout.Button("Release All Unused"))
{
objectPool.ReleaseAllUnused();
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Object Pool Data - {0}.csv", objectPool.Name), string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[objectInfos.Length + 1];
data[index++] = Utility.Text.Format("Name,Locked,{0},Custom Can Release Flag,Priority,Last Use Time", objectPool.AllowMultiSpawn ? "Count" : "In Use");
foreach (ObjectInfo objectInfo in objectInfos)
{
data[index++] = objectPool.AllowMultiSpawn ? Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.SpawnCount, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()) : Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.IsInUse, objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime());
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export object pool CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export object pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
else
{
GUILayout.Label("Object Pool is Empty ...");
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.Separator();
}
}
}
}

View File

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

View File

@ -0,0 +1,172 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.Procedure;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(ProcedureComponent))]
internal sealed class ProcedureComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_AvailableProcedureTypeNames = null;
private SerializedProperty m_EntranceProcedureTypeName = null;
private string[] m_ProcedureTypeNames = null;
private List<string> m_CurrentAvailableProcedureTypeNames = null;
private int m_EntranceProcedureIndex = -1;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
ProcedureComponent t = (ProcedureComponent)target;
if (string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
{
EditorGUILayout.HelpBox("Entrance procedure is invalid.", MessageType.Error);
}
else if (EditorApplication.isPlaying)
{
EditorGUILayout.LabelField("Current Procedure", t.CurrentProcedure == null ? "None" : t.CurrentProcedure.GetType().ToString());
}
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
GUILayout.Label("Available Procedures", EditorStyles.boldLabel);
if (m_ProcedureTypeNames.Length > 0)
{
EditorGUILayout.BeginVertical("box");
{
foreach (string procedureTypeName in m_ProcedureTypeNames)
{
bool selected = m_CurrentAvailableProcedureTypeNames.Contains(procedureTypeName);
if (selected != EditorGUILayout.ToggleLeft(procedureTypeName, selected))
{
if (!selected)
{
m_CurrentAvailableProcedureTypeNames.Add(procedureTypeName);
WriteAvailableProcedureTypeNames();
}
else if (procedureTypeName != m_EntranceProcedureTypeName.stringValue)
{
m_CurrentAvailableProcedureTypeNames.Remove(procedureTypeName);
WriteAvailableProcedureTypeNames();
}
}
}
}
EditorGUILayout.EndVertical();
}
else
{
EditorGUILayout.HelpBox("There is no available procedure.", MessageType.Warning);
}
if (m_CurrentAvailableProcedureTypeNames.Count > 0)
{
EditorGUILayout.Separator();
int selectedIndex = EditorGUILayout.Popup("Entrance Procedure", m_EntranceProcedureIndex, m_CurrentAvailableProcedureTypeNames.ToArray());
if (selectedIndex != m_EntranceProcedureIndex)
{
m_EntranceProcedureIndex = selectedIndex;
m_EntranceProcedureTypeName.stringValue = m_CurrentAvailableProcedureTypeNames[selectedIndex];
}
}
else
{
EditorGUILayout.HelpBox("Select available procedures first.", MessageType.Info);
}
}
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_AvailableProcedureTypeNames = serializedObject.FindProperty("m_AvailableProcedureTypeNames");
m_EntranceProcedureTypeName = serializedObject.FindProperty("m_EntranceProcedureTypeName");
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_ProcedureTypeNames = Type.GetRuntimeTypeNames(typeof(ProcedureBase));
ReadAvailableProcedureTypeNames();
int oldCount = m_CurrentAvailableProcedureTypeNames.Count;
m_CurrentAvailableProcedureTypeNames = m_CurrentAvailableProcedureTypeNames.Where(x => m_ProcedureTypeNames.Contains(x)).ToList();
if (m_CurrentAvailableProcedureTypeNames.Count != oldCount)
{
WriteAvailableProcedureTypeNames();
}
else if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
{
m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue);
if (m_EntranceProcedureIndex < 0)
{
m_EntranceProcedureTypeName.stringValue = null;
}
}
serializedObject.ApplyModifiedProperties();
}
private void ReadAvailableProcedureTypeNames()
{
m_CurrentAvailableProcedureTypeNames = new List<string>();
int count = m_AvailableProcedureTypeNames.arraySize;
for (int i = 0; i < count; i++)
{
m_CurrentAvailableProcedureTypeNames.Add(m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue);
}
}
private void WriteAvailableProcedureTypeNames()
{
m_AvailableProcedureTypeNames.ClearArray();
if (m_CurrentAvailableProcedureTypeNames == null)
{
return;
}
m_CurrentAvailableProcedureTypeNames.Sort();
int count = m_CurrentAvailableProcedureTypeNames.Count;
for (int i = 0; i < count; i++)
{
m_AvailableProcedureTypeNames.InsertArrayElementAtIndex(i);
m_AvailableProcedureTypeNames.GetArrayElementAtIndex(i).stringValue = m_CurrentAvailableProcedureTypeNames[i];
}
if (!string.IsNullOrEmpty(m_EntranceProcedureTypeName.stringValue))
{
m_EntranceProcedureIndex = m_CurrentAvailableProcedureTypeNames.IndexOf(m_EntranceProcedureTypeName.stringValue);
if (m_EntranceProcedureIndex < 0)
{
m_EntranceProcedureTypeName.stringValue = null;
}
}
}
}
}

View File

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

View File

@ -0,0 +1,152 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(ReferencePoolComponent))]
internal sealed class ReferencePoolComponentInspector : GameFrameworkInspector
{
private readonly Dictionary<string, List<ReferencePoolInfo>> m_ReferencePoolInfos = new Dictionary<string, List<ReferencePoolInfo>>(StringComparer.Ordinal);
private readonly HashSet<string> m_OpenedItems = new HashSet<string>();
private SerializedProperty m_EnableStrictCheck = null;
private bool m_ShowFullClassName = false;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
ReferencePoolComponent t = (ReferencePoolComponent)target;
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
bool enableStrictCheck = EditorGUILayout.Toggle("Enable Strict Check", t.EnableStrictCheck);
if (enableStrictCheck != t.EnableStrictCheck)
{
t.EnableStrictCheck = enableStrictCheck;
}
EditorGUILayout.LabelField("Reference Pool Count", ReferencePool.Count.ToString());
m_ShowFullClassName = EditorGUILayout.Toggle("Show Full Class Name", m_ShowFullClassName);
m_ReferencePoolInfos.Clear();
ReferencePoolInfo[] referencePoolInfos = ReferencePool.GetAllReferencePoolInfos();
foreach (ReferencePoolInfo referencePoolInfo in referencePoolInfos)
{
string assemblyName = referencePoolInfo.Type.Assembly.GetName().Name;
List<ReferencePoolInfo> results = null;
if (!m_ReferencePoolInfos.TryGetValue(assemblyName, out results))
{
results = new List<ReferencePoolInfo>();
m_ReferencePoolInfos.Add(assemblyName, results);
}
results.Add(referencePoolInfo);
}
foreach (KeyValuePair<string, List<ReferencePoolInfo>> assemblyReferencePoolInfo in m_ReferencePoolInfos)
{
bool lastState = m_OpenedItems.Contains(assemblyReferencePoolInfo.Key);
bool currentState = EditorGUILayout.Foldout(lastState, assemblyReferencePoolInfo.Key);
if (currentState != lastState)
{
if (currentState)
{
m_OpenedItems.Add(assemblyReferencePoolInfo.Key);
}
else
{
m_OpenedItems.Remove(assemblyReferencePoolInfo.Key);
}
}
if (currentState)
{
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField(m_ShowFullClassName ? "Full Class Name" : "Class Name", "Unused\tUsing\tAcquire\tRelease\tAdd\tRemove");
assemblyReferencePoolInfo.Value.Sort(Comparison);
foreach (ReferencePoolInfo referencePoolInfo in assemblyReferencePoolInfo.Value)
{
DrawReferencePoolInfo(referencePoolInfo);
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Reference Pool Data - {0}.csv", assemblyReferencePoolInfo.Key), string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[assemblyReferencePoolInfo.Value.Count + 1];
data[index++] = "Class Name,Full Class Name,Unused,Using,Acquire,Release,Add,Remove";
foreach (ReferencePoolInfo referencePoolInfo in assemblyReferencePoolInfo.Value)
{
data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4},{5},{6},{7}", referencePoolInfo.Type.Name, referencePoolInfo.Type.FullName, referencePoolInfo.UnusedReferenceCount, referencePoolInfo.UsingReferenceCount, referencePoolInfo.AcquireReferenceCount, referencePoolInfo.ReleaseReferenceCount, referencePoolInfo.AddReferenceCount, referencePoolInfo.RemoveReferenceCount);
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export reference pool CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export reference pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.Separator();
}
}
}
else
{
EditorGUILayout.PropertyField(m_EnableStrictCheck);
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
private void OnEnable()
{
m_EnableStrictCheck = serializedObject.FindProperty("m_EnableStrictCheck");
}
private void DrawReferencePoolInfo(ReferencePoolInfo referencePoolInfo)
{
EditorGUILayout.LabelField(m_ShowFullClassName ? referencePoolInfo.Type.FullName : referencePoolInfo.Type.Name, Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", referencePoolInfo.UnusedReferenceCount, referencePoolInfo.UsingReferenceCount, referencePoolInfo.AcquireReferenceCount, referencePoolInfo.ReleaseReferenceCount, referencePoolInfo.AddReferenceCount, referencePoolInfo.RemoveReferenceCount));
}
private int Comparison(ReferencePoolInfo a, ReferencePoolInfo b)
{
if (m_ShowFullClassName)
{
return a.Type.FullName.CompareTo(b.Type.FullName);
}
else
{
return a.Type.Name.CompareTo(b.Type.Name);
}
}
}
}

View File

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

View File

@ -0,0 +1,397 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(ResourceComponent))]
internal sealed class ResourceComponentInspector : GameFrameworkInspector
{
private static readonly string[] ResourceModeNames = new string[] { "Package", "Updatable", "Updatable While Playing" };
private SerializedProperty m_ResourceMode = null;
private SerializedProperty m_ReadWritePathType = null;
private SerializedProperty m_MinUnloadUnusedAssetsInterval = null;
private SerializedProperty m_MaxUnloadUnusedAssetsInterval = null;
private SerializedProperty m_AssetAutoReleaseInterval = null;
private SerializedProperty m_AssetCapacity = null;
private SerializedProperty m_AssetExpireTime = null;
private SerializedProperty m_AssetPriority = null;
private SerializedProperty m_ResourceAutoReleaseInterval = null;
private SerializedProperty m_ResourceCapacity = null;
private SerializedProperty m_ResourceExpireTime = null;
private SerializedProperty m_ResourcePriority = null;
private SerializedProperty m_UpdatePrefixUri = null;
private SerializedProperty m_GenerateReadWriteVersionListLength = null;
private SerializedProperty m_UpdateRetryCount = null;
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_LoadResourceAgentHelperCount = null;
private FieldInfo m_EditorResourceModeFieldInfo = null;
private int m_ResourceModeIndex = 0;
private HelperInfo<ResourceHelperBase> m_ResourceHelperInfo = new HelperInfo<ResourceHelperBase>("Resource");
private HelperInfo<LoadResourceAgentHelperBase> m_LoadResourceAgentHelperInfo = new HelperInfo<LoadResourceAgentHelperBase>("LoadResourceAgent");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
ResourceComponent t = (ResourceComponent)target;
bool isEditorResourceMode = (bool)m_EditorResourceModeFieldInfo.GetValue(target);
if (isEditorResourceMode)
{
EditorGUILayout.HelpBox("Editor resource mode is enabled. Some options are disabled.", MessageType.Warning);
}
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.EnumPopup("Resource Mode", t.ResourceMode);
}
else
{
int selectedIndex = EditorGUILayout.Popup("Resource Mode", m_ResourceModeIndex, ResourceModeNames);
if (selectedIndex != m_ResourceModeIndex)
{
m_ResourceModeIndex = selectedIndex;
m_ResourceMode.enumValueIndex = selectedIndex + 1;
}
}
m_ReadWritePathType.enumValueIndex = (int)(ReadWritePathType)EditorGUILayout.EnumPopup("Read-Write Path Type", t.ReadWritePathType);
}
EditorGUI.EndDisabledGroup();
float minUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Min Unload Unused Assets Interval", m_MinUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (minUnloadUnusedAssetsInterval != m_MinUnloadUnusedAssetsInterval.floatValue)
{
if (EditorApplication.isPlaying)
{
t.MinUnloadUnusedAssetsInterval = minUnloadUnusedAssetsInterval;
}
else
{
m_MinUnloadUnusedAssetsInterval.floatValue = minUnloadUnusedAssetsInterval;
}
}
float maxUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Max Unload Unused Assets Interval", m_MaxUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (maxUnloadUnusedAssetsInterval != m_MaxUnloadUnusedAssetsInterval.floatValue)
{
if (EditorApplication.isPlaying)
{
t.MaxUnloadUnusedAssetsInterval = maxUnloadUnusedAssetsInterval;
}
else
{
m_MaxUnloadUnusedAssetsInterval.floatValue = maxUnloadUnusedAssetsInterval;
}
}
EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying && isEditorResourceMode);
{
float assetAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Asset Auto Release Interval", m_AssetAutoReleaseInterval.floatValue);
if (assetAutoReleaseInterval != m_AssetAutoReleaseInterval.floatValue)
{
if (EditorApplication.isPlaying)
{
t.AssetAutoReleaseInterval = assetAutoReleaseInterval;
}
else
{
m_AssetAutoReleaseInterval.floatValue = assetAutoReleaseInterval;
}
}
int assetCapacity = EditorGUILayout.DelayedIntField("Asset Capacity", m_AssetCapacity.intValue);
if (assetCapacity != m_AssetCapacity.intValue)
{
if (EditorApplication.isPlaying)
{
t.AssetCapacity = assetCapacity;
}
else
{
m_AssetCapacity.intValue = assetCapacity;
}
}
float assetExpireTime = EditorGUILayout.DelayedFloatField("Asset Expire Time", m_AssetExpireTime.floatValue);
if (assetExpireTime != m_AssetExpireTime.floatValue)
{
if (EditorApplication.isPlaying)
{
t.AssetExpireTime = assetExpireTime;
}
else
{
m_AssetExpireTime.floatValue = assetExpireTime;
}
}
int assetPriority = EditorGUILayout.DelayedIntField("Asset Priority", m_AssetPriority.intValue);
if (assetPriority != m_AssetPriority.intValue)
{
if (EditorApplication.isPlaying)
{
t.AssetPriority = assetPriority;
}
else
{
m_AssetPriority.intValue = assetPriority;
}
}
float resourceAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Resource Auto Release Interval", m_ResourceAutoReleaseInterval.floatValue);
if (resourceAutoReleaseInterval != m_ResourceAutoReleaseInterval.floatValue)
{
if (EditorApplication.isPlaying)
{
t.ResourceAutoReleaseInterval = resourceAutoReleaseInterval;
}
else
{
m_ResourceAutoReleaseInterval.floatValue = resourceAutoReleaseInterval;
}
}
int resourceCapacity = EditorGUILayout.DelayedIntField("Resource Capacity", m_ResourceCapacity.intValue);
if (resourceCapacity != m_ResourceCapacity.intValue)
{
if (EditorApplication.isPlaying)
{
t.ResourceCapacity = resourceCapacity;
}
else
{
m_ResourceCapacity.intValue = resourceCapacity;
}
}
float resourceExpireTime = EditorGUILayout.DelayedFloatField("Resource Expire Time", m_ResourceExpireTime.floatValue);
if (resourceExpireTime != m_ResourceExpireTime.floatValue)
{
if (EditorApplication.isPlaying)
{
t.ResourceExpireTime = resourceExpireTime;
}
else
{
m_ResourceExpireTime.floatValue = resourceExpireTime;
}
}
int resourcePriority = EditorGUILayout.DelayedIntField("Resource Priority", m_ResourcePriority.intValue);
if (resourcePriority != m_ResourcePriority.intValue)
{
if (EditorApplication.isPlaying)
{
t.ResourcePriority = resourcePriority;
}
else
{
m_ResourcePriority.intValue = resourcePriority;
}
}
if (m_ResourceModeIndex > 0)
{
string updatePrefixUri = EditorGUILayout.DelayedTextField("Update Prefix Uri", m_UpdatePrefixUri.stringValue);
if (updatePrefixUri != m_UpdatePrefixUri.stringValue)
{
if (EditorApplication.isPlaying)
{
t.UpdatePrefixUri = updatePrefixUri;
}
else
{
m_UpdatePrefixUri.stringValue = updatePrefixUri;
}
}
int generateReadWriteVersionListLength = EditorGUILayout.DelayedIntField("Generate Read-Write Version List Length", m_GenerateReadWriteVersionListLength.intValue);
if (generateReadWriteVersionListLength != m_GenerateReadWriteVersionListLength.intValue)
{
if (EditorApplication.isPlaying)
{
t.GenerateReadWriteVersionListLength = generateReadWriteVersionListLength;
}
else
{
m_GenerateReadWriteVersionListLength.intValue = generateReadWriteVersionListLength;
}
}
int updateRetryCount = EditorGUILayout.DelayedIntField("Update Retry Count", m_UpdateRetryCount.intValue);
if (updateRetryCount != m_UpdateRetryCount.intValue)
{
if (EditorApplication.isPlaying)
{
t.UpdateRetryCount = updateRetryCount;
}
else
{
m_UpdateRetryCount.intValue = updateRetryCount;
}
}
}
}
EditorGUI.EndDisabledGroup();
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_InstanceRoot);
m_ResourceHelperInfo.Draw();
m_LoadResourceAgentHelperInfo.Draw();
m_LoadResourceAgentHelperCount.intValue = EditorGUILayout.IntSlider("Load Resource Agent Helper Count", m_LoadResourceAgentHelperCount.intValue, 1, 128);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Unload Unused Assets", Utility.Text.Format("{0:F2} / {1:F2}", t.LastUnloadUnusedAssetsOperationElapseSeconds, t.MaxUnloadUnusedAssetsInterval));
EditorGUILayout.LabelField("Read-Only Path", t.ReadOnlyPath.ToString());
EditorGUILayout.LabelField("Read-Write Path", t.ReadWritePath.ToString());
EditorGUILayout.LabelField("Current Variant", t.CurrentVariant ?? "<Unknwon>");
EditorGUILayout.LabelField("Applicable Game Version", isEditorResourceMode ? "N/A" : t.ApplicableGameVersion ?? "<Unknwon>");
EditorGUILayout.LabelField("Internal Resource Version", isEditorResourceMode ? "N/A" : t.InternalResourceVersion.ToString());
EditorGUILayout.LabelField("Asset Count", isEditorResourceMode ? "N/A" : t.AssetCount.ToString());
EditorGUILayout.LabelField("Resource Count", isEditorResourceMode ? "N/A" : t.ResourceCount.ToString());
EditorGUILayout.LabelField("Resource Group Count", isEditorResourceMode ? "N/A" : t.ResourceGroupCount.ToString());
if (m_ResourceModeIndex > 0)
{
EditorGUILayout.LabelField("Applying Resource Pack Path", isEditorResourceMode ? "N/A" : t.ApplyingResourcePackPath ?? "<Unknwon>");
EditorGUILayout.LabelField("Apply Waiting Count", isEditorResourceMode ? "N/A" : t.ApplyWaitingCount.ToString());
EditorGUILayout.LabelField("Updating Resource Group", isEditorResourceMode ? "N/A" : t.UpdatingResourceGroup != null ? t.UpdatingResourceGroup.Name : "<Unknwon>");
EditorGUILayout.LabelField("Update Waiting Count", isEditorResourceMode ? "N/A" : t.UpdateWaitingCount.ToString());
EditorGUILayout.LabelField("Update Waiting While Playing Count", isEditorResourceMode ? "N/A" : t.UpdateWaitingWhilePlayingCount.ToString());
EditorGUILayout.LabelField("Update Candidate Count", isEditorResourceMode ? "N/A" : t.UpdateCandidateCount.ToString());
}
EditorGUILayout.LabelField("Load Total Agent Count", isEditorResourceMode ? "N/A" : t.LoadTotalAgentCount.ToString());
EditorGUILayout.LabelField("Load Free Agent Count", isEditorResourceMode ? "N/A" : t.LoadFreeAgentCount.ToString());
EditorGUILayout.LabelField("Load Working Agent Count", isEditorResourceMode ? "N/A" : t.LoadWorkingAgentCount.ToString());
EditorGUILayout.LabelField("Load Waiting Task Count", isEditorResourceMode ? "N/A" : t.LoadWaitingTaskCount.ToString());
if (!isEditorResourceMode)
{
EditorGUILayout.BeginVertical("box");
{
TaskInfo[] loadAssetInfos = t.GetAllLoadAssetInfos();
if (loadAssetInfos.Length > 0)
{
foreach (TaskInfo loadAssetInfo in loadAssetInfos)
{
DrawLoadAssetInfo(loadAssetInfo);
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "Load Asset Task Data.csv", string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[loadAssetInfos.Length + 1];
data[index++] = "Load Asset Name,Serial Id,Priority,Status";
foreach (TaskInfo loadAssetInfo in loadAssetInfos)
{
data[index++] = Utility.Text.Format("{0},{1},{2},{3}", loadAssetInfo.Description, loadAssetInfo.SerialId, loadAssetInfo.Priority, loadAssetInfo.Status);
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export load asset task CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export load asset task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
else
{
GUILayout.Label("Load Asset Task is Empty ...");
}
}
EditorGUILayout.EndVertical();
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_ResourceMode = serializedObject.FindProperty("m_ResourceMode");
m_ReadWritePathType = serializedObject.FindProperty("m_ReadWritePathType");
m_MinUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MinUnloadUnusedAssetsInterval");
m_MaxUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MaxUnloadUnusedAssetsInterval");
m_AssetAutoReleaseInterval = serializedObject.FindProperty("m_AssetAutoReleaseInterval");
m_AssetCapacity = serializedObject.FindProperty("m_AssetCapacity");
m_AssetExpireTime = serializedObject.FindProperty("m_AssetExpireTime");
m_AssetPriority = serializedObject.FindProperty("m_AssetPriority");
m_ResourceAutoReleaseInterval = serializedObject.FindProperty("m_ResourceAutoReleaseInterval");
m_ResourceCapacity = serializedObject.FindProperty("m_ResourceCapacity");
m_ResourceExpireTime = serializedObject.FindProperty("m_ResourceExpireTime");
m_ResourcePriority = serializedObject.FindProperty("m_ResourcePriority");
m_UpdatePrefixUri = serializedObject.FindProperty("m_UpdatePrefixUri");
m_GenerateReadWriteVersionListLength = serializedObject.FindProperty("m_GenerateReadWriteVersionListLength");
m_UpdateRetryCount = serializedObject.FindProperty("m_UpdateRetryCount");
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_LoadResourceAgentHelperCount = serializedObject.FindProperty("m_LoadResourceAgentHelperCount");
m_EditorResourceModeFieldInfo = target.GetType().GetField("m_EditorResourceMode", BindingFlags.NonPublic | BindingFlags.Instance);
m_ResourceHelperInfo.Init(serializedObject);
m_LoadResourceAgentHelperInfo.Init(serializedObject);
RefreshModes();
RefreshTypeNames();
}
private void DrawLoadAssetInfo(TaskInfo loadAssetInfo)
{
EditorGUILayout.LabelField(loadAssetInfo.Description, Utility.Text.Format("[SerialId]{0} [Priority]{1} [Status]{2}", loadAssetInfo.SerialId, loadAssetInfo.Priority, loadAssetInfo.Status));
}
private void RefreshModes()
{
m_ResourceModeIndex = m_ResourceMode.enumValueIndex > 0 ? m_ResourceMode.enumValueIndex - 1 : 0;
}
private void RefreshTypeNames()
{
m_ResourceHelperInfo.Refresh();
m_LoadResourceAgentHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,75 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(SceneComponent))]
internal sealed class SceneComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableLoadSceneUpdateEvent = null;
private SerializedProperty m_EnableLoadSceneDependencyAssetEvent = null;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
SceneComponent t = (SceneComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableLoadSceneUpdateEvent);
EditorGUILayout.PropertyField(m_EnableLoadSceneDependencyAssetEvent);
}
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Loaded Scene Asset Names", GetSceneNameString(t.GetLoadedSceneAssetNames()));
EditorGUILayout.LabelField("Loading Scene Asset Names", GetSceneNameString(t.GetLoadingSceneAssetNames()));
EditorGUILayout.LabelField("Unloading Scene Asset Names", GetSceneNameString(t.GetUnloadingSceneAssetNames()));
EditorGUILayout.ObjectField("Main Camera", t.MainCamera, typeof(Camera), true);
Repaint();
}
}
private void OnEnable()
{
m_EnableLoadSceneUpdateEvent = serializedObject.FindProperty("m_EnableLoadSceneUpdateEvent");
m_EnableLoadSceneDependencyAssetEvent = serializedObject.FindProperty("m_EnableLoadSceneDependencyAssetEvent");
}
private string GetSceneNameString(string[] sceneAssetNames)
{
if (sceneAssetNames == null || sceneAssetNames.Length <= 0)
{
return "<Empty>";
}
string sceneNameString = string.Empty;
foreach (string sceneAssetName in sceneAssetNames)
{
if (!string.IsNullOrEmpty(sceneNameString))
{
sceneNameString += ", ";
}
sceneNameString += SceneComponent.GetSceneName(sceneAssetName);
}
return sceneNameString;
}
}
}

View File

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

View File

@ -0,0 +1,81 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(SettingComponent))]
internal sealed class SettingComponentInspector : GameFrameworkInspector
{
private HelperInfo<SettingHelperBase> m_SettingHelperInfo = new HelperInfo<SettingHelperBase>("Setting");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
SettingComponent t = (SettingComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
m_SettingHelperInfo.Draw();
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Setting Count", t.Count >= 0 ? t.Count.ToString() : "<Unknown>");
if (t.Count > 0)
{
string[] settingNames = t.GetAllSettingNames();
foreach (string settingName in settingNames)
{
EditorGUILayout.LabelField(settingName, t.GetString(settingName));
}
}
}
if (EditorApplication.isPlaying)
{
if (GUILayout.Button("Save Settings"))
{
t.Save();
}
if (GUILayout.Button("Remove All Settings"))
{
t.RemoveAllSettings();
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_SettingHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_SettingHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,87 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(SoundComponent))]
internal sealed class SoundComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnablePlaySoundUpdateEvent = null;
private SerializedProperty m_EnablePlaySoundDependencyAssetEvent = null;
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_AudioMixer = null;
private SerializedProperty m_SoundGroups = null;
private HelperInfo<SoundHelperBase> m_SoundHelperInfo = new HelperInfo<SoundHelperBase>("Sound");
private HelperInfo<SoundGroupHelperBase> m_SoundGroupHelperInfo = new HelperInfo<SoundGroupHelperBase>("SoundGroup");
private HelperInfo<SoundAgentHelperBase> m_SoundAgentHelperInfo = new HelperInfo<SoundAgentHelperBase>("SoundAgent");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
SoundComponent t = (SoundComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnablePlaySoundUpdateEvent);
EditorGUILayout.PropertyField(m_EnablePlaySoundDependencyAssetEvent);
EditorGUILayout.PropertyField(m_InstanceRoot);
EditorGUILayout.PropertyField(m_AudioMixer);
m_SoundHelperInfo.Draw();
m_SoundGroupHelperInfo.Draw();
m_SoundAgentHelperInfo.Draw();
EditorGUILayout.PropertyField(m_SoundGroups, true);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Sound Group Count", t.SoundGroupCount.ToString());
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnablePlaySoundUpdateEvent = serializedObject.FindProperty("m_EnablePlaySoundUpdateEvent");
m_EnablePlaySoundDependencyAssetEvent = serializedObject.FindProperty("m_EnablePlaySoundDependencyAssetEvent");
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_AudioMixer = serializedObject.FindProperty("m_AudioMixer");
m_SoundGroups = serializedObject.FindProperty("m_SoundGroups");
m_SoundHelperInfo.Init(serializedObject);
m_SoundGroupHelperInfo.Init(serializedObject);
m_SoundAgentHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_SoundHelperInfo.Refresh();
m_SoundGroupHelperInfo.Refresh();
m_SoundAgentHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,154 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(UIComponent))]
internal sealed class UIComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_EnableOpenUIFormSuccessEvent = null;
private SerializedProperty m_EnableOpenUIFormFailureEvent = null;
private SerializedProperty m_EnableOpenUIFormUpdateEvent = null;
private SerializedProperty m_EnableOpenUIFormDependencyAssetEvent = null;
private SerializedProperty m_EnableCloseUIFormCompleteEvent = null;
private SerializedProperty m_InstanceAutoReleaseInterval = null;
private SerializedProperty m_InstanceCapacity = null;
private SerializedProperty m_InstanceExpireTime = null;
private SerializedProperty m_InstancePriority = null;
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_UIGroups = null;
private HelperInfo<UIFormHelperBase> m_UIFormHelperInfo = new HelperInfo<UIFormHelperBase>("UIForm");
private HelperInfo<UIGroupHelperBase> m_UIGroupHelperInfo = new HelperInfo<UIGroupHelperBase>("UIGroup");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
UIComponent t = (UIComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_EnableOpenUIFormSuccessEvent);
EditorGUILayout.PropertyField(m_EnableOpenUIFormFailureEvent);
EditorGUILayout.PropertyField(m_EnableOpenUIFormUpdateEvent);
EditorGUILayout.PropertyField(m_EnableOpenUIFormDependencyAssetEvent);
EditorGUILayout.PropertyField(m_EnableCloseUIFormCompleteEvent);
}
EditorGUI.EndDisabledGroup();
float instanceAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Instance Auto Release Interval", m_InstanceAutoReleaseInterval.floatValue);
if (instanceAutoReleaseInterval != m_InstanceAutoReleaseInterval.floatValue)
{
if (EditorApplication.isPlaying)
{
t.InstanceAutoReleaseInterval = instanceAutoReleaseInterval;
}
else
{
m_InstanceAutoReleaseInterval.floatValue = instanceAutoReleaseInterval;
}
}
int instanceCapacity = EditorGUILayout.DelayedIntField("Instance Capacity", m_InstanceCapacity.intValue);
if (instanceCapacity != m_InstanceCapacity.intValue)
{
if (EditorApplication.isPlaying)
{
t.InstanceCapacity = instanceCapacity;
}
else
{
m_InstanceCapacity.intValue = instanceCapacity;
}
}
float instanceExpireTime = EditorGUILayout.DelayedFloatField("Instance Expire Time", m_InstanceExpireTime.floatValue);
if (instanceExpireTime != m_InstanceExpireTime.floatValue)
{
if (EditorApplication.isPlaying)
{
t.InstanceExpireTime = instanceExpireTime;
}
else
{
m_InstanceExpireTime.floatValue = instanceExpireTime;
}
}
int instancePriority = EditorGUILayout.DelayedIntField("Instance Priority", m_InstancePriority.intValue);
if (instancePriority != m_InstancePriority.intValue)
{
if (EditorApplication.isPlaying)
{
t.InstancePriority = instancePriority;
}
else
{
m_InstancePriority.intValue = instancePriority;
}
}
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_InstanceRoot);
m_UIFormHelperInfo.Draw();
m_UIGroupHelperInfo.Draw();
EditorGUILayout.PropertyField(m_UIGroups, true);
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("UI Group Count", t.UIGroupCount.ToString());
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_EnableOpenUIFormSuccessEvent = serializedObject.FindProperty("m_EnableOpenUIFormSuccessEvent");
m_EnableOpenUIFormFailureEvent = serializedObject.FindProperty("m_EnableOpenUIFormFailureEvent");
m_EnableOpenUIFormUpdateEvent = serializedObject.FindProperty("m_EnableOpenUIFormUpdateEvent");
m_EnableOpenUIFormDependencyAssetEvent = serializedObject.FindProperty("m_EnableOpenUIFormDependencyAssetEvent");
m_EnableCloseUIFormCompleteEvent = serializedObject.FindProperty("m_EnableCloseUIFormCompleteEvent");
m_InstanceAutoReleaseInterval = serializedObject.FindProperty("m_InstanceAutoReleaseInterval");
m_InstanceCapacity = serializedObject.FindProperty("m_InstanceCapacity");
m_InstanceExpireTime = serializedObject.FindProperty("m_InstanceExpireTime");
m_InstancePriority = serializedObject.FindProperty("m_InstancePriority");
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_UIGroups = serializedObject.FindProperty("m_UIGroups");
m_UIFormHelperInfo.Init(serializedObject);
m_UIGroupHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_UIFormHelperInfo.Refresh();
m_UIGroupHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@ -0,0 +1,141 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UnityGameFramework.Editor
{
[CustomEditor(typeof(WebRequestComponent))]
internal sealed class WebRequestComponentInspector : GameFrameworkInspector
{
private SerializedProperty m_InstanceRoot = null;
private SerializedProperty m_WebRequestAgentHelperCount = null;
private SerializedProperty m_Timeout = null;
private HelperInfo<WebRequestAgentHelperBase> m_WebRequestAgentHelperInfo = new HelperInfo<WebRequestAgentHelperBase>("WebRequestAgent");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
WebRequestComponent t = (WebRequestComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
EditorGUILayout.PropertyField(m_InstanceRoot);
m_WebRequestAgentHelperInfo.Draw();
m_WebRequestAgentHelperCount.intValue = EditorGUILayout.IntSlider("Web Request Agent Helper Count", m_WebRequestAgentHelperCount.intValue, 1, 16);
}
EditorGUI.EndDisabledGroup();
float timeout = EditorGUILayout.Slider("Timeout", m_Timeout.floatValue, 0f, 120f);
if (timeout != m_Timeout.floatValue)
{
if (EditorApplication.isPlaying)
{
t.Timeout = timeout;
}
else
{
m_Timeout.floatValue = timeout;
}
}
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Total Agent Count", t.TotalAgentCount.ToString());
EditorGUILayout.LabelField("Free Agent Count", t.FreeAgentCount.ToString());
EditorGUILayout.LabelField("Working Agent Count", t.WorkingAgentCount.ToString());
EditorGUILayout.LabelField("Waiting Agent Count", t.WaitingTaskCount.ToString());
EditorGUILayout.BeginVertical("box");
{
TaskInfo[] webRequestInfos = t.GetAllWebRequestInfos();
if (webRequestInfos.Length > 0)
{
foreach (TaskInfo webRequestInfo in webRequestInfos)
{
DrawWebRequestInfo(webRequestInfo);
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, "WebRequest Task Data.csv", string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[webRequestInfos.Length + 1];
data[index++] = "WebRequest Uri,Serial Id,Tag,Priority,Status";
foreach (TaskInfo webRequestInfo in webRequestInfos)
{
data[index++] = Utility.Text.Format("{0},{1},{2},{3},{4}", webRequestInfo.Description, webRequestInfo.SerialId, webRequestInfo.Tag ?? string.Empty, webRequestInfo.Priority, webRequestInfo.Status);
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export web request task CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export web request task CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
else
{
GUILayout.Label("WebRequset Task is Empty ...");
}
}
EditorGUILayout.EndVertical();
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
m_WebRequestAgentHelperCount = serializedObject.FindProperty("m_WebRequestAgentHelperCount");
m_Timeout = serializedObject.FindProperty("m_Timeout");
m_WebRequestAgentHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void DrawWebRequestInfo(TaskInfo webRequestInfo)
{
EditorGUILayout.LabelField(webRequestInfo.Description, Utility.Text.Format("[SerialId]{0} [Tag]{1} [Priority]{2} [Status]{3}", webRequestInfo.SerialId, webRequestInfo.Tag ?? "<None>", webRequestInfo.Priority, webRequestInfo.Status));
}
private void RefreshTypeNames()
{
m_WebRequestAgentHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,133 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEngine;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 构建配置相关的实用函数。
/// </summary>
internal static class BuildSettings
{
private static readonly string s_ConfigurationPath = null;
private static readonly List<string> s_DefaultSceneNames = new List<string>();
private static readonly List<string> s_SearchScenePaths = new List<string>();
static BuildSettings()
{
s_ConfigurationPath = Type.GetConfigurationPath<BuildSettingsConfigPathAttribute>() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/BuildSettings.xml"));
s_DefaultSceneNames.Clear();
s_SearchScenePaths.Clear();
if (!File.Exists(s_ConfigurationPath))
{
return;
}
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(s_ConfigurationPath);
XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework");
XmlNode xmlBuildSettings = xmlRoot.SelectSingleNode("BuildSettings");
XmlNode xmlDefaultScenes = xmlBuildSettings.SelectSingleNode("DefaultScenes");
XmlNode xmlSearchScenePaths = xmlBuildSettings.SelectSingleNode("SearchScenePaths");
XmlNodeList xmlNodeList = null;
XmlNode xmlNode = null;
xmlNodeList = xmlDefaultScenes.ChildNodes;
for (int i = 0; i < xmlNodeList.Count; i++)
{
xmlNode = xmlNodeList.Item(i);
if (xmlNode.Name != "DefaultScene")
{
continue;
}
string defaultSceneName = xmlNode.Attributes.GetNamedItem("Name").Value;
s_DefaultSceneNames.Add(defaultSceneName);
}
xmlNodeList = xmlSearchScenePaths.ChildNodes;
for (int i = 0; i < xmlNodeList.Count; i++)
{
xmlNode = xmlNodeList.Item(i);
if (xmlNode.Name != "SearchScenePath")
{
continue;
}
string searchScenePath = xmlNode.Attributes.GetNamedItem("Path").Value;
s_SearchScenePaths.Add(searchScenePath);
}
}
catch
{
}
}
/// <summary>
/// 将构建场景设置为默认。
/// </summary>
[MenuItem("Game Framework/Scenes in Build Settings/Default Scenes", false, 20)]
public static void DefaultScenes()
{
HashSet<string> sceneNames = new HashSet<string>();
foreach (string sceneName in s_DefaultSceneNames)
{
sceneNames.Add(sceneName);
}
List<EditorBuildSettingsScene> scenes = new List<EditorBuildSettingsScene>();
foreach (string sceneName in sceneNames)
{
scenes.Add(new EditorBuildSettingsScene(sceneName, true));
}
EditorBuildSettings.scenes = scenes.ToArray();
Debug.Log("Set scenes of build settings to default scenes.");
}
/// <summary>
/// 将构建场景设置为所有。
/// </summary>
[MenuItem("Game Framework/Scenes in Build Settings/All Scenes", false, 21)]
public static void AllScenes()
{
HashSet<string> sceneNames = new HashSet<string>();
foreach (string sceneName in s_DefaultSceneNames)
{
sceneNames.Add(sceneName);
}
string[] sceneGuids = AssetDatabase.FindAssets("t:Scene", s_SearchScenePaths.ToArray());
foreach (string sceneGuid in sceneGuids)
{
string sceneName = AssetDatabase.GUIDToAssetPath(sceneGuid);
sceneNames.Add(sceneName);
}
List<EditorBuildSettingsScene> scenes = new List<EditorBuildSettingsScene>();
foreach (string sceneName in sceneNames)
{
scenes.Add(new EditorBuildSettingsScene(sceneName, true));
}
EditorBuildSettings.scenes = scenes.ToArray();
Debug.Log("Set scenes of build settings to all scenes.");
}
}
}

View File

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

View File

@ -0,0 +1,16 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
namespace UnityGameFramework.Editor
{
/// <summary>
/// BuildSettings 配置路径属性。
/// </summary>
public sealed class BuildSettingsConfigPathAttribute : ConfigPathAttribute
{
}
}

View File

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

View File

@ -0,0 +1,18 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 配置路径属性。
/// </summary>
public abstract class ConfigPathAttribute : Attribute
{
}
}

View File

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

View File

@ -0,0 +1,35 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
using UnityEngine;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 帮助相关的实用函数。
/// </summary>
public static class Help
{
[MenuItem("Game Framework/Documentation", false, 90)]
public static void ShowDocumentation()
{
ShowHelp("https://gameframework.cn/document/");
}
[MenuItem("Game Framework/API Reference", false, 91)]
public static void ShowApiReference()
{
ShowHelp("https://gameframework.cn/api/");
}
private static void ShowHelp(string uri)
{
Application.OpenURL(uri);
}
}
}

View File

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

View File

@ -0,0 +1,97 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
namespace UnityGameFramework.Editor
{
internal sealed class HelperInfo<T> where T : MonoBehaviour
{
private const string CustomOptionName = "<Custom>";
private readonly string m_Name;
private SerializedProperty m_HelperTypeName;
private SerializedProperty m_CustomHelper;
private string[] m_HelperTypeNames;
private int m_HelperTypeNameIndex;
public HelperInfo(string name)
{
m_Name = name;
m_HelperTypeName = null;
m_CustomHelper = null;
m_HelperTypeNames = null;
m_HelperTypeNameIndex = 0;
}
public void Init(SerializedObject serializedObject)
{
m_HelperTypeName = serializedObject.FindProperty(Utility.Text.Format("m_{0}HelperTypeName", m_Name));
m_CustomHelper = serializedObject.FindProperty(Utility.Text.Format("m_Custom{0}Helper", m_Name));
}
public void Draw()
{
string displayName = FieldNameForDisplay(m_Name);
int selectedIndex = EditorGUILayout.Popup(Utility.Text.Format("{0} Helper", displayName), m_HelperTypeNameIndex, m_HelperTypeNames);
if (selectedIndex != m_HelperTypeNameIndex)
{
m_HelperTypeNameIndex = selectedIndex;
m_HelperTypeName.stringValue = selectedIndex <= 0 ? null : m_HelperTypeNames[selectedIndex];
}
if (m_HelperTypeNameIndex <= 0)
{
EditorGUILayout.PropertyField(m_CustomHelper);
if (m_CustomHelper.objectReferenceValue == null)
{
EditorGUILayout.HelpBox(Utility.Text.Format("You must set Custom {0} Helper.", displayName), MessageType.Error);
}
}
}
public void Refresh()
{
List<string> helperTypeNameList = new List<string>
{
CustomOptionName
};
helperTypeNameList.AddRange(Type.GetRuntimeTypeNames(typeof(T)));
m_HelperTypeNames = helperTypeNameList.ToArray();
m_HelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_HelperTypeName.stringValue))
{
m_HelperTypeNameIndex = helperTypeNameList.IndexOf(m_HelperTypeName.stringValue);
if (m_HelperTypeNameIndex <= 0)
{
m_HelperTypeNameIndex = 0;
m_HelperTypeName.stringValue = null;
}
}
}
private string FieldNameForDisplay(string fieldName)
{
if (string.IsNullOrEmpty(fieldName))
{
return string.Empty;
}
string str = Regex.Replace(fieldName, @"^m_", string.Empty);
str = Regex.Replace(str, @"((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", @" $1").TrimStart();
return str;
}
}
}

View File

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

View File

@ -0,0 +1,122 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
#if !UNITY_2019_1_OR_NEWER
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditorInternal;
using UnityEngine;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 日志重定向相关的实用函数。
/// </summary>
internal static class LogRedirection
{
private static readonly Regex LogRegex = new Regex(@" \(at (.+)\:(\d+)\)\r?\n");
[OnOpenAsset(0)]
private static bool OnOpenAsset(int instanceId, int line)
{
string selectedStackTrace = GetSelectedStackTrace();
if (string.IsNullOrEmpty(selectedStackTrace))
{
return false;
}
if (!selectedStackTrace.Contains("UnityGameFramework.Runtime.DefaultLogHelper:Log"))
{
return false;
}
Match match = LogRegex.Match(selectedStackTrace);
if (!match.Success)
{
return false;
}
if (!match.Groups[1].Value.Contains("DefaultLogHelper.cs"))
{
return false;
}
match = match.NextMatch();
if (!match.Success)
{
return false;
}
if (match.Groups[1].Value.Contains("GameFrameworkLog.cs"))
{
match = match.NextMatch();
if (!match.Success)
{
return false;
}
}
if (match.Groups[1].Value.Contains("Log.cs"))
{
match = match.NextMatch();
if (!match.Success)
{
return false;
}
}
InternalEditorUtility.OpenFileAtLineExternal(Path.Combine(Application.dataPath, match.Groups[1].Value.Substring(7)), int.Parse(match.Groups[2].Value));
return true;
}
private static string GetSelectedStackTrace()
{
Assembly editorWindowAssembly = typeof(EditorWindow).Assembly;
if (editorWindowAssembly == null)
{
return null;
}
System.Type consoleWindowType = editorWindowAssembly.GetType("UnityEditor.ConsoleWindow");
if (consoleWindowType == null)
{
return null;
}
FieldInfo consoleWindowFieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
if (consoleWindowFieldInfo == null)
{
return null;
}
EditorWindow consoleWindow = consoleWindowFieldInfo.GetValue(null) as EditorWindow;
if (consoleWindow == null)
{
return null;
}
if (consoleWindow != EditorWindow.focusedWindow)
{
return null;
}
FieldInfo activeTextFieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
if (activeTextFieldInfo == null)
{
return null;
}
return (string)activeTextFieldInfo.GetValue(consoleWindow);
}
}
}
#endif

View File

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

View File

@ -0,0 +1,179 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEditor;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 日志脚本宏定义。
/// </summary>
public static class LogScriptingDefineSymbols
{
private const string EnableLogScriptingDefineSymbol = "ENABLE_LOG";
private const string EnableDebugAndAboveLogScriptingDefineSymbol = "ENABLE_DEBUG_AND_ABOVE_LOG";
private const string EnableInfoAndAboveLogScriptingDefineSymbol = "ENABLE_INFO_AND_ABOVE_LOG";
private const string EnableWarningAndAboveLogScriptingDefineSymbol = "ENABLE_WARNING_AND_ABOVE_LOG";
private const string EnableErrorAndAboveLogScriptingDefineSymbol = "ENABLE_ERROR_AND_ABOVE_LOG";
private const string EnableFatalAndAboveLogScriptingDefineSymbol = "ENABLE_FATAL_AND_ABOVE_LOG";
private const string EnableDebugLogScriptingDefineSymbol = "ENABLE_DEBUG_LOG";
private const string EnableInfoLogScriptingDefineSymbol = "ENABLE_INFO_LOG";
private const string EnableWarningLogScriptingDefineSymbol = "ENABLE_WARNING_LOG";
private const string EnableErrorLogScriptingDefineSymbol = "ENABLE_ERROR_LOG";
private const string EnableFatalLogScriptingDefineSymbol = "ENABLE_FATAL_LOG";
private static readonly string[] AboveLogScriptingDefineSymbols = new string[]
{
EnableDebugAndAboveLogScriptingDefineSymbol,
EnableInfoAndAboveLogScriptingDefineSymbol,
EnableWarningAndAboveLogScriptingDefineSymbol,
EnableErrorAndAboveLogScriptingDefineSymbol,
EnableFatalAndAboveLogScriptingDefineSymbol
};
private static readonly string[] SpecifyLogScriptingDefineSymbols = new string[]
{
EnableDebugLogScriptingDefineSymbol,
EnableInfoLogScriptingDefineSymbol,
EnableWarningLogScriptingDefineSymbol,
EnableErrorLogScriptingDefineSymbol,
EnableFatalLogScriptingDefineSymbol
};
/// <summary>
/// 禁用所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Disable All Logs", false, 30)]
public static void DisableAllLogs()
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableLogScriptingDefineSymbol);
foreach (string specifyLogScriptingDefineSymbol in SpecifyLogScriptingDefineSymbols)
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(specifyLogScriptingDefineSymbol);
}
foreach (string aboveLogScriptingDefineSymbol in AboveLogScriptingDefineSymbols)
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
}
}
/// <summary>
/// 开启所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable All Logs", false, 31)]
public static void EnableAllLogs()
{
DisableAllLogs();
ScriptingDefineSymbols.AddScriptingDefineSymbol(EnableLogScriptingDefineSymbol);
}
/// <summary>
/// 开启调试及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Debug And Above Logs", false, 32)]
public static void EnableDebugAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableDebugAndAboveLogScriptingDefineSymbol);
}
/// <summary>
/// 开启信息及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Info And Above Logs", false, 33)]
public static void EnableInfoAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableInfoAndAboveLogScriptingDefineSymbol);
}
/// <summary>
/// 开启警告及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Warning And Above Logs", false, 34)]
public static void EnableWarningAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableWarningAndAboveLogScriptingDefineSymbol);
}
/// <summary>
/// 开启错误及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Error And Above Logs", false, 35)]
public static void EnableErrorAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableErrorAndAboveLogScriptingDefineSymbol);
}
/// <summary>
/// 开启严重错误及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Fatal And Above Logs", false, 36)]
public static void EnableFatalAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableFatalAndAboveLogScriptingDefineSymbol);
}
/// <summary>
/// 设置日志脚本宏定义。
/// </summary>
/// <param name="aboveLogScriptingDefineSymbol">要设置的日志脚本宏定义。</param>
public static void SetAboveLogScriptingDefineSymbol(string aboveLogScriptingDefineSymbol)
{
if (string.IsNullOrEmpty(aboveLogScriptingDefineSymbol))
{
return;
}
foreach (string i in AboveLogScriptingDefineSymbols)
{
if (i == aboveLogScriptingDefineSymbol)
{
DisableAllLogs();
ScriptingDefineSymbols.AddScriptingDefineSymbol(aboveLogScriptingDefineSymbol);
return;
}
}
}
/// <summary>
/// 设置日志脚本宏定义。
/// </summary>
/// <param name="specifyLogScriptingDefineSymbols">要设置的日志脚本宏定义。</param>
public static void SetSpecifyLogScriptingDefineSymbols(string[] specifyLogScriptingDefineSymbols)
{
if (specifyLogScriptingDefineSymbols == null || specifyLogScriptingDefineSymbols.Length <= 0)
{
return;
}
bool removed = false;
foreach (string specifyLogScriptingDefineSymbol in specifyLogScriptingDefineSymbols)
{
if (string.IsNullOrEmpty(specifyLogScriptingDefineSymbol))
{
continue;
}
foreach (string i in SpecifyLogScriptingDefineSymbols)
{
if (i == specifyLogScriptingDefineSymbol)
{
if (!removed)
{
removed = true;
DisableAllLogs();
}
ScriptingDefineSymbols.AddScriptingDefineSymbol(specifyLogScriptingDefineSymbol);
break;
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,91 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 打开文件夹相关的实用函数。
/// </summary>
public static class OpenFolder
{
/// <summary>
/// 打开 Data Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Data Path", false, 10)]
public static void OpenFolderDataPath()
{
Execute(Application.dataPath);
}
/// <summary>
/// 打开 Persistent Data Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Persistent Data Path", false, 11)]
public static void OpenFolderPersistentDataPath()
{
Execute(Application.persistentDataPath);
}
/// <summary>
/// 打开 Streaming Assets Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Streaming Assets Path", false, 12)]
public static void OpenFolderStreamingAssetsPath()
{
Execute(Application.streamingAssetsPath);
}
/// <summary>
/// 打开 Temporary Cache Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Temporary Cache Path", false, 13)]
public static void OpenFolderTemporaryCachePath()
{
Execute(Application.temporaryCachePath);
}
#if UNITY_2018_3_OR_NEWER
/// <summary>
/// 打开 Console Log Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Console Log Path", false, 14)]
public static void OpenFolderConsoleLogPath()
{
Execute(System.IO.Path.GetDirectoryName(Application.consoleLogPath));
}
#endif
/// <summary>
/// 打开指定路径的文件夹。
/// </summary>
/// <param name="folder">要打开的文件夹的路径。</param>
public static void Execute(string folder)
{
folder = Utility.Text.Format("\"{0}\"", folder);
switch (Application.platform)
{
case RuntimePlatform.WindowsEditor:
Process.Start("Explorer.exe", folder.Replace('/', '\\'));
break;
case RuntimePlatform.OSXEditor:
Process.Start("open", folder);
break;
default:
throw new GameFrameworkException(Utility.Text.Format("Not support open folder on '{0}' platform.", Application.platform));
}
}
}
}

View File

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

View File

@ -0,0 +1,157 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Collections.Generic;
using UnityEditor;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 脚本宏定义。
/// </summary>
public static class ScriptingDefineSymbols
{
private static readonly BuildTargetGroup[] BuildTargetGroups = new BuildTargetGroup[]
{
BuildTargetGroup.Standalone,
BuildTargetGroup.iOS,
BuildTargetGroup.Android,
BuildTargetGroup.WSA,
BuildTargetGroup.WebGL
};
/// <summary>
/// 检查指定平台是否存在指定的脚本宏定义。
/// </summary>
/// <param name="buildTargetGroup">要检查脚本宏定义的平台。</param>
/// <param name="scriptingDefineSymbol">要检查的脚本宏定义。</param>
/// <returns>指定平台是否存在指定的脚本宏定义。</returns>
public static bool HasScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
{
if (string.IsNullOrEmpty(scriptingDefineSymbol))
{
return false;
}
string[] scriptingDefineSymbols = GetScriptingDefineSymbols(buildTargetGroup);
foreach (string i in scriptingDefineSymbols)
{
if (i == scriptingDefineSymbol)
{
return true;
}
}
return false;
}
/// <summary>
/// 为指定平台增加指定的脚本宏定义。
/// </summary>
/// <param name="buildTargetGroup">要增加脚本宏定义的平台。</param>
/// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param>
public static void AddScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
{
if (string.IsNullOrEmpty(scriptingDefineSymbol))
{
return;
}
if (HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol))
{
return;
}
List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup))
{
scriptingDefineSymbol
};
SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
}
/// <summary>
/// 为指定平台移除指定的脚本宏定义。
/// </summary>
/// <param name="buildTargetGroup">要移除脚本宏定义的平台。</param>
/// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param>
public static void RemoveScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
{
if (string.IsNullOrEmpty(scriptingDefineSymbol))
{
return;
}
if (!HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol))
{
return;
}
List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup));
while (scriptingDefineSymbols.Contains(scriptingDefineSymbol))
{
scriptingDefineSymbols.Remove(scriptingDefineSymbol);
}
SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
}
/// <summary>
/// 为所有平台增加指定的脚本宏定义。
/// </summary>
/// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param>
public static void AddScriptingDefineSymbol(string scriptingDefineSymbol)
{
if (string.IsNullOrEmpty(scriptingDefineSymbol))
{
return;
}
foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups)
{
AddScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
}
}
/// <summary>
/// 为所有平台移除指定的脚本宏定义。
/// </summary>
/// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param>
public static void RemoveScriptingDefineSymbol(string scriptingDefineSymbol)
{
if (string.IsNullOrEmpty(scriptingDefineSymbol))
{
return;
}
foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups)
{
RemoveScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
}
}
/// <summary>
/// 获取指定平台的脚本宏定义。
/// </summary>
/// <param name="buildTargetGroup">要获取脚本宏定义的平台。</param>
/// <returns>平台的脚本宏定义。</returns>
public static string[] GetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup)
{
return PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';');
}
/// <summary>
/// 设置指定平台的脚本宏定义。
/// </summary>
/// <param name="buildTargetGroup">要设置脚本宏定义的平台。</param>
/// <param name="scriptingDefineSymbols">要设置的脚本宏定义。</param>
public static void SetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup, string[] scriptingDefineSymbols)
{
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", scriptingDefineSymbols));
}
}
}

View File

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

View File

@ -0,0 +1,127 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Collections.Generic;
using System.Reflection;
namespace UnityGameFramework.Editor
{
/// <summary>
/// 类型相关的实用函数。
/// </summary>
internal static class Type
{
private static readonly string[] RuntimeAssemblyNames =
{
#if UNITY_2017_3_OR_NEWER
"UnityGameFramework.Runtime",
#endif
"Assembly-CSharp",
};
private static readonly string[] RuntimeOrEditorAssemblyNames =
{
#if UNITY_2017_3_OR_NEWER
"UnityGameFramework.Runtime",
#endif
"Assembly-CSharp",
#if UNITY_2017_3_OR_NEWER
"UnityGameFramework.Editor",
#endif
"Assembly-CSharp-Editor",
};
/// <summary>
/// 获取配置路径。
/// </summary>
/// <typeparam name="T">配置类型。</typeparam>
/// <returns>配置路径。</returns>
internal static string GetConfigurationPath<T>() where T : ConfigPathAttribute
{
foreach (System.Type type in Utility.Assembly.GetTypes())
{
if (!type.IsAbstract || !type.IsSealed)
{
continue;
}
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
if (fieldInfo.FieldType == typeof(string) && fieldInfo.IsDefined(typeof(T), false))
{
return (string)fieldInfo.GetValue(null);
}
}
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
if (propertyInfo.PropertyType == typeof(string) && propertyInfo.IsDefined(typeof(T), false))
{
return (string)propertyInfo.GetValue(null, null);
}
}
}
return null;
}
/// <summary>
/// 在运行时程序集中获取指定基类的所有子类的名称。
/// </summary>
/// <param name="typeBase">基类类型。</param>
/// <returns>指定基类的所有子类的名称。</returns>
internal static string[] GetRuntimeTypeNames(System.Type typeBase)
{
return GetTypeNames(typeBase, RuntimeAssemblyNames);
}
/// <summary>
/// 在运行时或编辑器程序集中获取指定基类的所有子类的名称。
/// </summary>
/// <param name="typeBase">基类类型。</param>
/// <returns>指定基类的所有子类的名称。</returns>
internal static string[] GetRuntimeOrEditorTypeNames(System.Type typeBase)
{
return GetTypeNames(typeBase, RuntimeOrEditorAssemblyNames);
}
private static string[] GetTypeNames(System.Type typeBase, string[] assemblyNames)
{
List<string> typeNames = new List<string>();
foreach (string assemblyName in assemblyNames)
{
Assembly assembly = null;
try
{
assembly = Assembly.Load(assemblyName);
}
catch
{
continue;
}
if (assembly == null)
{
continue;
}
System.Type[] types = assembly.GetTypes();
foreach (System.Type type in types)
{
if (type.IsClass && !type.IsAbstract && typeBase.IsAssignableFrom(type))
{
typeNames.Add(type.FullName);
}
}
}
typeNames.Sort();
return typeNames.ToArray();
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,21 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
namespace UnityGameFramework.Editor.ResourceTools
{
public enum AssetsOrder : byte
{
AssetNameAsc,
AssetNameDesc,
DependencyResourceCountAsc,
DependencyResourceCountDesc,
DependencyAssetCountAsc,
DependencyAssetCountDesc,
ScatteredDependencyAssetCountAsc,
ScatteredDependencyAssetCountDesc,
}
}

View File

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

View File

@ -0,0 +1,96 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Collections.Generic;
namespace UnityGameFramework.Editor.ResourceTools
{
public sealed class DependencyData
{
private List<Resource> m_DependencyResources;
private List<Asset> m_DependencyAssets;
private List<string> m_ScatteredDependencyAssetNames;
public DependencyData()
{
m_DependencyResources = new List<Resource>();
m_DependencyAssets = new List<Asset>();
m_ScatteredDependencyAssetNames = new List<string>();
}
public int DependencyResourceCount
{
get
{
return m_DependencyResources.Count;
}
}
public int DependencyAssetCount
{
get
{
return m_DependencyAssets.Count;
}
}
public int ScatteredDependencyAssetCount
{
get
{
return m_ScatteredDependencyAssetNames.Count;
}
}
public void AddDependencyAsset(Asset asset)
{
if (!m_DependencyResources.Contains(asset.Resource))
{
m_DependencyResources.Add(asset.Resource);
}
m_DependencyAssets.Add(asset);
}
public void AddScatteredDependencyAsset(string dependencyAssetName)
{
m_ScatteredDependencyAssetNames.Add(dependencyAssetName);
}
public Resource[] GetDependencyResources()
{
return m_DependencyResources.ToArray();
}
public Asset[] GetDependencyAssets()
{
return m_DependencyAssets.ToArray();
}
public string[] GetScatteredDependencyAssetNames()
{
return m_ScatteredDependencyAssetNames.ToArray();
}
public void RefreshData()
{
m_DependencyResources.Sort(DependencyResourcesComparer);
m_DependencyAssets.Sort(DependencyAssetsComparer);
m_ScatteredDependencyAssetNames.Sort();
}
private int DependencyResourcesComparer(Resource a, Resource b)
{
return a.FullName.CompareTo(b.FullName);
}
private int DependencyAssetsComparer(Asset a, Asset b)
{
return a.Name.CompareTo(b.Name);
}
}
}

View File

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

View File

@ -0,0 +1,533 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace UnityGameFramework.Editor.ResourceTools
{
/// <summary>
/// 资源分析器。
/// </summary>
internal sealed class ResourceAnalyzer : EditorWindow
{
private ResourceAnalyzerController m_Controller = null;
private bool m_Analyzed = false;
private int m_ToolbarIndex = 0;
private int m_AssetCount = 0;
private string[] m_CachedAssetNames = null;
private int m_SelectedAssetIndex = -1;
private string m_SelectedAssetName = null;
private DependencyData m_SelectedDependencyData = null;
private AssetsOrder m_AssetsOrder = AssetsOrder.AssetNameAsc;
private string m_AssetsFilter = null;
private Vector2 m_AssetsScroll = Vector2.zero;
private Vector2 m_DependencyResourcesScroll = Vector2.zero;
private Vector2 m_DependencyAssetsScroll = Vector2.zero;
private Vector2 m_ScatteredDependencyAssetsScroll = Vector2.zero;
private int m_ScatteredAssetCount = 0;
private string[] m_CachedScatteredAssetNames = null;
private int m_SelectedScatteredAssetIndex = -1;
private string m_SelectedScatteredAssetName = null;
private Asset[] m_SelectedHostAssets = null;
private ScatteredAssetsOrder m_ScatteredAssetsOrder = ScatteredAssetsOrder.AssetNameAsc;
private string m_ScatteredAssetsFilter = null;
private Vector2 m_ScatteredAssetsScroll = Vector2.zero;
private Vector2 m_HostAssetsScroll = Vector2.zero;
private int m_CircularDependencyCount = 0;
private string[][] m_CachedCircularDependencyDatas = null;
private Vector2 m_CircularDependencyScroll = Vector2.zero;
[MenuItem("Game Framework/Resource Tools/Resource Analyzer", false, 42)]
private static void Open()
{
ResourceAnalyzer window = GetWindow<ResourceAnalyzer>("Resource Analyzer", true);
window.minSize = new Vector2(800f, 600f);
}
private void OnEnable()
{
m_Controller = new ResourceAnalyzerController();
m_Controller.OnLoadingResource += OnLoadingResource;
m_Controller.OnLoadingAsset += OnLoadingAsset;
m_Controller.OnLoadCompleted += OnLoadCompleted;
m_Controller.OnAnalyzingAsset += OnAnalyzingAsset;
m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted;
m_Analyzed = false;
m_ToolbarIndex = 0;
m_AssetCount = 0;
m_CachedAssetNames = null;
m_SelectedAssetIndex = -1;
m_SelectedAssetName = null;
m_SelectedDependencyData = new DependencyData();
m_AssetsOrder = AssetsOrder.ScatteredDependencyAssetCountDesc;
m_AssetsFilter = null;
m_AssetsScroll = Vector2.zero;
m_DependencyResourcesScroll = Vector2.zero;
m_DependencyAssetsScroll = Vector2.zero;
m_ScatteredDependencyAssetsScroll = Vector2.zero;
m_ScatteredAssetCount = 0;
m_CachedScatteredAssetNames = null;
m_SelectedScatteredAssetIndex = -1;
m_SelectedScatteredAssetName = null;
m_SelectedHostAssets = new Asset[] { };
m_ScatteredAssetsOrder = ScatteredAssetsOrder.HostAssetCountDesc;
m_ScatteredAssetsFilter = null;
m_ScatteredAssetsScroll = Vector2.zero;
m_HostAssetsScroll = Vector2.zero;
m_CircularDependencyCount = 0;
m_CachedCircularDependencyDatas = null;
m_CircularDependencyScroll = Vector2.zero;
}
private void OnGUI()
{
EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
{
GUILayout.Space(5f);
int toolbarIndex = GUILayout.Toolbar(m_ToolbarIndex, new string[] { "Summary", "Asset Dependency Viewer", "Scattered Asset Viewer", "Circular Dependency Viewer" }, GUILayout.Height(30f));
if (toolbarIndex != m_ToolbarIndex)
{
m_ToolbarIndex = toolbarIndex;
GUI.FocusControl(null);
}
switch (m_ToolbarIndex)
{
case 0:
DrawSummary();
break;
case 1:
DrawAssetDependencyViewer();
break;
case 2:
DrawScatteredAssetViewer();
break;
case 3:
DrawCircularDependencyViewer();
break;
}
}
EditorGUILayout.EndVertical();
}
private void DrawAnalyzeButton()
{
if (!m_Analyzed)
{
EditorGUILayout.HelpBox("Please analyze first.", MessageType.Info);
}
if (GUILayout.Button("Analyze", GUILayout.Height(30f)))
{
m_Controller.Clear();
m_SelectedAssetIndex = -1;
m_SelectedAssetName = null;
m_SelectedDependencyData = new DependencyData();
m_SelectedScatteredAssetIndex = -1;
m_SelectedScatteredAssetName = null;
m_SelectedHostAssets = new Asset[] { };
if (m_Controller.Prepare())
{
m_Controller.Analyze();
m_Analyzed = true;
m_AssetCount = m_Controller.GetAssetNames().Length;
m_ScatteredAssetCount = m_Controller.GetScatteredAssetNames().Length;
m_CachedCircularDependencyDatas = m_Controller.GetCircularDependencyDatas();
m_CircularDependencyCount = m_CachedCircularDependencyDatas.Length;
OnAssetsOrderOrFilterChanged();
OnScatteredAssetsOrderOrFilterChanged();
}
else
{
EditorUtility.DisplayDialog("Resource Analyze", "Can not parse 'ResourceCollection.xml', please use 'Resource Editor' tool first.", "OK");
}
}
}
private void DrawSummary()
{
DrawAnalyzeButton();
}
private void DrawAssetDependencyViewer()
{
if (!m_Analyzed)
{
DrawAnalyzeButton();
return;
}
EditorGUILayout.BeginHorizontal();
{
GUILayout.Space(5f);
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f));
{
GUILayout.Space(5f);
string title = null;
if (string.IsNullOrEmpty(m_AssetsFilter))
{
title = Utility.Text.Format("Assets In Resources ({0})", m_AssetCount);
}
else
{
title = Utility.Text.Format("Assets In Resources ({0}/{1})", m_CachedAssetNames.Length, m_AssetCount);
}
EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 150f));
{
m_AssetsScroll = EditorGUILayout.BeginScrollView(m_AssetsScroll);
{
int selectedIndex = GUILayout.SelectionGrid(m_SelectedAssetIndex, m_CachedAssetNames, 1, "toggle");
if (selectedIndex != m_SelectedAssetIndex)
{
m_SelectedAssetIndex = selectedIndex;
m_SelectedAssetName = m_CachedAssetNames[selectedIndex];
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("Asset Name", m_SelectedAssetName ?? "<None>");
EditorGUILayout.LabelField("Resource Name", m_SelectedAssetName == null ? "<None>" : m_Controller.GetAsset(m_SelectedAssetName).Resource.FullName);
EditorGUILayout.BeginHorizontal();
{
AssetsOrder assetsOrder = (AssetsOrder)EditorGUILayout.EnumPopup("Order by", m_AssetsOrder);
if (assetsOrder != m_AssetsOrder)
{
m_AssetsOrder = assetsOrder;
OnAssetsOrderOrFilterChanged();
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
string assetsFilter = EditorGUILayout.TextField("Assets Filter", m_AssetsFilter);
if (assetsFilter != m_AssetsFilter)
{
m_AssetsFilter = assetsFilter;
OnAssetsOrderOrFilterChanged();
}
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_AssetsFilter));
{
if (GUILayout.Button("x", GUILayout.Width(20f)))
{
m_AssetsFilter = null;
GUI.FocusControl(null);
OnAssetsOrderOrFilterChanged();
}
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f));
{
GUILayout.Space(5f);
EditorGUILayout.LabelField(Utility.Text.Format("Dependency Resources ({0})", m_SelectedDependencyData.DependencyResourceCount), EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.2f));
{
m_DependencyResourcesScroll = EditorGUILayout.BeginScrollView(m_DependencyResourcesScroll);
{
Resource[] dependencyResources = m_SelectedDependencyData.GetDependencyResources();
foreach (Resource dependencyResource in dependencyResources)
{
GUILayout.Label(dependencyResource.FullName);
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
EditorGUILayout.LabelField(Utility.Text.Format("Dependency Assets ({0})", m_SelectedDependencyData.DependencyAssetCount), EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.3f));
{
m_DependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_DependencyAssetsScroll);
{
Asset[] dependencyAssets = m_SelectedDependencyData.GetDependencyAssets();
foreach (Asset dependencyAsset in dependencyAssets)
{
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("GO", GUILayout.Width(30f)))
{
m_SelectedAssetName = dependencyAsset.Name;
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
}
GUILayout.Label(dependencyAsset.Name);
}
EditorGUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
EditorGUILayout.LabelField(Utility.Text.Format("Scattered Dependency Assets ({0})", m_SelectedDependencyData.ScatteredDependencyAssetCount), EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.5f - 116f));
{
m_ScatteredDependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredDependencyAssetsScroll);
{
string[] scatteredDependencyAssetNames = m_SelectedDependencyData.GetScatteredDependencyAssetNames();
foreach (string scatteredDependencyAssetName in scatteredDependencyAssetNames)
{
EditorGUILayout.BeginHorizontal();
{
int count = m_Controller.GetHostAssets(scatteredDependencyAssetName).Length;
EditorGUI.BeginDisabledGroup(count < 2);
{
if (GUILayout.Button("GO", GUILayout.Width(30f)))
{
m_SelectedScatteredAssetName = scatteredDependencyAssetName;
m_SelectedScatteredAssetIndex = new List<string>(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName);
m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName);
m_ToolbarIndex = 2;
GUI.FocusControl(null);
}
}
EditorGUI.EndDisabledGroup();
GUILayout.Label(count > 1 ? Utility.Text.Format("{0} ({1})", scatteredDependencyAssetName, count) : scatteredDependencyAssetName);
}
EditorGUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
}
private void DrawScatteredAssetViewer()
{
if (!m_Analyzed)
{
DrawAnalyzeButton();
return;
}
EditorGUILayout.BeginHorizontal();
{
GUILayout.Space(5f);
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f));
{
GUILayout.Space(5f);
string title = null;
if (string.IsNullOrEmpty(m_ScatteredAssetsFilter))
{
title = Utility.Text.Format("Scattered Assets ({0})", m_ScatteredAssetCount);
}
else
{
title = Utility.Text.Format("Scattered Assets ({0}/{1})", m_CachedScatteredAssetNames.Length, m_ScatteredAssetCount);
}
EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 132f));
{
m_ScatteredAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredAssetsScroll);
{
int selectedIndex = GUILayout.SelectionGrid(m_SelectedScatteredAssetIndex, m_CachedScatteredAssetNames, 1, "toggle");
if (selectedIndex != m_SelectedScatteredAssetIndex)
{
m_SelectedScatteredAssetIndex = selectedIndex;
m_SelectedScatteredAssetName = m_CachedScatteredAssetNames[selectedIndex];
m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName);
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("Scattered Asset Name", m_SelectedScatteredAssetName ?? "<None>");
EditorGUILayout.BeginHorizontal();
{
ScatteredAssetsOrder scatteredAssetsOrder = (ScatteredAssetsOrder)EditorGUILayout.EnumPopup("Order by", m_ScatteredAssetsOrder);
if (scatteredAssetsOrder != m_ScatteredAssetsOrder)
{
m_ScatteredAssetsOrder = scatteredAssetsOrder;
OnScatteredAssetsOrderOrFilterChanged();
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
string scatteredAssetsFilter = EditorGUILayout.TextField("Assets Filter", m_ScatteredAssetsFilter);
if (scatteredAssetsFilter != m_ScatteredAssetsFilter)
{
m_ScatteredAssetsFilter = scatteredAssetsFilter;
OnScatteredAssetsOrderOrFilterChanged();
}
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_ScatteredAssetsFilter));
{
if (GUILayout.Button("x", GUILayout.Width(20f)))
{
m_ScatteredAssetsFilter = null;
GUI.FocusControl(null);
OnScatteredAssetsOrderOrFilterChanged();
}
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f));
{
GUILayout.Space(5f);
EditorGUILayout.LabelField(Utility.Text.Format("Host Assets ({0})", m_SelectedHostAssets.Length), EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 68f));
{
m_HostAssetsScroll = EditorGUILayout.BeginScrollView(m_HostAssetsScroll);
{
foreach (Asset hostAsset in m_SelectedHostAssets)
{
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("GO", GUILayout.Width(30f)))
{
m_SelectedAssetName = hostAsset.Name;
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
m_ToolbarIndex = 1;
GUI.FocusControl(null);
}
GUILayout.Label(Utility.Text.Format("{0} [{1}]", hostAsset.Name, hostAsset.Resource.FullName));
}
EditorGUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
}
private void DrawCircularDependencyViewer()
{
if (!m_Analyzed)
{
DrawAnalyzeButton();
return;
}
EditorGUILayout.BeginHorizontal();
{
GUILayout.Space(5f);
EditorGUILayout.BeginVertical();
{
GUILayout.Space(5f);
EditorGUILayout.LabelField(Utility.Text.Format("Circular Dependency ({0})", m_CircularDependencyCount), EditorStyles.boldLabel);
m_CircularDependencyScroll = EditorGUILayout.BeginScrollView(m_CircularDependencyScroll);
{
int count = 0;
foreach (string[] circularDependencyData in m_CachedCircularDependencyDatas)
{
GUILayout.Label(Utility.Text.Format("{0}) {1}", ++count, circularDependencyData[circularDependencyData.Length - 1]), EditorStyles.boldLabel);
EditorGUILayout.BeginVertical("box");
{
foreach (string circularDependency in circularDependencyData)
{
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label(circularDependency);
if (GUILayout.Button("GO", GUILayout.Width(30f)))
{
m_SelectedAssetName = circularDependency;
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
m_ToolbarIndex = 1;
GUI.FocusControl(null);
}
}
EditorGUILayout.EndHorizontal();
}
}
EditorGUILayout.EndVertical();
GUILayout.Space(5f);
}
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
}
private void OnAssetsOrderOrFilterChanged()
{
m_CachedAssetNames = m_Controller.GetAssetNames(m_AssetsOrder, m_AssetsFilter);
if (!string.IsNullOrEmpty(m_SelectedAssetName))
{
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
}
}
private void OnScatteredAssetsOrderOrFilterChanged()
{
m_CachedScatteredAssetNames = m_Controller.GetScatteredAssetNames(m_ScatteredAssetsOrder, m_ScatteredAssetsFilter);
if (!string.IsNullOrEmpty(m_SelectedScatteredAssetName))
{
m_SelectedScatteredAssetIndex = new List<string>(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName);
}
}
private void OnLoadingResource(int index, int count)
{
EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count);
}
private void OnLoadingAsset(int index, int count)
{
EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count);
}
private void OnLoadCompleted()
{
EditorUtility.ClearProgressBar();
}
private void OnAnalyzingAsset(int index, int count)
{
EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index, count), (float)index / count);
}
private void OnAnalyzeCompleted()
{
EditorUtility.ClearProgressBar();
}
}
}

View File

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

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
namespace UnityGameFramework.Editor.ResourceTools
{
public sealed partial class ResourceAnalyzerController
{
private sealed class CircularDependencyChecker
{
private readonly Stamp[] m_Stamps;
public CircularDependencyChecker(Stamp[] stamps)
{
m_Stamps = stamps;
}
public string[][] Check()
{
HashSet<string> hosts = new HashSet<string>();
foreach (Stamp stamp in m_Stamps)
{
hosts.Add(stamp.HostAssetName);
}
List<string[]> results = new List<string[]>();
foreach (string host in hosts)
{
LinkedList<string> route = new LinkedList<string>();
HashSet<string> visited = new HashSet<string>();
if (Check(host, route, visited))
{
results.Add(route.ToArray());
}
}
return results.ToArray();
}
private bool Check(string host, LinkedList<string> route, HashSet<string> visited)
{
visited.Add(host);
route.AddLast(host);
foreach (Stamp stamp in m_Stamps)
{
if (host != stamp.HostAssetName)
{
continue;
}
if (visited.Contains(stamp.DependencyAssetName))
{
route.AddLast(stamp.DependencyAssetName);
return true;
}
if (Check(stamp.DependencyAssetName, route, visited))
{
return true;
}
}
route.RemoveLast();
visited.Remove(host);
return false;
}
}
}
}

View File

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

View File

@ -0,0 +1,43 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Runtime.InteropServices;
namespace UnityGameFramework.Editor.ResourceTools
{
public sealed partial class ResourceAnalyzerController
{
[StructLayout(LayoutKind.Auto)]
private struct Stamp
{
private readonly string m_HostAssetName;
private readonly string m_DependencyAssetName;
public Stamp(string hostAssetName, string dependencyAssetName)
{
m_HostAssetName = hostAssetName;
m_DependencyAssetName = dependencyAssetName;
}
public string HostAssetName
{
get
{
return m_HostAssetName;
}
}
public string DependencyAssetName
{
get
{
return m_DependencyAssetName;
}
}
}
}
}

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