Browse Source

特供版

“hujiajun” 4 weeks ago
parent
commit
d09e6b177a
100 changed files with 8544 additions and 5426 deletions
  1. 1 1
      Assets/Editor.meta
  2. 1 1
      Assets/Editor/change.cs.meta
  3. 8 8
      Assets/FrameWork/Login/Login.prefab
  4. 17 0
      Assets/FrameWork/PlayerToImage.prefab
  5. 1 1
      Assets/FrameWork/ProjectManager/Main.prefab
  6. 1 5123
      Assets/FrameWork/ProjectManager/RTC/RoomMain/RoomMain.prefab
  7. 0 13
      Assets/FrameWork/ProjectManager/RTC/远程协助.prefab
  8. 12 12
      Assets/FrameWork/ProjectManager/XunJian/列表模块/列表模块.prefab
  9. 8 8
      Assets/FrameWork/ProjectManager/XunJian/进入任务/进入任务.prefab
  10. 0 1
      Assets/FrameWork/Windows.asset
  11. 9 1
      Assets/HotUpdate/Scripts/LoginManager.cs
  12. 1 0
      Assets/HotUpdate/Scripts/Scripts/HttpEdustryAction.cs
  13. 3 1
      Assets/HotUpdate/Scripts/Scripts/JinRuRenwu.cs
  14. 6 2
      Assets/HotUpdate/Scripts/Scripts/Main/ProjectMainWindow.cs
  15. 0 18
      Assets/HotUpdate/Scripts/Scripts/Project/RTC/ProjectRrmoteAssWindow.cs
  16. 0 116
      Assets/HotUpdate/Scripts/Scripts/Project/RTC/RoomMain/GHZRoomMain.cs
  17. 3 1
      Assets/HotUpdate/Scripts/Scripts/Project/XunJian/进入任务/ChangeCameraSaoMiao.cs
  18. 13 1
      Assets/HotUpdate/Scripts/Scripts/Project/XunJianLieBiaoWindow.cs
  19. 1 1
      Assets/HotUpdate/Scripts/Scripts/Scripts/MQTTClient.cs
  20. 3 1
      Assets/HotUpdate/Scripts/Scripts/Scripts/Window/WindowsManager.cs
  21. 0 34
      Assets/HotUpdate/Scripts/Scripts/TestCreateRoom.cs
  22. 0 60
      Assets/HotUpdate/Scripts/Scripts/TestLogin.cs
  23. 13 0
      Assets/HotUpdate/XRToolkit/UnityTool/Posture.cs
  24. 1 1
      Assets/HotUpdate/XRToolkit/UnityTool/Posture.cs.meta
  25. 1 1
      Assets/HotUpdate/XRToolkit/UnityTool/UnitySingleton.cs
  26. 68 0
      Assets/HotUpdate/XRToolkit/UnityTool/UnityUtil.cs
  27. 0 15
      Assets/Main/LoadDll.cs
  28. 1347 0
      Assets/RTC.prefab
  29. 7 0
      Assets/RTC.prefab.meta
  30. 1 1
      Assets/Remote30.meta
  31. 1 1
      Assets/Remote30/Agora-RTC-Plugin.meta
  32. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example.meta
  33. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput.meta
  34. 17 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.asset
  35. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.asset.meta
  36. 19 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.cs
  37. 1 1
      Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.cs.meta
  38. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor.meta
  39. 214 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/CommandBuild.cs
  40. 1 1
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/CommandBuild.cs.meta
  41. 40 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/SceneWindow.cs
  42. 1 1
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/SceneWindow.cs.meta
  43. 153 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Home.cs
  44. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Home.cs.meta
  45. 2417 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/HomeScene.unity
  46. 7 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/HomeScene.unity.meta
  47. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Image.meta
  48. BIN
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Image/agora2.png
  49. 152 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Image/agora2.png.meta
  50. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab.meta
  51. 353 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab/CasePanel.prefab
  52. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab/CasePanel.prefab.meta
  53. 106 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/README.md
  54. 7 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/README.md.meta
  55. 98 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/README.zh.md
  56. 7 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/README.zh.md.meta
  57. 8 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools.meta
  58. 41 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/Logger.cs
  59. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/Logger.cs.meta
  60. 33 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/PermissionHelper.cs
  61. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/PermissionHelper.cs.meta
  62. 36 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RequestToken.cs
  63. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RequestToken.cs.meta
  64. 253 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RingBuffer.cs
  65. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RingBuffer.cs.meta
  66. 15 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/UIElementDragger.cs
  67. 11 0
      Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/UIElementDragger.cs.meta
  68. 8 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK.meta
  69. 8 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code.meta
  70. 8 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event.meta
  71. 49 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/CloudAudioEngineEventHandler.cs
  72. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/CloudAudioEngineEventHandler.cs.meta
  73. 98 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaPlayerSourceObserver.cs
  74. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaPlayerSourceObserver.cs.meta
  75. 32 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaRecorderObserver.cs
  76. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaRecorderObserver.cs.meta
  77. 905 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/RtcEngineEventHandler.cs
  78. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/RtcEngineEventHandler.cs.meta
  79. 264 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioDeviceManager.cs
  80. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioDeviceManager.cs.meta
  81. 66 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioEncodedFrameObserver.cs
  82. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioEncodedFrameObserver.cs.meta
  83. 166 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioFrameObserver.cs
  84. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioFrameObserver.cs.meta
  85. 46 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioSpectrumObserver.cs
  86. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioSpectrumObserver.cs.meta
  87. 651 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayer.cs
  88. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayer.cs.meta
  89. 158 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCacheManager.cs
  90. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCacheManager.cs.meta
  91. 48 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCustomDataProvider.cs
  92. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCustomDataProvider.cs.meta
  93. 27 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerFrameObserver.cs
  94. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerFrameObserver.cs.meta
  95. 127 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerSourceObserver.cs
  96. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerSourceObserver.cs.meta
  97. 58 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorder.cs
  98. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorder.cs.meta
  99. 32 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorderObserver.cs
  100. 11 0
      Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorderObserver.cs.meta

+ 1 - 1
Assets/Editor.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 58a464a068f414aec8460ef6071d9233
+guid: 1dfa6ced52f0c4c8cb88b748e15d0a58
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}

+ 1 - 1
Assets/Editor/change.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: c040b6937eb394ba592f889d5311ba05
+guid: cf1bfa8079bd742bdb7fb99874d11fe3
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 8 - 8
Assets/FrameWork/Login/Login.prefab

@@ -933,7 +933,7 @@ RectTransform:
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 20, y: 20}
   m_Pivot: {x: 0.5, y: 0.5}
@@ -1142,7 +1142,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &7900262154886229374
 RectTransform:
   m_ObjectHideFlags: 0
@@ -1246,7 +1246,7 @@ MonoBehaviour:
   m_HandleRect: {fileID: 2291749833963476096}
   m_Direction: 0
   m_Value: 0
-  m_Size: 0.9714286
+  m_Size: 1
   m_NumberOfSteps: 0
   m_OnValueChanged:
     m_PersistentCalls:
@@ -1418,7 +1418,7 @@ MonoBehaviour:
   m_HandleRect: {fileID: 8421095476062917274}
   m_Direction: 2
   m_Value: 1
-  m_Size: 0.80786264
+  m_Size: 0.831196
   m_NumberOfSteps: 0
   m_OnValueChanged:
     m_PersistentCalls:
@@ -1441,7 +1441,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &5402804543893913684
 RectTransform:
   m_ObjectHideFlags: 0
@@ -1889,7 +1889,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &6291323004802443224
 RectTransform:
   m_ObjectHideFlags: 0
@@ -2582,7 +2582,7 @@ RectTransform:
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 20, y: 20}
   m_Pivot: {x: 0.5, y: 0.5}
@@ -2840,7 +2840,7 @@ RectTransform:
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 20, y: 20}
   m_Pivot: {x: 0.5, y: 0.5}

+ 17 - 0
Assets/FrameWork/PlayerToImage.prefab

@@ -187,6 +187,7 @@ GameObject:
   - component: {fileID: 6371964580815403536}
   - component: {fileID: 6371964580815403566}
   - component: {fileID: 6371964580815403567}
+  - component: {fileID: 1002154401532247085}
   m_Layer: 6
   m_Name: RawImage
   m_TagString: Untagged
@@ -249,6 +250,21 @@ MonoBehaviour:
     y: 0
     width: 1
     height: 1
+--- !u!114 &1002154401532247085
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6371964580815403537}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d4c33e92d8dc2934e919ffa2ff71afd6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  CaptureImage: {fileID: 0}
+  RGBCamTexture: {fileID: 0}
+  isAuto: 1
 --- !u!1 &6371964581270030862
 GameObject:
   m_ObjectHideFlags: 0
@@ -312,3 +328,4 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 0ab938c0a73719d42b9f2a2ef9f79083, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  mediaPlayer: {fileID: 0}

+ 1 - 1
Assets/FrameWork/ProjectManager/Main.prefab

@@ -20105,7 +20105,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!4 &1351349470932465109
 Transform:
   m_ObjectHideFlags: 0

File diff suppressed because it is too large
+ 1 - 5123
Assets/FrameWork/ProjectManager/RTC/RoomMain/RoomMain.prefab


+ 0 - 13
Assets/FrameWork/ProjectManager/RTC/远程协助.prefab

@@ -9,7 +9,6 @@ GameObject:
   serializedVersion: 6
   m_Component:
   - component: {fileID: 1172451362088300627}
-  - component: {fileID: 6076648255187854325}
   m_Layer: 5
   m_Name: "\u8FDC\u7A0B\u534F\u52A9"
   m_TagString: Untagged
@@ -37,15 +36,3 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 100, y: 100}
   m_Pivot: {x: 0.5, y: 0.5}
---- !u!114 &6076648255187854325
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 8368926532142905148}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 095bf4eef799e3e48ba8f1d18dafeee5, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 

+ 12 - 12
Assets/FrameWork/ProjectManager/XunJian/列表模块/列表模块.prefab

@@ -244,7 +244,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &2852261238146184139
 RectTransform:
   m_ObjectHideFlags: 0
@@ -261,10 +261,10 @@ RectTransform:
   m_Father: {fileID: 517678915528449164}
   m_RootOrder: 3
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 0, y: 0}
-  m_AnchoredPosition: {x: 0, y: 0}
-  m_SizeDelta: {x: 0, y: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 0, y: 1}
+  m_AnchoredPosition: {x: 85, y: -505}
+  m_SizeDelta: {x: 120, y: 120}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!222 &6659525292876512007
 CanvasRenderer:
@@ -3323,7 +3323,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &461962345745390567
 RectTransform:
   m_ObjectHideFlags: 0
@@ -3340,10 +3340,10 @@ RectTransform:
   m_Father: {fileID: 517678915528449164}
   m_RootOrder: 2
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 0, y: 0}
-  m_AnchoredPosition: {x: 0, y: 0}
-  m_SizeDelta: {x: 0, y: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 0, y: 1}
+  m_AnchoredPosition: {x: 85, y: -365}
+  m_SizeDelta: {x: 120, y: 120}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!222 &7804394111943363572
 CanvasRenderer:
@@ -5036,7 +5036,7 @@ MonoBehaviour:
     m_Right: 25
     m_Top: 25
     m_Bottom: 42
-  m_ChildAlignment: 0
+  m_ChildAlignment: 1
   m_StartCorner: 0
   m_StartAxis: 0
   m_CellSize: {x: 120, y: 120}
@@ -5063,7 +5063,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 4534851700080226489}
-  m_Enabled: 1
+  m_Enabled: 0
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 05841a9ad3fccc44da9d0e4653f05e2a, type: 3}
   m_Name: 

+ 8 - 8
Assets/FrameWork/ProjectManager/XunJian/进入任务/进入任务.prefab

@@ -7590,19 +7590,19 @@ PrefabInstance:
     m_Modifications:
     - target: {fileID: 1046681076883175317, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchorMax.y
-      value: 1
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 1046681076883175317, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchorMin.y
-      value: 1
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 1046681076883175317, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchoredPosition.x
-      value: 135
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 1046681076883175317, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchoredPosition.y
-      value: -50
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 2663175551128001469, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_Name
@@ -7618,19 +7618,19 @@ PrefabInstance:
       objectReference: {fileID: 0}
     - target: {fileID: 6534303979265014755, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchorMax.y
-      value: 1
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 6534303979265014755, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchorMin.y
-      value: 1
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 6534303979265014755, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchoredPosition.x
-      value: 405
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 6534303979265014755, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: m_AnchoredPosition.y
-      value: -50
+      value: 0
       objectReference: {fileID: 0}
     - target: {fileID: 7708746070731989160, guid: cb61b52cc83342e489699f3476640957, type: 3}
       propertyPath: playImg

+ 0 - 1
Assets/FrameWork/Windows.asset

@@ -15,7 +15,6 @@ MonoBehaviour:
   initShowWindow: 100001
   canvas: {fileID: 8894333160753431150, guid: 1e72723ecae88b64ab695e52b7cfa9de, type: 3}
   initComponent:
-  - {fileID: 11500000, guid: 95bd5e73b2b930240adab20b3c9619d2, type: 3}
   - {fileID: 11500000, guid: 950e827448571e746810b732dc8b4029, type: 3}
   - {fileID: 11500000, guid: 8a480db2749607445822a51058194ffd, type: 3}
   windowItemGameObjectList:

+ 9 - 1
Assets/HotUpdate/Scripts/LoginManager.cs

@@ -7,6 +7,8 @@ using XRTool.Util;
 
 public class LoginManager : MonoSingleton<LoginManager>
 {
+    public static string rtcuid;
+    public static string rtctoken;
     //账号列表
     [HideInInspector]
     public GameObject bigLoginItem;
@@ -167,7 +169,7 @@ public class LoginManager : MonoSingleton<LoginManager>
 
     public void LogingCallBack(string msg)
     {
-        Debug.Log(msg);
+        Debug.Log("LogingCallBack===>"+msg);
         try
         {
 
@@ -179,7 +181,13 @@ public class LoginManager : MonoSingleton<LoginManager>
                 string token = obj["data"]["token"].ToString();
                 login.UserInfo.Instance.Token = token;
                 HttpEdustryAction.Token = token;
+                
+                HttpTool.Instance.PostLogin(HttpEdustryAction.UserInfo, "", (data)=>{
 
+                     JObject obj = JObject.Parse(data);
+                    rtcuid =  obj["data"]["supportUnionID"].ToString();//js["data"]["unionId"].ToString();
+                   rtctoken =  obj["data"]["supportToken"].ToString();//js["data"]["token"].ToString();
+                });
 
            //     RoomFileMinio.Instance.islogin = true;
 

+ 1 - 0
Assets/HotUpdate/Scripts/Scripts/HttpEdustryAction.cs

@@ -4,6 +4,7 @@ public class HttpEdustryAction
     public static string LoginList = "/mr-endustry/v1/user/login/list";
 
     public static string Login = "/mr-endustry/v1/user/login";
+    public static string UserInfo = "/mr-endustry/v1/user/info";
 
     public static string timestamp = "/mr-endustry/v1/user/timestamp";
 

+ 3 - 1
Assets/HotUpdate/Scripts/Scripts/JinRuRenwu.cs

@@ -414,10 +414,12 @@ public class JinRuRenwu : WindowSingleton<JinRuRenwu>
     public void gotoRTC()
     {
 
-        WindowsManager.Instance.show(WindowConfig.windowType.Tip2, false, "敬请期待!");
 
+        WindowsManager.Instance.rtcobj.SetActive(true);
+        //WindowsManager.Instance.gameObject.SetActive(false);
 
         /*
+        WindowsManager.Instance.show(WindowConfig.windowType.Tip2, false, "敬请期待!");
         List<string> backTip = new List<string>();
         backTip.Add("test1");
         backTip.Add("test2");

+ 6 - 2
Assets/HotUpdate/Scripts/Scripts/Main/ProjectMainWindow.cs

@@ -1,6 +1,7 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using UnityEngine.SceneManagement;
 using XRTool.Util;
 
 public class ProjectMainWindow : WindowSingleton<ProjectMainWindow>
@@ -16,8 +17,11 @@ public class ProjectMainWindow : WindowSingleton<ProjectMainWindow>
 
     public void showRtc()
     {
-        ShowInfoTipManager.Instance.showTip("暂未开放,敬请期待");
-        TimerMgr.Instance.CreateTimer(()=> { ShowInfoTipManager.Instance.closeTip(); },2f);
+        //SceneManager.LoadScene(1);
+        WindowsManager.Instance.rtcobj.SetActive(true);
+        WindowsManager.Instance.gameObject.SetActive(false);
+       // ShowInfoTipManager.Instance.showTip("暂未开放,敬请期待");
+       // TimerMgr.Instance.CreateTimer(()=> { ShowInfoTipManager.Instance.closeTip(); },2f);
         //WindowsManager.Instance.show(WindowConfig.windowType.RoomMain);
     }
 }

+ 0 - 18
Assets/HotUpdate/Scripts/Scripts/Project/RTC/ProjectRrmoteAssWindow.cs

@@ -1,18 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-
-public class ProjectRrmoteAssWindow : WindowSingleton<ProjectXunJianWindow>
-{
-    public void show()
-    {
-
-        this.gameObject.SetActive(true);
-    }
-
-    public void hide()
-    {
-
-        this.gameObject.SetActive(false);
-    }
-}

+ 0 - 116
Assets/HotUpdate/Scripts/Scripts/Project/RTC/RoomMain/GHZRoomMain.cs

@@ -1,116 +0,0 @@
-using GHZRtc;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-public class GHZRoomMain : SingletonMono<GHZRoomMain>
-{
-    public Button audioOpenBtn;
-    public Button audioCloseBtn;
-    public Button videoOpenBtn;
-    public Button videoCloseBtn;
-    public Button clearAllArrowBtn;
-    public Button hangupBtn;
-    public GameObject exitSelectUI;
-    public Button noExitBtn;
-    public Button yesExitBtn;
-    public RawImage videoRawImage;
-
-    private bool isRTCVideo;
-
-    private void Awake()
-    {
-        audioOpenBtn.onClick.AddListener(() => LocalAudioStream(true));
-        audioCloseBtn.onClick.AddListener(() => LocalAudioStream(false));
-
-        videoOpenBtn.onClick.AddListener(() => LocalVideoStream(true));
-        videoCloseBtn.onClick.AddListener(() => LocalVideoStream(false));
-
-        clearAllArrowBtn.onClick.AddListener(() => ClearAllArrow());
-        hangupBtn.onClick.AddListener(() => HangUpOnClick());
-        noExitBtn.onClick.AddListener(() => ExitRoom(false));
-        yesExitBtn.onClick.AddListener(() => ExitRoom(true));
-
-        GHZRTCFusionManager.OnUserJoined += UserJoined;
-        GHZRTCFusionManager.OnUserOffline += UserOffline;
-        GHZRTCFusionManager.OnRemoteAudioStateChanged += RemoteAudioStateChanged;
-        GHZRTCFusionManager.OnRemoteVideoStateChanged += RemoteVideoStateChanged;
-
-        isRTCVideo = false;
-    }
-
-    private void OnDisable()
-    {
-        GHZRTCFusionManager.OnUserJoined -= UserJoined;
-        GHZRTCFusionManager.OnUserOffline -= UserOffline;
-        GHZRTCFusionManager.OnRemoteAudioStateChanged -= RemoteAudioStateChanged;
-        GHZRTCFusionManager.OnRemoteVideoStateChanged -= RemoteVideoStateChanged;
-    }
-
-    private void LocalAudioStream( bool state )
-    {
-        audioOpenBtn.gameObject.SetActive(state);
-        audioCloseBtn.gameObject.SetActive(!state);
-        GHZRTCFusionManager.Instance.MuteLocalAudioStream(state);
-    }
-
-    private void LocalVideoStream(bool state)
-    {
-        videoOpenBtn.gameObject.SetActive(state);
-        audioCloseBtn.gameObject.SetActive(!state);
-        GHZRTCFusionManager.Instance.MuteLocalVideoStream(state);
-    }
-
-    private void ClearAllArrow()
-    {
-
-    }
-
-    private void HangUpOnClick()
-    {
-        exitSelectUI.gameObject.SetActive(true);
-    }
-
-    private void ExitRoom(bool state)
-    {
-        exitSelectUI.gameObject.SetActive(false);
-        if (state)
-        {
-          
-            GHZRTCFusionManager.Instance.LeaveRoom();
-        }
-      
-    }
-
-    private void UserJoined (string uid)
-    {
-
-        Debug.Log("DGJ  UserJoined ===>  "+ uid);
-        // 检测到有人进入房间 并且当前无画面 就显示当前人的画面
-        if (!isRTCVideo)
-        {
-            isRTCVideo = true;
-            GHZRTCFusionManager.Instance.SetVideoFrame(videoRawImage, uid);
-            videoRawImage.gameObject.SetActive(true);
-        }
-
-    }
-
-    private void UserOffline(string uid)
-    {
-        Debug.Log("DGJ  UserOffline ===>  " + uid);
-    }
-
-
-    private void RemoteAudioStateChanged(string uid , REMOTE_AUIDO_STATE_REASON_RTC state)
-    {
-
-    }
-
-    private void RemoteVideoStateChanged(string uid ,REMOTE_VIDEO_STATE_REASON_RTC state)
-    {
-
-    }
-
-}

+ 3 - 1
Assets/HotUpdate/Scripts/Scripts/Project/XunJian/进入任务/ChangeCameraSaoMiao.cs

@@ -328,7 +328,9 @@ public class ChangeCameraSaoMiao : MonoSingleton<ChangeCameraSaoMiao>
             JinRuRenwu.Instance.paizhaoanniu.SetActive(false);
             JinRuRenwu.Instance.paizhaoGo.SetActive(false);
         }
-        XRRGBCamera.Instance.stopCamera();
+        
+        if(!WindowsManager.Instance.rtcobj.activeSelf)
+            XRRGBCamera.Instance.stopCamera();
         paizhao.SetActive(false);
         luxiang.SetActive(false);
         saomiao.SetActive(false);

+ 13 - 1
Assets/HotUpdate/Scripts/Scripts/Project/XunJianLieBiaoWindow.cs

@@ -30,6 +30,15 @@ public class XunJianLieBiaoWindow : WindowSingleton<XunJianLieBiaoWindow>
             uiScroll.InitList(0, data);
             XunJianDataManager.Instance.GetXunJianList((List<XunJianListData> data) =>
             {
+                if(data.Count==0)
+                {
+                    uiScroll.gameObject.SetActive(false);
+                }
+                else
+                {
+
+                    uiScroll.gameObject.SetActive(true);
+                }
                 for (int i = 0; i < MaxLiebiao; i++)
                 {
                     if(data.Count> i)
@@ -125,8 +134,11 @@ public class XunJianLieBiaoWindow : WindowSingleton<XunJianLieBiaoWindow>
 
     public void showRtc()
     {
+        WindowsManager.Instance.rtcobj.SetActive(true);
+        WindowsManager.Instance.gameObject.SetActive(false);
+        /*
         ShowInfoTipManager.Instance.showTip("暂未开放,敬请期待");
-        TimerMgr.Instance.CreateTimer(() => { ShowInfoTipManager.Instance.closeTip(); }, 2f);
+        TimerMgr.Instance.CreateTimer(() => { ShowInfoTipManager.Instance.closeTip(); }, 2f);*/
         //WindowsManager.Instance.show(WindowConfig.windowType.RoomMain);
     }
 

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/Scripts/MQTTClient.cs

@@ -124,7 +124,7 @@ public class MQTTClient : MonoSingleton<MQTTClient>
         qt.OnConnecting += OnConnecting;
         qt.OnReceived += OnReceived;
         qt.OnClose += OnClose;
-        qt.Connect();
+        qt.Connect(bytes);
         StartCoroutine(Reconnection());
         //  StartSendCameraPos();
     }

+ 3 - 1
Assets/HotUpdate/Scripts/Scripts/Scripts/Window/WindowsManager.cs

@@ -13,6 +13,8 @@ using static WindowConfig;
 
 public class WindowsManager : MonoSingleton<WindowsManager>
 {
+
+    public GameObject rtcobj;
     public bool isTest = false;
     public delegate void OnTipBackEvent(string msg);
     public  OnTipBackEvent OnTipBackChange;
@@ -135,7 +137,7 @@ public class WindowsManager : MonoSingleton<WindowsManager>
         obj.transform.localEulerAngles = Vector3.zero;
         GameObject.Instantiate(GetPrefab(windowType.XunJian, DeviceType.type + "_ARSaoTu"));
         GameObject.Instantiate(GetPrefab(windowType.ProjectMain, "PlayerToImage"));
-        GameObject.Instantiate(GetPrefab(windowType.RTC, "GHZRtcNew"));
+    //    GameObject.Instantiate(GetPrefab(windowType.RTC, "GHZRtcNew"));
         GameObject.Instantiate(GetPrefab(windowType.RTC, "Tools"));
         GameObject.Instantiate(GetPrefab(windowType.XunJian, "ImmersalSDK"));
         DianYunManager.Instance.stopSaoMiao();

+ 0 - 34
Assets/HotUpdate/Scripts/Scripts/TestCreateRoom.cs

@@ -1,34 +0,0 @@
-using Newtonsoft.Json.Linq;
-using System.Collections;
-using System.Collections.Generic;
-using TMPro;
-using UnityEngine;
-
-public class TestCreateRoom : MonoBehaviour
-{
-   
-    // Start is called before the first frame update
-    void Start()
-    {
-       // Debug.Log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
-        StartCoroutine(HttpTool.Instance.SendHttp("/cmcc-endustry/v1/rtc/createRoom", "", message =>
-        {
-            JObject jobject = JObject.Parse(message);
-            Debug.Log("DGJ ===>  CreateRoom  " + message);
-
-        //    "Request Timeout"
-        if (jobject["code"].ToString() == "200" && !string.IsNullOrWhiteSpace(jobject["data"].ToString()))
-            {
-                Debug.LogError("DGJ === RoomID  " + jobject["data"]["roomId"]);
-                UILogManager.Instance.logText.text = jobject["data"]["roomId"].ToString();
-                GHZRTCFusionManager.Instance.CreateRoom(jobject["data"]["host"].ToString(), jobject["data"]["token"].ToString());
-            }
-            else if (jobject["code"].ToString() == "503")
-            {
-
-            }
-        }, "application/x-www-form-urlencoded"));  
-    }
-
-  
-}

+ 0 - 60
Assets/HotUpdate/Scripts/Scripts/TestLogin.cs

@@ -1,60 +0,0 @@
-using LitJson;
-using Newtonsoft.Json.Linq;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using TMPro;
-public class TestLogin : MonoBehaviour
-{
-    public TMP_Text logText;
-    private float times = 0;
-    private bool init = false;
-    // Start is called before the first frame update
-    void Start()
-    {
-    
-       
-    }
-
-    private void Update()
-    {
-        times += Time.deltaTime;
-        if (times>3&&!init)
-        {
-            init = true;
-            JsonData data = new JsonData();
-            data["account"] = "13910723157";
-            data["password"] = "1";
-            HttpTool.Instance.PostLogin("/cmcc-endustry/v1/user/login", data.ToJson(), LoginCallBack);
-        }
-    }
-    public void LoginCallBack(string msg)
-    {
-        Debug.Log(msg);
-        JObject obj = JObject.Parse(msg);
-
-       if(obj["code"].ToString() == "200")
-        {
-            string token = obj["data"]["token"].ToString();
-            login.UserInfo.Instance.Token = token;
-            StartCoroutine(
-            HttpTool.Instance.SendHttp("/cmcc-endustry/v1/rtc/createRoom", "", message =>
-            {
-                JObject jobject = JObject.Parse(message);
-                Debug.Log("DGJ ===>  CreateRoom  " + message);
-
-                //    "Request Timeout"
-                if (jobject["code"].ToString() == "200" && !string.IsNullOrWhiteSpace(jobject["data"].ToString()))
-                {
-                    Debug.LogError("DGJ === RoomID  " + jobject["data"]["roomId"]);
-                    logText.text = jobject["data"]["roomId"].ToString();
-                    GHZRTCFusionManager.Instance.CreateRoom(jobject["data"]["host"].ToString(),jobject["data"]["token"].ToString());
-                }
-                else if (jobject["code"].ToString() == "503")
-                {
-                   
-                }
-            }, "application/x-www-form-urlencoded"));
-        }
-    }
-}

+ 13 - 0
Assets/HotUpdate/XRToolkit/UnityTool/Posture.cs

@@ -0,0 +1,13 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+namespace ShadowStudio.Model
+{
+    public struct Posture
+    {
+        public Vector3 position;
+        public Vector3 angle;
+        public Vector3 scale;
+        public int count;
+    }
+}

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/TestCreateRoom.cs.meta → Assets/HotUpdate/XRToolkit/UnityTool/Posture.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: d792753345f69ef469339a1329d062a3
+guid: 6536af9227627c74f9dce3605fb84427
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 1 - 1
Assets/HotUpdate/XRToolkit/UnityTool/UnitySingleton.cs

@@ -59,7 +59,7 @@ namespace XRTool.Util
             if (instance != null && instance.gameObject != gameObject)
             {
                 Debug.LogErrorFormat("{0}为单例对象,但是场景中存在多个{0},已删除本对象", GetType().Name);
-                Destroy(gameObject);
+             //   Destroy(gameObject);
             }
             else
             {

+ 68 - 0
Assets/HotUpdate/XRToolkit/UnityTool/UnityUtil.cs

@@ -173,6 +173,13 @@ namespace XRTool.Util
             }
             return forreturn;
         }
+        public struct Posture
+        {
+            public Vector3 position;
+            public Vector3 angle;
+            public Vector3 scale;
+            public int count;
+        }
         public static void SetParent(Transform parent, Transform child)
         {
             child.SetParent(parent);
@@ -180,6 +187,67 @@ namespace XRTool.Util
             child.localRotation = Quaternion.identity;
             child.localScale = Vector3.one;
         }
+        public static void SetPosture(Transform info, Posture posture, float time = -1)
+        {
+            info.localPosition = posture.position;
+            info.localEulerAngles = posture.angle;
+            info.localScale = posture.scale;
+        }
+        public static Posture GetPosture(string info)
+        {
+            Posture posture = new Posture();
+            string[] arr = info.Split('|');
+            for (int i = 0; i < arr.Length; i++)
+            {
+                if (string.IsNullOrEmpty(arr[i]))
+                {
+                    continue;
+                }
+                string[] v = arr[i].Split(',');
+                Vector3 vector = Vector3.zero;
+                for (int j = 0; j < v.Length; j++)
+                {
+                    float value = float.Parse(v[j]);
+                    if (j == 0)
+                    {
+                        vector.x = value;
+                    }
+                    else if (j == 1)
+                    {
+                        vector.y = value;
+                    }
+                    else if (j == 2)
+                    {
+                        vector.z = value;
+                    }
+                }
+                vector *= maxTransfer;
+                if (i == 0)
+                {
+                    posture.position = vector;
+                }
+                else if (i == 1)
+                {
+                    posture.angle = vector;
+                }
+                else if (i == 2)
+                {
+                    posture.scale = vector;
+                }
+                posture.count = i;
+            }
+
+            return posture;
+        }
+        public static Posture GetPosture(Transform info)
+        {
+            Posture posture = new Posture();
+            posture.position = info.localPosition;
+            posture.angle = info.localEulerAngles;
+            posture.scale = info.localScale;
+            posture.count = 2;
+            return posture;
+        }
         /// <summary>
                 /// 去除文件bom头后的字符
                 /// </summary>

+ 0 - 15
Assets/Main/LoadDll.cs

@@ -1,5 +1,4 @@
 
-using HybridCLR;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -205,9 +204,6 @@ public class LoadDll : MonoBehaviour
         }
 #endif
 
-        HomologousImageMode mode = HomologousImageMode.SuperSet;
-        LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(www.downloadHandler.data, mode);
-        Debug.Log($"LoadMetadataForAOTAssembly:{name}. mode:{mode} ret:{err}");
     }
 
      public IEnumerator DownLoadAssets(string dllPath,string name,bool isRemote=true)
@@ -316,17 +312,6 @@ public class LoadDll : MonoBehaviour
     /// </summary>
     private static void LoadMetadataForAOTAssemblies()
     {
-        /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
-        /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
-        /// 
-        HomologousImageMode mode = HomologousImageMode.SuperSet;
-        foreach (var aotDllName in AOTMetaAssemblyFiles)
-        {
-            byte[] dllBytes = ReadBytesFromStreamingAssets(aotDllName);
-            // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
-            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
-            Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
-        }
     }
 
 

+ 1347 - 0
Assets/RTC.prefab

@@ -0,0 +1,1347 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1753656144154665620
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6559544491057943124}
+  - component: {fileID: 8333085361432020381}
+  m_Layer: 0
+  m_Name: ArrowList
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &6559544491057943124
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1753656144154665620}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 3912773516131837836}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8333085361432020381
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1753656144154665620}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: aa22e78e66313e1499cb1b7373a77e8c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  arrow: {fileID: 5499693674242144792, guid: 29675f3807dc81a4c8fb996856725fdf, type: 3}
+  arrow2: {fileID: 5499693674242144792, guid: f8eef83a759fe9a4780d030ae44ee73b, type: 3}
+  num: 0
+--- !u!1 &3912773516131837832
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 3912773516131837836}
+  - component: {fileID: 3912773516131837837}
+  - component: {fileID: 3912773516131837838}
+  - component: {fileID: 3912773516131837839}
+  - component: {fileID: 3912773516131837827}
+  - component: {fileID: 3912773516131837843}
+  - component: {fileID: 3912773516131837842}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &3912773516131837836
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: -6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338232423991862}
+  - {fileID: 6559544491057943124}
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: -0.7781334, y: -5.010691}
+  m_SizeDelta: {x: 100, y: 100}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!223 &3912773516131837837
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &3912773516131837838
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!114 &3912773516131837839
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &3912773516131837827
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 948b9ab040508dc48a294230f85b39e2, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!114 &3912773516131837843
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 95bd5e73b2b930240adab20b3c9619d2, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!114 &3912773516131837842
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3912773516131837832}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f83f04cbdb0c0ca4c931c9d1dae1981b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  audiosource: {fileID: 0}
+--- !u!1 &4309338231096751910
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231096751914}
+  - component: {fileID: 4309338231096751915}
+  - component: {fileID: 4309338231096751908}
+  - component: {fileID: 4309338231096751909}
+  m_Layer: 8
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4309338231096751914
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231096751910}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338232492224388}
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!223 &4309338231096751915
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231096751910}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 1
+  m_Camera: {fileID: 4309338232090421979}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &4309338231096751908
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231096751910}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 0
+--- !u!114 &4309338231096751909
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231096751910}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!1 &4309338231173401385
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231173401384}
+  - component: {fileID: 4309338231173401391}
+  m_Layer: 3
+  m_Name: PopPublic
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338231173401384
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231173401385}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338231233015103}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338231173401391
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231173401385}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 848568c0494dbb543a1bc4fd6ff9457d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Prefab:
+  - {fileID: 4482520272683810389, guid: 789660a2b32e2f84e9e0939efa573d41, type: 3}
+  - {fileID: 6552768087607729808, guid: 43f87b9d5fd81364092f9dd319dbfdac, type: 3}
+  - {fileID: 1993260005584970223, guid: b98e0a444b4a0cc4da1c96d2df1f3161, type: 3}
+  window: []
+--- !u!1 &4309338231233015099
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231233015103}
+  - component: {fileID: 4309338231233015096}
+  - component: {fileID: 4309338231233015097}
+  - component: {fileID: 4309338231233015098}
+  - component: {fileID: 4309338231233015102}
+  m_Layer: 3
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4309338231233015103
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231233015099}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: -6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338231173401384}
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: -0.7781334, y: -5.010691}
+  m_SizeDelta: {x: 100, y: 100}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!223 &4309338231233015096
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231233015099}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &4309338231233015097
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231233015099}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!114 &4309338231233015098
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231233015099}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &4309338231233015102
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231233015099}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 948b9ab040508dc48a294230f85b39e2, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1 &4309338231277928231
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231277928230}
+  - component: {fileID: 4309338231277928228}
+  - component: {fileID: 4309338231277928229}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4309338231277928230
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231277928231}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338231672099210}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &4309338231277928228
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231277928231}
+  m_CullTransparentMesh: 0
+--- !u!114 &4309338231277928229
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231277928231}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: New Text
+--- !u!1 &4309338231303167506
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231303167505}
+  - component: {fileID: 4309338231303167504}
+  m_Layer: 0
+  m_Name: ShowRoom
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338231303167505
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231303167506}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232423991862}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338231303167504
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231303167506}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f1fd6650b4edd3f4faa7ab6b05413464, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Prefab:
+  - {fileID: 2241088652506551446, guid: 3ac948fe5851d8c488bb8d296946c5d0, type: 3}
+  - {fileID: 1469341746259159848, guid: 9e09beb27b326d34a9b8151cb04f5356, type: 3}
+  - {fileID: 4740575582196431468, guid: 0cea6fb206f65894595cf366b0d770d4, type: 3}
+  - {fileID: 5968991834605629360, guid: e3e984cd1dd165242ac3986ab38c9688, type: 3}
+  - {fileID: 2799213986232774072, guid: aada762ac48142a4898ba48b91a0d7e6, type: 3}
+  window: []
+  showMainScreenBtn: {fileID: 0}
+--- !u!1 &4309338231445702602
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231445702600}
+  - component: {fileID: 4309338231445702601}
+  - component: {fileID: 4309338231445702607}
+  m_Layer: 0
+  m_Name: Log
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338231445702600
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231445702602}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -0.7781334, y: -5.9106913, z: -6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 6
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338231445702601
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231445702602}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5eb3897621f42f24c84f2bb9119a2097, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!114 &4309338231445702607
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231445702602}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 823a759a1f882ab43bb354cfa5c1594c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1 &4309338231672099211
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231672099210}
+  - component: {fileID: 4309338231672099215}
+  - component: {fileID: 4309338231672099208}
+  - component: {fileID: 4309338231672099209}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &4309338231672099210
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231672099211}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: -15.547461}
+  m_LocalScale: {x: 0, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338231277928230}
+  m_Father: {fileID: 4309338232668835564}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 475.09695, y: 315.46194}
+  m_SizeDelta: {x: 929, y: 614}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!223 &4309338231672099215
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231672099211}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &4309338231672099208
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231672099211}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!114 &4309338231672099209
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231672099211}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!1 &4309338231792315196
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231792315139}
+  - component: {fileID: 4309338231792315138}
+  m_Layer: 0
+  m_Name: ShowOffice
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338231792315139
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231792315196}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232423991862}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338231792315138
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231792315196}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 92d9de848bc714d40ba0a829bf0fc23a, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Prefab:
+  - {fileID: 5189302353021310843, guid: f834b5f94633e5947bd0cc72a757df93, type: 3}
+  - {fileID: 4507694177786838805, guid: ca1c2bf767c840f4098e180e21665ff8, type: 3}
+  - {fileID: 2744153305912311890, guid: 5250aa3e06e48c74ba8b0009149ba3f8, type: 3}
+  - {fileID: 2539131660605934548, guid: 28f8d8851a7b5f74c8b484a99a4f6168, type: 3}
+  - {fileID: 6233831381892610832, guid: fb253eb4691025f45a785ac819e69cd7, type: 3}
+  window: []
+--- !u!1 &4309338231976203563
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338231976203562}
+  - component: {fileID: 4309338231976203561}
+  m_Layer: 0
+  m_Name: ShowLogin
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338231976203562
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231976203563}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232423991862}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338231976203561
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338231976203563}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0e525bca3d9b9264c875e3420c4ac45d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Prefab:
+  - {fileID: 4214644006012593618, guid: afba134eefaa848469233cf2dd308790, type: 3}
+  - {fileID: 177754137775656777, guid: 8424bf138cfb87e4ba067ca1cf86b920, type: 3}
+  window: []
+  loginType: 1
+--- !u!1 &4309338232090421973
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232090421978}
+  - component: {fileID: 4309338232090421979}
+  m_Layer: 0
+  m_Name: Camera
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232090421978
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232090421973}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -0.7781334, y: -5.9106913, z: -6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!20 &4309338232090421979
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232090421973}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 2
+  m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_FocalLength: 50
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 256
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 8400000, guid: 2515c6a63a25f954f87089e5f3fc4a59, type: 2}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!1 &4309338232351469840
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232351469847}
+  - component: {fileID: 4309338232351469846}
+  m_Layer: 0
+  m_Name: GameStartLogo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232351469847
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232351469840}
+  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_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232423991862}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338232351469846
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232351469840}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6bc6bcb528d092a48bd4bb4e40266c0b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Prefab: []
+  window: []
+--- !u!1 &4309338232423991863
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232423991862}
+  - component: {fileID: 4309338232423991861}
+  - component: {fileID: 4309338232423991860}
+  m_Layer: 0
+  m_Name: GameSart
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232423991862
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232423991863}
+  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_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338232351469847}
+  - {fileID: 4309338231976203562}
+  - {fileID: 4309338231792315139}
+  - {fileID: 4309338231303167505}
+  m_Father: {fileID: 3912773516131837836}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338232423991861
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232423991863}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b69ff07236e004f8992242dbf033b841, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  systemMenu: {fileID: 0}
+--- !u!114 &4309338232423991860
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232423991863}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: c66f4a6973afc3f439c079ed8df4d320, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1 &4309338232492224389
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232492224388}
+  - component: {fileID: 4309338232492224394}
+  - component: {fileID: 4309338232492224395}
+  m_Layer: 8
+  m_Name: RawImage
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4309338232492224388
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232492224389}
+  m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338231096751914}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &4309338232492224394
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232492224389}
+  m_CullTransparentMesh: 1
+--- !u!114 &4309338232492224395
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232492224389}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Texture: {fileID: 0}
+  m_UVRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+--- !u!1 &4309338232510732525
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232510732530}
+  - component: {fileID: 4309338232510732531}
+  - component: {fileID: 4309338232510732529}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232510732530
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232510732525}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -0.7781334, y: -5.9106913, z: -6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338232510732531
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232510732525}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 10
+--- !u!114 &4309338232510732529
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232510732525}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_SendPointerHoverToParent: 1
+  m_MoveRepeatDelay: 0.5
+  m_MoveRepeatRate: 0.1
+  m_XRTrackingOrigin: {fileID: 0}
+  m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_DeselectOnBackgroundClick: 1
+  m_PointerBehavior: 0
+  m_CursorLockBehavior: 0
+--- !u!1 &4309338232643208225
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232643208224}
+  m_Layer: 0
+  m_Name: RTC
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232643208224
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232643208225}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0.7781334, y: 5.9106913, z: 6.641512}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338231096751914}
+  - {fileID: 4309338232090421978}
+  - {fileID: 3912773516131837836}
+  - {fileID: 4309338232668835564}
+  - {fileID: 4309338232510732530}
+  - {fileID: 4309338231233015103}
+  - {fileID: 4309338231445702600}
+  - {fileID: 7752609514569809291}
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &4309338232668835565
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4309338232668835564}
+  - component: {fileID: 4309338232668835571}
+  m_Layer: 0
+  m_Name: Agora
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4309338232668835564
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232668835565}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -11.3750925, y: -14.372624, z: 8.905949}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4309338231672099210}
+  m_Father: {fileID: 4309338232643208224}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4309338232668835571
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4309338232668835565}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 926f16f1c9728dc40bf672f2f7783b69, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  _appIdInput: {fileID: 11400000, guid: 300c6525f002a4dbaac41a5c4b054e35, type: 2}
+  _appID: 
+  _token: 
+  _channelName: 
+  LogText: {fileID: 4309338231277928229}
+  uid: 0
+  userAccount: 
+  isSwitchCamera: 0
+  ca: {fileID: 4309338232090421979}
+  img: {fileID: 4309338232492224395}
+--- !u!1001 &4309338231202052652
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 4309338232643208224}
+    m_Modifications:
+    - target: {fileID: 4297547537947087003, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_RootOrder
+      value: 7
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: -0.7781334
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: -5.9106913
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: -6.641512
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6120500274624405637, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_Name
+      value: RTC (1)
+      objectReference: {fileID: 0}
+    - target: {fileID: 6391953062967754586, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 6955780621421951218, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+--- !u!4 &7752609514569809291 stripped
+Transform:
+  m_CorrespondingSourceObject: {fileID: 5790244892868462503, guid: 248bb4393032d4aa59ae6d9165c8f0cc, type: 3}
+  m_PrefabInstance: {fileID: 4309338231202052652}
+  m_PrefabAsset: {fileID: 0}

+ 7 - 0
Assets/RTC.prefab.meta

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

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/Project/RTC.meta → Assets/Remote30.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 1ae1216798e078b48999e5fb5ed8dc3d
+guid: f88f1d055a72a4af0bbd708adfbbe051
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/Project/RTC/RoomMain.meta → Assets/Remote30/Agora-RTC-Plugin.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 569d650a600cc524aa40d337c877f903
+guid: a2fb2627347a94307aaff8ad64afcd73
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput.meta

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

+ 17 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.asset

@@ -0,0 +1,17 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 310468f085ef24732beac714c9bb64fd, type: 3}
+  m_Name: AppIdInput
+  m_EditorClassIdentifier: 
+  appID: 59a3e20fd9674f53a3422ff48b16db75
+  token: 
+  channelName: 

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.asset.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 300c6525f002a4dbaac41a5c4b054e35
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 19 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.cs

@@ -0,0 +1,19 @@
+using UnityEngine;
+using UnityEngine.Events;
+using System.Collections;
+using System;
+using UnityEngine.Serialization;
+
+[CreateAssetMenu(menuName = "Agora/AppIdInput", fileName = "AppIdInput", order = 1)]
+[Serializable]
+public class AppIdInput : ScriptableObject
+{
+    [FormerlySerializedAs("APP_ID")] [SerializeField]
+    public string appID = "";
+
+    [FormerlySerializedAs("TOKEN")] [SerializeField]
+    public string token = "";
+
+    [FormerlySerializedAs("CHANNEL_NAME")] [SerializeField]
+    public string channelName = "YOUR_CHANNEL_NAME";
+}

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/Project/RTC/RoomMain/GHZRoomMain.cs.meta → Assets/Remote30/Agora-RTC-Plugin/API-Example/AppIdInput/AppIdInput.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: a6b6d7302d9ff0a469ae11ac47a45997
+guid: 310468f085ef24732beac714c9bb64fd
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor.meta

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

+ 214 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/CommandBuild.cs

@@ -0,0 +1,214 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEditor.Build;
+#if UNITY_2018_4_OR_NEWER
+using UnityEditor.Build.Reporting;
+#endif 
+using UnityEngine;
+
+public class CommandBuild : MonoBehaviour
+{
+
+
+    private static string[] GetAllScenes()
+    {
+        string[] scenes = new string[] {
+            "Assets/API-Example/HomeScene.unity",
+            "Assets/API-Example/Examples/Basic/JoinChannelVideo/BasicVideoCallScene.unity",
+            "Assets/API-Example/Examples/Basic/JoinChannelAudio/BasicAudioCallScene.unity",
+
+            "Assets/API-Example/Examples/Advanced/AudioMixing/AudioMixingScene.unity",
+            "Assets/API-Example/Examples/Advanced/AudioSpectrum/AudioSpectrumScene.unity",
+            "Assets/API-Example/Examples/Advanced/ChannelMediaRelay/ChannelMediaRelayScene.unity",
+            "Assets/API-Example/Examples/Advanced/ContentInspect/ContentInspectScene.unity",
+            "Assets/API-Example/Examples/Advanced/CustomCaptureAudio/CustomCaptureAudioScene.unity",
+            "Assets/API-Example/Examples/Advanced/CustomCaptureVideo/CustomCaptureVideoScene.unity",
+            "Assets/API-Example/Examples/Advanced/CustomRenderAudio/CustomRenderAudioScene.unity",
+            "Assets/API-Example/Examples/Advanced/DeviceManager/DeviceManagerScene.unity",
+            "Assets/API-Example/Examples/Advanced/DualCamera/DualCameraScene.unity",
+            "Assets/API-Example/Examples/Advanced/JoinChannelVideoToken/JoinChannelVideoTokenScene.unity",
+            "Assets/API-Example/Examples/Advanced/JoinChannelWithUserAccount/JoinChannelWithUserAccountScene.unity",
+            "Assets/API-Example/Examples/Advanced/MediaPlayer/MediaPlayerScene.unity",
+            "Assets/API-Example/Examples/Advanced/MediaRecorder/MediaRecorderScene.unity",
+            "Assets/API-Example/Examples/Advanced/Metadata/MetadataScene.unity",
+            "Assets/API-Example/Examples/Advanced/ProcessAudioRawData/ProcessAudioRawDataScene.unity",
+            "Assets/API-Example/Examples/Advanced/ProcessVideoRawData/ProcessVideoRawDataScene.unity",
+            "Assets/API-Example/Examples/Advanced/PushEncodedVideoImage/PushEncodedVideoImageScene.unity",
+            "Assets/API-Example/Examples/Advanced/RtmpStreaming/RtmpStreamingScene.unity",
+            "Assets/API-Example/Examples/Advanced/ScreenShare/ScreenShareScene.unity",
+            "Assets/API-Example/Examples/Advanced/ScreenShareWhileVideoCall/ScreenShareWhileVideoCallScene.unity",
+            "Assets/API-Example/Examples/Advanced/SetBeautyEffectOptions/SetBeautyEffectOptionsScene.unity",
+            "Assets/API-Example/Examples/Advanced/SetEncryption/SetEncryptionScene.unity",
+            "Assets/API-Example/Examples/Advanced/SetVideoEncodeConfiguration/SetVideoEncodeConfigurationScene.unity",
+            "Assets/API-Example/Examples/Advanced/SpatialAudioWithMediaPlayer/SpatialAudioWithMediaPlayerScene.unity",
+            "Assets/API-Example/Examples/Advanced/StartDirectCdnStreaming/StartDirectCdnStreamingScene.unity",
+            "Assets/API-Example/Examples/Advanced/StartLocalVideoTranscoder/StartLocalVideoTranscoderScene.unity",
+            "Assets/API-Example/Examples/Advanced/StartRhythmPlayer/StartRhythmPlayerScene.unity",
+            "Assets/API-Example/Examples/Advanced/StartRtmpStreamWithTranscoding/StartRtmpStreamWithTranscodingScene.unity",
+            "Assets/API-Example/Examples/Advanced/StreamMessage/StreamMessageScene.unity",
+            "Assets/API-Example/Examples/Advanced/TakeSnapshot/TakeSnapshotScene.unity",
+            "Assets/API-Example/Examples/Advanced/VirtualBackground/VirtualBackgroundScene.unity",
+            "Assets/API-Example/Examples/Advanced/VoiceChanger/VoiceChangerScene.unity"
+        };
+        return scenes;
+    }
+
+    [MenuItem("Build/Android")]
+    public static void BuildAndrod()
+    {
+
+        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
+        buildPlayerOptions.scenes = GetAllScenes();
+        buildPlayerOptions.locationPathName = "../Build/Android.apk";
+        buildPlayerOptions.target = BuildTarget.Android;
+        buildPlayerOptions.options = BuildOptions.None;
+
+#if UNITY_2018_4_OR_NEWER
+        BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        BuildSummary summary = report.summary;
+
+        if (summary.result == BuildResult.Succeeded)
+        {
+            Debug.Log("Build Android succeeded: " + summary.totalSize + " bytes");
+        }
+
+        if (summary.result == BuildResult.Failed)
+        {
+            Debug.Log("Build Android failed");
+        }
+#else
+        string message = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        Debug.Log("Build Android: " + message);
+#endif
+    }
+
+
+    [MenuItem("Build/IPhone")]
+    public static void BuildIPhone()
+    {
+        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
+        buildPlayerOptions.scenes = GetAllScenes();
+        buildPlayerOptions.locationPathName = "../Build/IPhone";
+        buildPlayerOptions.target = BuildTarget.iOS;
+        buildPlayerOptions.options = BuildOptions.None;
+
+#if UNITY_2018_4_OR_NEWER
+        BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        BuildSummary summary = report.summary;
+
+        if (summary.result == BuildResult.Succeeded)
+        {
+            Debug.Log("Build IPhone succeeded: " + summary.totalSize + " bytes");
+        }
+
+        if (summary.result == BuildResult.Failed)
+        {
+            Debug.Log("Build IPhone failed");
+        }
+#else
+        string message = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        Debug.Log("Build IPhone: " + message);
+#endif
+    }
+
+    [MenuItem("Build/Mac")]
+    public static void BuildMac()
+    {
+        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
+        buildPlayerOptions.scenes = GetAllScenes();
+        buildPlayerOptions.locationPathName = "../Build/Mac.app";
+        buildPlayerOptions.target = BuildTarget.StandaloneOSX;
+        buildPlayerOptions.options = BuildOptions.None;
+
+#if UNITY_2018_4_OR_NEWER
+        BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        BuildSummary summary = report.summary;
+
+        if (summary.result == BuildResult.Succeeded)
+        {
+            Debug.Log("Build Mac succeeded: " + summary.totalSize + " bytes");
+        }
+
+        if (summary.result == BuildResult.Failed)
+        {
+            Debug.Log("Build Mac failed");
+        }
+#else
+        string message = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        Debug.Log("Build Mac: " + message);
+#endif
+    }
+
+
+    [MenuItem("Build/x86")]
+    public static void BuildWin32()
+    {
+
+        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
+        buildPlayerOptions.scenes = GetAllScenes();
+        buildPlayerOptions.locationPathName = "../Build/x86/x86.exe";
+        buildPlayerOptions.target = BuildTarget.StandaloneWindows;
+        buildPlayerOptions.options = BuildOptions.None;
+
+#if UNITY_2018_4_OR_NEWER
+        BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        BuildSummary summary = report.summary;
+
+        if (summary.result == BuildResult.Succeeded)
+        {
+            Debug.Log("Build x86 succeeded: " + summary.totalSize + " bytes");
+        }
+
+        if (summary.result == BuildResult.Failed)
+        {
+            Debug.Log("Build x86 failed");
+        }
+#else
+        string message = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        Debug.Log("Build Win32: " + message);
+#endif
+
+    }
+
+    [MenuItem("Build/x86_64")]
+    public static void BuildWin64()
+    {
+        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
+        buildPlayerOptions.scenes = GetAllScenes();
+        buildPlayerOptions.locationPathName = "../Build/x86_64/x86_64.exe";
+        buildPlayerOptions.target = BuildTarget.StandaloneWindows64;
+        buildPlayerOptions.options = BuildOptions.None;
+
+#if UNITY_2018_4_OR_NEWER
+        BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        BuildSummary summary = report.summary;
+
+        if (summary.result == BuildResult.Succeeded)
+        {
+            Debug.Log("Build x86_64 succeeded: " + summary.totalSize + " bytes");
+        }
+
+        if (summary.result == BuildResult.Failed)
+        {
+            Debug.Log("Build x86_64 failed");
+        }
+#else
+        string message = BuildPipeline.BuildPlayer(buildPlayerOptions);
+        Debug.Log("Build x86_64: " + message);
+#endif
+
+    }
+
+    [MenuItem("Build/All")]
+    public static void BuildAll()
+    {
+        BuildAndrod();
+        BuildIPhone();
+        BuildMac();
+        BuildWin32();
+        BuildWin64();
+    }
+
+
+}

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/Project/RTC/ProjectRrmoteAssWindow.cs.meta → Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/CommandBuild.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 095bf4eef799e3e48ba8f1d18dafeee5
+guid: eb3b50c9e751a4456a735673fa3790b4
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 40 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/SceneWindow.cs

@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+public class SceneEditorWindow : EditorWindow
+{
+    List<SceneAsset> m_SceneAssets = new List<SceneAsset>();
+
+    // Add menu item named "Example Window" to the Window menu
+    [MenuItem("Build/List Scenes", false, 1)]
+    public static void ShowWindow()
+    {
+        //Show existing window instance. If one doesn't exist, make one.
+        EditorWindow.GetWindow(typeof(SceneEditorWindow));
+    }
+
+    void OnGUI()
+    {
+        GUILayout.Space(8);
+        if (GUILayout.Button("Search and Add Scene files"))
+        {
+            List<EditorBuildSettingsScene> editorBuildSettingsScenes = new List<EditorBuildSettingsScene>();
+            foreach (var file in System.IO.Directory.EnumerateFiles(".", "*.unity", System.IO.SearchOption.AllDirectories))
+            {
+                string scenePath = file.Remove(0, 2);
+                UnityEngine.Debug.Log(scenePath);
+                editorBuildSettingsScenes.Add(new EditorBuildSettingsScene(scenePath, true));
+            }
+            EditorBuildSettings.scenes = editorBuildSettingsScenes.ToArray();
+        }
+
+        GUILayout.Space(8);
+        if (GUILayout.Button("Clear Scene files"))
+        {
+            EditorBuildSettings.scenes = null;
+        }
+    }
+
+
+}

+ 1 - 1
Assets/HotUpdate/Scripts/Scripts/TestLogin.cs.meta → Assets/Remote30/Agora-RTC-Plugin/API-Example/Editor/SceneWindow.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: db1dbbce521bb1341a9dc0fd2c18c618
+guid: 2506364097bac4e859841f21a6314af2
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 153 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Home.cs

@@ -0,0 +1,153 @@
+using System.Collections;
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.SceneManagement;
+using Agora.Util;
+
+public class Home : MonoBehaviour
+{
+    public InputField AppIdInupt;
+    public InputField ChannelInput;
+    public InputField TokenInput;
+
+    public AppIdInput AppInputConfig;
+    public GameObject CasePanel;
+    public GameObject CaseScrollerView;
+
+    public GameObject EventSystem;
+
+    private string _playSceneName = "";
+
+
+    private string[] _baseSceneNameList = {
+        "BasicAudioCallScene",
+        "BasicVideoCallScene"
+    };
+
+    private string[] _advancedNameList = {
+        "AudioMixingScene",
+        "AudioSpectrumScene",
+        "ChannelMediaRelayScene",
+        "ContentInspectScene",
+        "CustomCaptureAudioScene",
+        "CustomCaptureVideoScene",
+        "CustomRenderAudioScene",
+        "DeviceManagerScene",
+        "DualCameraScene",
+        "JoinChannelVideoTokenScene",
+        "JoinChannelWithUserAccountScene",
+        "MediaPlayerScene",
+        "MediaPlayerWithCustomDataProviderScene",
+        "MediaRecorderScene",
+        "MetadataScene",
+        "ProcessAudioRawDataScene",
+        "ProcessVideoRawDataScene",
+        "PushEncodedVideoImageScene",
+        "ScreenShareScene",
+        "ScreenShareWhileVideoCallScene",
+        "SetBeautyEffectOptionsScene",
+        "SetEncryptionScene",
+        "SetVideoEncodeConfigurationScene",
+        "StartLocalVideoTranscoderScene",
+        "SpatialAudioWithMediaPlayerScene",
+        "StartDirectCdnStreamingScene",
+        "StartRhythmPlayerScene",
+        "StartRtmpStreamWithTranscodingScene",
+        "StreamMessageScene",
+        "TakeSnapshotScene",
+        "VirtualBackgroundScene",
+        "VoiceChangerScene"
+    };
+
+    private void Awake()
+    {
+        PermissionHelper.RequestMicrophontPermission();
+        PermissionHelper.RequestCameraPermission();
+
+        GameObject content = GameObject.Find("Content");
+        var contentRectTrans = content.GetComponent<RectTransform>();
+
+        for (int i = 0; i < _baseSceneNameList.Length; i++)
+        {
+            var go = Instantiate(CasePanel, content.transform);
+            var name = go.transform.Find("Text").gameObject.GetComponent<Text>();
+            name.text = _baseSceneNameList[i];
+            var button = go.transform.Find("Button").gameObject.GetComponent<Button>();
+            button.onClick.AddListener(OnJoinSceneClicked);
+            button.onClick.AddListener(SetScolllerActive);
+        }
+
+        for (int i = 0; i < _advancedNameList.Length; i++)
+        {
+            var go = Instantiate(CasePanel, content.transform);
+            var name = go.transform.Find("Text").gameObject.GetComponent<Text>();
+            name.text = _advancedNameList[i];
+            var button = go.transform.Find("Button").gameObject.GetComponent<Button>();
+            button.onClick.AddListener(OnJoinSceneClicked);
+            button.onClick.AddListener(SetScolllerActive);
+        }
+
+
+        if (this.AppInputConfig)
+        {
+            this.AppIdInupt.text = this.AppInputConfig.appID;
+            this.ChannelInput.text = this.AppInputConfig.channelName;
+            this.TokenInput.text = this.AppInputConfig.token;
+        }
+
+    }
+
+    // Start is called before the first frame update
+    private void Start()
+    {
+
+    }
+
+    // Update is called once per frame
+    private void Update()
+    {
+
+    }
+
+    private void OnApplicationQuit()
+    {
+        Debug.Log("OnApplicationQuit");
+    }
+
+    public void OnLeaveButtonClicked()
+    {
+        StartCoroutine(UnloadSceneAsync());
+        CaseScrollerView.SetActive(true);
+    }
+
+    public IEnumerator UnloadSceneAsync()
+    {
+        if (this._playSceneName != "")
+        {
+            AsyncOperation async = SceneManager.UnloadSceneAsync(_playSceneName);
+            yield return async;
+            EventSystem.gameObject.SetActive(true);
+        }
+    }
+
+    public void OnJoinSceneClicked()
+    {
+        this.AppInputConfig.appID = this.AppIdInupt.text;
+        this.AppInputConfig.channelName = this.ChannelInput.text;
+        this.AppInputConfig.token = this.TokenInput.text;
+
+        var button = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject;
+        var sceneName = button.transform.parent.Find("Text").gameObject.GetComponent<Text>().text;
+
+        EventSystem.gameObject.SetActive(false);
+
+        SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
+        this._playSceneName = sceneName;
+
+    }
+
+    public void SetScolllerActive()
+    {
+        CaseScrollerView.SetActive(false);
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Home.cs.meta

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

+ 2417 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/HomeScene.unity

@@ -0,0 +1,2417 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.5748249, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 0
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 500
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 2
+    m_PVRDenoiserTypeDirect: 0
+    m_PVRDenoiserTypeIndirect: 0
+    m_PVRDenoiserTypeAO: 0
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 0
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &20064290
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 20064291}
+  - component: {fileID: 20064293}
+  - component: {fileID: 20064292}
+  m_Layer: 5
+  m_Name: Content
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &20064291
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 20064290}
+  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: 237592859}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0.000024704623, y: 0.000009595477}
+  m_SizeDelta: {x: -3, y: 0}
+  m_Pivot: {x: 0, y: 1}
+--- !u!114 &20064292
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 20064290}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalFit: 0
+  m_VerticalFit: 2
+--- !u!114 &20064293
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 20064290}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Padding:
+    m_Left: 0
+    m_Right: 0
+    m_Top: 0
+    m_Bottom: 0
+  m_ChildAlignment: 0
+  m_Spacing: 20
+  m_ChildForceExpandWidth: 0
+  m_ChildForceExpandHeight: 0
+  m_ChildControlWidth: 0
+  m_ChildControlHeight: 0
+  m_ChildScaleWidth: 0
+  m_ChildScaleHeight: 0
+--- !u!1 &82540983
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 82540984}
+  - component: {fileID: 82540985}
+  - component: {fileID: 82540986}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &82540984
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 82540983}
+  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: 958552243}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &82540985
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 82540983}
+  m_CullTransparentMesh: 0
+--- !u!114 &82540986
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 82540983}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!1 &98763800
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 98763801}
+  - component: {fileID: 98763803}
+  - component: {fileID: 98763802}
+  m_Layer: 5
+  m_Name: SDKText
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &98763801
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 98763800}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0.9999968, y: 0.9999968, z: 0.9999968}
+  m_Children: []
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 544.00006, y: 210.7}
+  m_SizeDelta: {x: 338, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &98763802
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 98763800}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 3
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'SDK Version: 4.0.0'
+--- !u!222 &98763803
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 98763800}
+  m_CullTransparentMesh: 0
+--- !u!1 &112708733
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 112708737}
+  - component: {fileID: 112708736}
+  - component: {fileID: 112708735}
+  - component: {fileID: 112708734}
+  - component: {fileID: 112708738}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &112708734
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 112708733}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &112708735
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 112708733}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 1
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 1280, y: 720}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0.856
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+--- !u!223 &112708736
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 112708733}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 0
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &112708737
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 112708733}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_Children:
+  - {fileID: 1413793155}
+  - {fileID: 1783804914}
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!114 &112708738
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 112708733}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: c7b548af9d337405f889b92c979c9e36, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  AppIdInupt: {fileID: 958552242}
+  ChannelInput: {fileID: 1085297498}
+  TokenInput: {fileID: 444718502}
+  AppInputConfig: {fileID: 11400000, guid: 300c6525f002a4dbaac41a5c4b054e35, type: 2}
+  CasePanel: {fileID: 1036881438794844, guid: 2496050ad79454c69b7285bad8bdc7d5, type: 3}
+  CaseScrollerView: {fileID: 1783804913}
+  EventSystem: {fileID: 260626451}
+--- !u!1 &237592858
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 237592859}
+  - component: {fileID: 237592862}
+  - component: {fileID: 237592861}
+  - component: {fileID: 237592860}
+  m_Layer: 5
+  m_Name: Viewport
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &237592859
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 237592858}
+  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: 20064291}
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 1}
+--- !u!114 &237592860
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 237592858}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &237592861
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 237592858}
+  m_CullTransparentMesh: 0
+--- !u!114 &237592862
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 237592858}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_ShowMaskGraphic: 0
+--- !u!1 &260626451
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 260626454}
+  - component: {fileID: 260626453}
+  - component: {fileID: 260626452}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &260626452
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 260626451}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalAxis: Horizontal
+  m_VerticalAxis: Vertical
+  m_SubmitButton: Submit
+  m_CancelButton: Cancel
+  m_InputActionsPerSecond: 10
+  m_RepeatDelay: 0.5
+  m_ForceModuleActive: 0
+--- !u!114 &260626453
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 260626451}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 5
+--- !u!4 &260626454
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 260626451}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &330805450
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 330805451}
+  - component: {fileID: 330805453}
+  - component: {fileID: 330805452}
+  m_Layer: 0
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &330805451
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330805450}
+  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: 1413793155}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &330805452
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330805450}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Return
+--- !u!222 &330805453
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330805450}
+  m_CullTransparentMesh: 0
+--- !u!1 &369058273
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 369058277}
+  - component: {fileID: 369058276}
+  - component: {fileID: 369058275}
+  - component: {fileID: 369058274}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &369058274
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 369058273}
+  m_Enabled: 0
+--- !u!124 &369058275
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 369058273}
+  m_Enabled: 1
+--- !u!20 &369058276
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 369058273}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 2
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_FocalLength: 50
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &369058277
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 369058273}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &444718501
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 444718503}
+  - component: {fileID: 444718505}
+  - component: {fileID: 444718504}
+  - component: {fileID: 444718502}
+  m_Layer: 5
+  m_Name: TokenInputField
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &444718502
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 444718501}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 444718504}
+  m_TextComponent: {fileID: 1567269256}
+  m_Placeholder: {fileID: 1103881581}
+  m_ContentType: 0
+  m_InputType: 0
+  m_AsteriskChar: 42
+  m_KeyboardType: 0
+  m_LineType: 0
+  m_HideMobileInput: 0
+  m_CharacterValidation: 0
+  m_CharacterLimit: 0
+  m_OnEndEdit:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_CustomCaretColor: 0
+  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
+  m_Text: 
+  m_CaretBlinkRate: 0.85
+  m_CaretWidth: 1
+  m_ReadOnly: 0
+  m_ShouldActivateOnSelect: 1
+--- !u!224 &444718503
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 444718501}
+  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: 1103881583}
+  - {fileID: 1567269254}
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 8
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 543, y: -193.90002}
+  m_SizeDelta: {x: 340, y: 55.7}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &444718504
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 444718501}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &444718505
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 444718501}
+  m_CullTransparentMesh: 0
+--- !u!1 &645418226
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 645418227}
+  m_Layer: 5
+  m_Name: Sliding Area
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &645418227
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 645418226}
+  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: 2042549588}
+  m_Father: {fileID: 1409839258}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: -20, y: -20}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &922351949
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 922351950}
+  - component: {fileID: 922351952}
+  - component: {fileID: 922351951}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &922351950
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 922351949}
+  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: 1783804914}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 455, y: 146.00002}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &922351951
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 922351949}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'APP ID:'
+--- !u!222 &922351952
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 922351949}
+  m_CullTransparentMesh: 0
+--- !u!1 &958552241
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 958552243}
+  - component: {fileID: 958552245}
+  - component: {fileID: 958552244}
+  - component: {fileID: 958552242}
+  m_Layer: 5
+  m_Name: AppIdInputField
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &958552242
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 958552241}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 958552244}
+  m_TextComponent: {fileID: 82540986}
+  m_Placeholder: {fileID: 1414058528}
+  m_ContentType: 0
+  m_InputType: 0
+  m_AsteriskChar: 42
+  m_KeyboardType: 0
+  m_LineType: 0
+  m_HideMobileInput: 0
+  m_CharacterValidation: 0
+  m_CharacterLimit: 0
+  m_OnEndEdit:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_CustomCaretColor: 0
+  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
+  m_Text: 
+  m_CaretBlinkRate: 0.85
+  m_CaretWidth: 1
+  m_ReadOnly: 0
+  m_ShouldActivateOnSelect: 1
+--- !u!224 &958552243
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 958552241}
+  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: 1414058530}
+  - {fileID: 82540984}
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 543, y: 93.1}
+  m_SizeDelta: {x: 340, y: 55.7}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &958552244
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 958552241}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &958552245
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 958552241}
+  m_CullTransparentMesh: 0
+--- !u!1 &1085297497
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1085297499}
+  - component: {fileID: 1085297501}
+  - component: {fileID: 1085297500}
+  - component: {fileID: 1085297498}
+  m_Layer: 5
+  m_Name: ChannelInputField
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1085297498
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1085297497}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1085297500}
+  m_TextComponent: {fileID: 1222550865}
+  m_Placeholder: {fileID: 1453378164}
+  m_ContentType: 0
+  m_InputType: 0
+  m_AsteriskChar: 42
+  m_KeyboardType: 0
+  m_LineType: 0
+  m_HideMobileInput: 0
+  m_CharacterValidation: 0
+  m_CharacterLimit: 0
+  m_OnEndEdit:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_CustomCaretColor: 0
+  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
+  m_Text: Unity_Channel
+  m_CaretBlinkRate: 0.85
+  m_CaretWidth: 1
+  m_ReadOnly: 0
+  m_ShouldActivateOnSelect: 1
+--- !u!224 &1085297499
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1085297497}
+  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: 1453378166}
+  - {fileID: 1222550863}
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 6
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 543, y: -50.899998}
+  m_SizeDelta: {x: 340, y: 55.7}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1085297500
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1085297497}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1085297501
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1085297497}
+  m_CullTransparentMesh: 0
+--- !u!1 &1103881580
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1103881583}
+  - component: {fileID: 1103881582}
+  - component: {fileID: 1103881581}
+  m_Layer: 5
+  m_Name: Placeholder
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1103881581
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1103881580}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 2
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Enter text...
+--- !u!222 &1103881582
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1103881580}
+  m_CullTransparentMesh: 0
+--- !u!224 &1103881583
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1103881580}
+  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: 444718503}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1222550862
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1222550863}
+  - component: {fileID: 1222550864}
+  - component: {fileID: 1222550865}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1222550863
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1222550862}
+  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: 1085297499}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &1222550864
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1222550862}
+  m_CullTransparentMesh: 0
+--- !u!114 &1222550865
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1222550862}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Unity_Channel
+--- !u!1 &1409839257
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1409839258}
+  - component: {fileID: 1409839261}
+  - component: {fileID: 1409839260}
+  - component: {fileID: 1409839259}
+  m_Layer: 5
+  m_Name: Scrollbar Vertical
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1409839258
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1409839257}
+  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: 645418227}
+  m_Father: {fileID: 1783804914}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 1, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 20, y: 0}
+  m_Pivot: {x: 1, y: 1}
+--- !u!114 &1409839259
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1409839257}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 2042549589}
+  m_HandleRect: {fileID: 2042549588}
+  m_Direction: 2
+  m_Value: 1
+  m_Size: 1
+  m_NumberOfSteps: 0
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+--- !u!114 &1409839260
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1409839257}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1409839261
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1409839257}
+  m_CullTransparentMesh: 0
+--- !u!1 &1413793154
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1413793155}
+  - component: {fileID: 1413793158}
+  - component: {fileID: 1413793157}
+  - component: {fileID: 1413793156}
+  m_Layer: 0
+  m_Name: Button
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1413793155
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1413793154}
+  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: 330805451}
+  m_Father: {fileID: 112708737}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 1, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: -67, y: -63}
+  m_SizeDelta: {x: 77.29999, y: 68.79999}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1413793156
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1413793154}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1413793157}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 112708738}
+        m_MethodName: OnLeaveButtonClicked
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+--- !u!114 &1413793157
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1413793154}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1413793158
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1413793154}
+  m_CullTransparentMesh: 0
+--- !u!1 &1414058527
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1414058530}
+  - component: {fileID: 1414058529}
+  - component: {fileID: 1414058528}
+  m_Layer: 5
+  m_Name: Placeholder
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1414058528
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1414058527}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 2
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Enter text...
+--- !u!222 &1414058529
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1414058527}
+  m_CullTransparentMesh: 0
+--- !u!224 &1414058530
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1414058527}
+  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: 958552243}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1453378163
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1453378166}
+  - component: {fileID: 1453378165}
+  - component: {fileID: 1453378164}
+  m_Layer: 5
+  m_Name: Placeholder
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1453378164
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1453378163}
+  m_Enabled: 0
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 2
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Enter text...
+--- !u!222 &1453378165
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1453378163}
+  m_CullTransparentMesh: 0
+--- !u!224 &1453378166
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1453378163}
+  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: 1085297499}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1567269253
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1567269254}
+  - component: {fileID: 1567269255}
+  - component: {fileID: 1567269256}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1567269254
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1567269253}
+  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: 444718503}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: -0.5}
+  m_SizeDelta: {x: -20, y: -13}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &1567269255
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1567269253}
+  m_CullTransparentMesh: 0
+--- !u!114 &1567269256
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1567269253}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!1 &1638969926
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1638969928}
+  - component: {fileID: 1638969927}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1638969927
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1638969926}
+  m_Enabled: 1
+  serializedVersion: 10
+  m_Type: 1
+  m_Shape: 0
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.802082
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1638969928
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1638969926}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &1770001163
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1770001164}
+  - component: {fileID: 1770001166}
+  - component: {fileID: 1770001165}
+  m_Layer: 5
+  m_Name: Text (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1770001164
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1770001163}
+  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: 1783804914}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 455, y: 2}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1770001165
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1770001163}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Channel
+--- !u!222 &1770001166
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1770001163}
+  m_CullTransparentMesh: 0
+--- !u!1 &1783804913
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1783804914}
+  - component: {fileID: 1783804917}
+  - component: {fileID: 1783804916}
+  - component: {fileID: 1783804915}
+  m_Layer: 5
+  m_Name: Scroll View
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1783804914
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1783804913}
+  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: 237592859}
+  - {fileID: 1409839258}
+  - {fileID: 98763801}
+  - {fileID: 922351950}
+  - {fileID: 958552243}
+  - {fileID: 1770001164}
+  - {fileID: 1085297499}
+  - {fileID: 2068508248}
+  - {fileID: 444718503}
+  m_Father: {fileID: 112708737}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: -223, y: 0}
+  m_SizeDelta: {x: 600, y: 700}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1783804915
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1783804913}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 0.392}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1783804916
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1783804913}
+  m_CullTransparentMesh: 0
+--- !u!114 &1783804917
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1783804913}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Content: {fileID: 20064291}
+  m_Horizontal: 0
+  m_Vertical: 1
+  m_MovementType: 1
+  m_Elasticity: 0.1
+  m_Inertia: 1
+  m_DecelerationRate: 0.135
+  m_ScrollSensitivity: 1
+  m_Viewport: {fileID: 237592859}
+  m_HorizontalScrollbar: {fileID: 0}
+  m_VerticalScrollbar: {fileID: 1409839259}
+  m_HorizontalScrollbarVisibility: 2
+  m_VerticalScrollbarVisibility: 2
+  m_HorizontalScrollbarSpacing: -3
+  m_VerticalScrollbarSpacing: 0
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+--- !u!1 &2042549587
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2042549588}
+  - component: {fileID: 2042549590}
+  - component: {fileID: 2042549589}
+  m_Layer: 5
+  m_Name: Handle
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2042549588
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2042549587}
+  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: 645418227}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 20, y: 20}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2042549589
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2042549587}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &2042549590
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2042549587}
+  m_CullTransparentMesh: 0
+--- !u!1 &2068508247
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2068508248}
+  - component: {fileID: 2068508250}
+  - component: {fileID: 2068508249}
+  m_Layer: 5
+  m_Name: Text (2)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2068508248
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2068508247}
+  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: 1783804914}
+  m_RootOrder: 7
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 455, y: -141}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2068508249
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2068508247}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'Token:'
+--- !u!222 &2068508250
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2068508247}
+  m_CullTransparentMesh: 0

+ 7 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/HomeScene.unity.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Image.meta

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

BIN
Assets/Remote30/Agora-RTC-Plugin/API-Example/Image/agora2.png


+ 152 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Image/agora2.png.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab.meta

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

+ 353 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab/CasePanel.prefab

@@ -0,0 +1,353 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1036881438794844
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 224345646677206142}
+  - component: {fileID: 222977441614407690}
+  - component: {fileID: 114185648007682220}
+  m_Layer: 5
+  m_Name: CasePanel
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &224345646677206142
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1036881438794844}
+  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: 224308374033113526}
+  - {fileID: 224938511741827896}
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 0, y: 1}
+  m_AnchoredPosition: {x: 623, y: -93}
+  m_SizeDelta: {x: 580, y: 80}
+  m_Pivot: {x: 0, y: 1}
+--- !u!222 &222977441614407690
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1036881438794844}
+  m_CullTransparentMesh: 0
+--- !u!114 &114185648007682220
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1036881438794844}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 0.712}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 07f7a6254fefb42078aed732c77c3cda, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &1130559936070958
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 224918487906776580}
+  - component: {fileID: 222387459500286586}
+  - component: {fileID: 114531629486495798}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &224918487906776580
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1130559936070958}
+  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: 224308374033113526}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &222387459500286586
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1130559936070958}
+  m_CullTransparentMesh: 0
+--- !u!114 &114531629486495798
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1130559936070958}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Jump
+--- !u!1 &1610732099111804
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 224938511741827896}
+  - component: {fileID: 222656902020873038}
+  - component: {fileID: 114064395545068140}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &224938511741827896
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1610732099111804}
+  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: 224345646677206142}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 300, y: 31.1}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &222656902020873038
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1610732099111804}
+  m_CullTransparentMesh: 0
+--- !u!114 &114064395545068140
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1610732099111804}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 20
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 2
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: BasicVideoCall
+--- !u!1 &1966949020592634
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 224308374033113526}
+  - component: {fileID: 222780278525291890}
+  - component: {fileID: 114681506339907642}
+  - component: {fileID: 114300398960532148}
+  m_Layer: 5
+  m_Name: Button
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &224308374033113526
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1966949020592634}
+  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: 224918487906776580}
+  m_Father: {fileID: 224345646677206142}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 222, y: 0}
+  m_SizeDelta: {x: 74.8, y: 62.2}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &222780278525291890
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1966949020592634}
+  m_CullTransparentMesh: 0
+--- !u!114 &114681506339907642
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1966949020592634}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!114 &114300398960532148
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1966949020592634}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 114681506339907642}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls: []

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Prefab/CasePanel.prefab.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2496050ad79454c69b7285bad8bdc7d5
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 100100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 106 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/README.md

@@ -0,0 +1,106 @@
+# API-Example-Unity
+
+*__其他语言版本:__  [__简体中文__](README.zh.md)*
+
+## Overview
+
+The API-Example-Unity project is an open-source demo that will show you different scenes on how to integrate Agora SDK APIs into your project.
+
+Any scene of this project can run successfully alone.
+
+## Project structure
+
+* **Basic demos:**
+
+| Demo                                                         | Description                                        | APIs                                                         |
+| ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ |
+| [JoinChannelAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Basic/JoinChannelAudio) | basic demo to show audio call                      | CreateAgoraRtcEngine, JoinChannel, LeaveChannel              |
+| [JoinChannelVideo](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Basic/JoinChannelVideo) | video demo with role selection in Editor Inspector | SetChannelProfile,SetClientRole,EnableVideo,EnableVideo, JoinChannel, VideoSurface |
+
+* **Advanced demos:**
+
+| Demo                                                         | Description                                                  | APIs                                                         |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [AudioMixing](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/AudioMixing) | audioMixing and play audio effect in the channel             | StartAudioMixing, PlayEffect                                 |
+| [AudioSpectrum](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/AudioSpectrum) | audio spectrum             | IAudioSpectrumObserver, RegisterMediaPlayerAudioSpectrumObserver                                 |
+| [ChannelMediaRelay](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ChannelMediaRelay) | start cross channel media streaming forwarding. This method can be used to realize cross channel wheat connection and other scenes. | StartChannelMediaRelay, UpdateChannelMediaRelay, PauseAllChannelMediaRelay, ResumeAllChannelMediaRelay, StopChannelMediaRelay |
+| [ContentInspect](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ContentInspect) | content inspect | SetContentInspect |
+| [CustomCaptureAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomCaptureAudio) | Sending raw data from AudioSource into the Agora channel     | PushAudioFrame                                               |
+| [CustomCaptureVideo](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomCaptureVideo) | Sending raw data from VideoSource into the Agora channel     | PushVideoFrame                                               |
+| [CustomRenderAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomRenderAudio) | use AudioSource to play raw data received in the Agora channel | PullAudioFrame                                               |
+| [DeviceManager](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/DeviceManager) | show how to get and set Device on the desktop platforms      | GetAudioDeviceManager, GetVideoDeviceManager                 |
+| [DualCamera](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/DualCamera) | show how to use dual camera to capture data                  | StartPrimaryCameraCapture, StartSecondaryCameraCapture       |
+| [JoinChannelVideoToken](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/JoinChannelVideoToken) | demo on how to run Agora app with a token                    | RenewToken                                                   |
+| [JoinChannelWithUserAccount](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/JoinChannelWithUserAccount) | demo on how to join channel with user account                | JoinChannelWithUserAccount,   GetUserInfoByUserAccount       |
+| [MediaPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/MediaPlayer) | how to  play media                                           | CreateMediaPlayer,  Play, Stop                               |
+| [MediaRecorder](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/MediaRecorder) | Media recording                  | StartRecording,  StopRecording,                                                |
+| [Metadata](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/Metadata) | send meta data                  | IMetadataObserver                                                |
+| [ProcessAudioRawData](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ProcessAudioRawData) | process raw Audio data in rtc engine and play with audioclip                       | RegisterAudioFrameObserver, OnPlaybackAudioFrame, OnRceordAudioFrame |
+| [ProcessVideoRawData](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ProcessVideoRawData) | process raw Video data in rtc engine and render with texture                       | RegisterVideoFrameObserver, OnCaptureVideoFrame, OnRenderVideoFrame |
+| [PushEncodedVideoImage](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/PushEncodedVideoImage) | push encoded data in rtc engine                              | PushEncodedVideoImage                                        |
+| [ScreenShare](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ScreenShare) | sharing screen view with rtc engine                          | StartScreenCaptureByWindowId, StartScreenCaptureByDisplayId  |
+| [ScreenShareWhileVideoCall](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ScreenShareWhileVideoCall) | sharing screen view while with a video call                  | StartScreenCaptureByWindowId, StartScreenCaptureByDisplayId  |
+| [SetBeautyEffectOptions](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetBeautyEffectOptions) | Turn on beauty during video call                             | SetBeautyEffectOptions                                       |
+| [SetEncryption](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetEncryption) | sending video with encryption                                | EnableEncryption                                             |
+| [SetVideoEncoderConfiguration](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetVideoEncoderConfiguration) | video demo with multiple encoding dimension choice           | SetVideoEncoderConfiguration                                 |
+| [SpatialAudioWithMediaPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SpatialAudioWithMediaPlayer) | play media with spatial audio                                | GetLocalSpatialAudioEngine, UpdateRemotePositionEx           |
+| [StartLocalVideoTranscoder](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartLocalVideoTranscoder) | Merging of multiple video sources, options are jpg,png,gif,medai,etc | StartLocalVideoTranscoder                                    |
+| [StartDirectCdnStreaming](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartDirectCdnStreaming) | stream video by RTMP Push to a CDN          | StartDirectCdnStreaming, SetDirectCdnStreamingVideoConfiguration, StopDirectCdnStreaming                               |
+| [StartRhythmPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartRhythmPlayer) | use phythm player in rtc engine                              | StartRhythmPlayer                                            |
+| [StartRtmpStreamWithTranscoding](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartRtmpStreamWithTranscoding) | stream video by RTMP Push to a CDN                           | StartRtmpStreamWithTranscoding, UpdateRtmpTranscoding, StopRtmpStream |
+| [StreamMessage](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StreamMessage) | how to send stream message                                   | CreateDataStream, SendStreamMessage                          |
+| [TakeSnapshot](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/TakeSnapshot) | how to screen shot                                           | TakeSnapshot                                                 |
+| [VirtualBackground](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/VirtualBackground) | enable virtual background                                    | EnableVirtualBackground                                      |
+| [VoiceChanger](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/VoiceChanger) | how to modify your voice                                     | SetVoiceBeautifierPreset, SetAudioEffectPreset,SetVoiceConversionPreset,SetLocalVoicePitch, SetLocalVoiceEqualization,   SetLocalVoiceReverb |
+
+## How to run the sample project
+
+#### Developer Environment Requirements
+
+* Unity 2017 LTS and up
+
+#### Steps to run
+
+First, create a developer account at [Agora.io](https://dashboard.agora.io/signin/), and obtain an App ID.
+
+Then do the following:
+
+1. Clone this repository.
+
+2. Open the project in Unity Editor. Note that you will see compiler errors before you download the SDK package.
+
+3. You may download the SDK package in either of the following two ways:
+
+    a. From Unity Asset Store download and import [the Agora Video SDK](https://assetstore.unity.com/packages/tools/video/agora-video-chat-sdk-for-unity-134502)
+    
+    b. Download the ******Agora Video SDK****** from [Agora.io SDK](https://docs.agora.io/en/Video/downloads?platform=Unity). Unzip the downloaded SDK package and import into Unity project
+
+4.  Fill your App ID into the ******API-Example-Unity/Assets/API-Example/appIdInput/AppIdInput.asset****** 
+
+5.  Choose one of the scene that you want to run
+
+Run the game and you are now good to go!
+
+
+
+## Feedback
+
+If you have any problems or suggestions regarding the sample projects, feel free to file an issue.
+
+## Reference
+
+- You can find full API document at [Document Center](https://docs.agora.io/en/video-call-4.x/api-ref)
+- You can find full release note at [Release Note](https://docs.agora.io/en/video-call-4.x/release_unity_ng?platform=Unity)
+- You can file issues about this demo at [issue](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/issues)
+
+## Related resources
+
+- Check our [FAQ](https://docs.agora.io/en/faq) to see if your issue has been recorded.
+- Dive into [Agora SDK Samples](https://github.com/AgoraIO) to see more tutorials
+- Take a look at [Agora Use Case](https://github.com/AgoraIO-usecase) for more complicated real use case
+- Take a look at [AgoraIO-Extensions](https://github.com/AgoraIO-Extensions) for Crossplatform and Marketing-place projects
+- Repositories managed by developer communities can be found at [Agora Community](https://github.com/AgoraIO-Community)
+- If you encounter problems during integration, feel free to ask questions in [Stack Overflow](https://stackoverflow.com/questions/tagged/agora.io)
+
+## License
+The sample projects are under the MIT license.

+ 7 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/README.md.meta

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

+ 98 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/README.zh.md

@@ -0,0 +1,98 @@
+# API-Example-Unity
+
+*Read this in other languages: [English](README.md)*
+
+## 简介
+
+这个开源示例项目演示了不同场景下,Agora SDK 的基本集成逻辑。 项目中每个 Scene 都是一个独立的场景,都可以成功独立运行。
+
+在这个示例项目中包含的所有场景都可以独立运行:
+
+## 项目结构
+
+* **基础案例:**
+
+| Demo                                                         | Description                                        | APIs                                                         |
+| ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ |
+| [JoinChannelAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Basic/JoinChannelAudio) | 基础音频通话                      | CreateAgoraRtcEngine, JoinChannelByKey, LeaveChannel                    |
+| [JoinChannelVideo](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Basic/JoinChannelVideo) | 基础视频通话 | SetChannelProfile,SetClientRole,EnableVideo,EnableVideo, JoinChannelByKey, VideoSurface |
+
+* **进阶案例:**
+
+| Demo                                                         | Description                                                  | APIs                                                         |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [AudioMixing](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/AudioMixing) | 在频道内播放混音和已音效             | StartAudioMixing, PlayEffect                                 |
+| [AudioSpectrum](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/AudioSpectrum) | 媒体音谱功能             | IAudioSpectrumObserver, RegisterMediaPlayerAudioSpectrumObserver                                 |
+| [ChannelMediaRelay](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ChannelMediaRelay) | 启动跨通道媒体流转发。该方法可用于实现跨通道连麦等场景。            | StartChannelMediaRelay, UpdateChannelMediaRelay, PauseAllChannelMediaRelay, ResumeAllChannelMediaRelay, StopChannelMediaRelay                      |
+| [ContentInspect](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ContentInspect) | 内容鉴定 | SetContentInspect |
+| [CustomCaptureAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomCaptureAudio) | 推送外部音频帧     | PushAudioFrame                                               |
+| [CustomCaptureVideo](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomCaptureVideo) | 推送外部视频帧     | PushVideoFrame                                               |
+| [CustomRenderAudio](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/CustomRenderAudio) |  拉取远端音频数据 | PullAudioFrame                                               |
+| [DeviceManager](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/DeviceManager) | 获取当前的音视频设备信息      | GetAudioDeviceManager, GetVideoDeviceManager |
+| [DualCamera](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/DualCamera) | 双摄像头工作  | StartPrimaryCameraCapture, StartSecondaryCameraCapture |
+| [JoinChannelVideoToken](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/JoinChannelVideoToken) | 使用Token加入频道和更新Token                    | RenewToken                                                   |
+| [JoinChannelWithUserAccount](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/JoinChannelWithUserAccount) | 使用用户账号加入频道                  | JoinChannelWithUserAccount,   GetUserInfoByUserAccount                                                 |
+| [MediaPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/MediaPlayer) | 播放媒体文件                  | CreateMediaPlayer,  Play, Stop                                               |
+| [MediaRecorder](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/MediaRecorder) | 媒体录制                  | StartRecording,  StopRecording,                                                |
+| [Metadata](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/Metadata) | 发送元数据                  | IMetadataObserver                                                |
+| [ProcessAudioRawData](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ProcessAudioRawData) | 获注册音频裸数据观测器,并用audioclip播放获取到的音频数据                       | RegisterAudioFrameObserver, OnPlaybackAudioFrame, OnRceordAudioFrame |
+| [ProcessVideoRawData](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ProcessVideoRawData) | 注册视频裸数据观测器,并渲染在Texture上                       | RegisterVideoFrameObserver, OnCaptureVideoFrame, OnRenderVideoFrame |
+| [PushEncodedVideoImage](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/PushEncodedVideoImage) | 发送结构化数据 | PushEncodedVideoImage |
+| [ScreenShare](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ScreenShare) | 屏幕共享            | StartScreenCaptureByWindowId, StartScreenCaptureByDisplayId                       |
+| [ScreenShareWhileVideoCall](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/ScreenShareWhileVideoCall) | 在视频通话时进行屏幕共享            | StartScreenCaptureByWindowId, StartScreenCaptureByDisplayId                       |
+| [SetBeautyEffectOptions](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetBeautyEffectOptions) | 开启美颜效果            | SetBeautyEffectOptions                   |
+| [SetEncryption](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetEncryption) | 开启或关闭内置加密                                | EnableEncryption                                             |
+| [SetVideoEncoderConfiguration](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SetVideoEncoderConfiguration) | 设置视频编码属性。           | SetVideoEncoderConfiguration                                 |
+| [SpatialAudioWithMediaPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/SpatialAudioWithMediaPlayer) | 使用空间音效播放媒体文件        | GetLocalSpatialAudioEngine, UpdateRemotePositionEx                                 |
+| [StartDirectCdnStreaming](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartDirectCdnStreaming) | cdn推流        | StartDirectCdnStreaming, SetDirectCdnStreamingVideoConfiguration, StopDirectCdnStreaming                               |
+| [StartLocalVideoTranscoder](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartLocalVideoTranscoder) | 多路视频合成一路,可以合成png,jpg,jif等等         | StartLocalVideoTranscoder                        |
+| [StartRhythmPlayer](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartRhythmPlayer) | 开启节拍器        | StartRhythmPlayer                        |
+| [StartRtmpStreamWithTranscoding](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StartRtmpStreamWithTranscoding) | 推流到CDN        | StartRtmpStreamWithTranscoding, UpdateRtmpTranscoding, StopRtmpStream                        |
+| [StreamMessage](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/StreamMessage) | 发送流数据        | CreateDataStream, SendStreamMessage                        |
+| [TakeSnapshot](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/TakeSnapshot) | 屏幕截图      | TakeSnapshot                        |
+| [VirtualBackground](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/VirtualBackground) | 开启虚拟背景   | EnableVirtualBackground                 |
+| [VoiceChanger](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/tree/release/4.0.0/API-Example-Unity/Assets/API-Example/Examples/Advanced/VoiceChanger) | 变声设置   | SetVoiceBeautifierPreset, SetAudioEffectPreset,SetVoiceConversionPreset,SetLocalVoicePitch, SetLocalVoiceEqualization,   SetLocalVoiceReverb                  |
+
+
+
+## 如何运行示例程序
+
+#### 运行环境
+
+* Unity 2017 LTS 或以上
+
+#### 运行步骤
+
+* 首先在 [Agora.io 注册](https://dashboard.agora.io/cn/signup/) 注册账号,并创建自己的测试项目,获取到 AppID。
+
+* 然后在 [Agora.io SDK](https://docs.agora.io/cn/Agora%20Platform/downloads) 下载 **Unity SDK**,解压后把 sdk 包中的 unitypackage文件导入工程
+
+* 最后使用 Unity 打开本项目, 将获取到的AppID填入******API-Example-Unity/Assets/API-Example/appIdInput/AppIdInput.asset*****中
+
+* 一切就绪。你可以自由探索示例项目,体验 SDK 的丰富功能。
+
+
+
+## 反馈
+
+如果您对示例项目有任何问题或建议,请随时提交问题。
+
+## 参考文档
+
+- 您可以在 [文档中心](https://docs.agora.io/cn/All/api-ref?platform=Unity)找到完整的API文档
+- 您可以在 [发版说明](https://docs.agora.io/cn/video-call-4.x/release_unity_ng?platform=Unity)找到完整的发版说明
+- 您可以在 [github issue](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/issues)提交你的issue
+
+## 相关资源
+
+- 你可以先参阅[常见问题](https://docs.agora.io/cn/faq)
+- 如果你想了解更多官方示例,可以参考[官方 SDK 示例](https://github.com/AgoraIO)
+- 如果你想了解声网 SDK 在复杂场景下的应用,可以参考[官方场景案例](https://github.com/AgoraIO-usecase)
+- 如果你想了解声网的一些社区开发者维护的项目,可以查看[社区](https://github.com/AgoraIO-Community)
+- 如果你想了解声网的跨平台框架和云市场相关的项目,可以查看[AgoraIO-Extensions](https://github.com/AgoraIO-Extensions)
+- 若遇到问题需要开发者帮助,你可以到[开发者社区](https://rtcdeveloper.com/)提问
+- 如果需要售后技术支持, 你可以在[Agora Dashboard](https://dashboard.agora.io/)提交工单
+
+## 代码许可
+
+示例项目遵守 MIT 许可证。

+ 7 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/README.zh.md.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools.meta

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

+ 41 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/Logger.cs

@@ -0,0 +1,41 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Agora.Util
+{
+    public class Logger
+    {
+        Text text;
+
+        public Logger(Text text)
+        {
+            this.text = text;
+        }
+
+        public void UpdateLog(string logMessage)
+        {
+            Debug.Log(logMessage);
+            string srcLogMessage = text.text;
+            if (srcLogMessage.Length > 400)
+            {
+                srcLogMessage = srcLogMessage.Substring(srcLogMessage.Length - 50);
+            }
+
+            srcLogMessage += "\r\n \r\n";
+            srcLogMessage += logMessage;
+            text.text = srcLogMessage;
+        }
+
+        public bool DebugAssert(bool condition, string message)
+        {
+            if (!condition)
+            {
+                UpdateLog(message);
+                return false;
+            }
+
+            Debug.Assert(condition, message);
+            return true;
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/Logger.cs.meta

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

+ 33 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/PermissionHelper.cs

@@ -0,0 +1,33 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+#if(UNITY_2018_3_OR_NEWER && UNITY_ANDROID)
+using UnityEngine.Android;
+#endif
+
+namespace Agora.Util
+{
+    public class PermissionHelper
+    {
+        public static void RequestMicrophontPermission()
+        {
+#if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID)
+		if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
+		{                 
+			Permission.RequestUserPermission(Permission.Microphone);
+		}
+#endif
+        }
+
+        public static void RequestCameraPermission()
+        {
+#if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID)
+		if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
+		{                 
+			Permission.RequestUserPermission(Permission.Camera);
+		}
+#endif
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/PermissionHelper.cs.meta

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

+ 36 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RequestToken.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections;
+using UnityEngine;
+using UnityEngine.Networking;
+
+[Serializable]
+public class TokenObject {
+  public string rtcToken;
+}
+
+namespace Agora.Util
+{
+  public static class HelperClass
+  {
+    public static IEnumerator FetchToken(
+        string url, string channel, int userId, Action<string> callback = null
+    ) {
+      UnityWebRequest request = UnityWebRequest.Get(string.Format(
+        "{0}/rtc/{1}/publisher/uid/{2}/", url, channel, userId
+      ));
+      yield return request.SendWebRequest();
+
+      if (request.isNetworkError || request.isHttpError) {
+        Debug.Log(request.error);
+        callback(null);
+        yield break;
+      }
+
+      TokenObject tokenInfo = JsonUtility.FromJson<TokenObject>(
+        request.downloadHandler.text
+      );
+
+      callback(tokenInfo.rtcToken);
+    }
+  }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RequestToken.cs.meta

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

+ 253 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RingBuffer.cs

@@ -0,0 +1,253 @@
+#region License
+/* Copyright 2015 Joe Osborne
+ * 
+ * This file is part of RingBuffer.
+ *
+ *  RingBuffer is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  RingBuffer is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with RingBuffer. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace RingBuffer {
+    /// <summary>
+    /// A generic ring buffer with fixed capacity.
+    /// </summary>
+    /// <typeparam name="T">The type of data stored in the buffer</typeparam>
+    public class RingBuffer<T> : IEnumerable<T>, IEnumerable, ICollection<T>, 
+        ICollection {
+
+        protected int head = 0;
+        protected int tail = 0;
+        protected int size = 0;
+
+        protected T[] buffer;
+
+        private bool allowOverflow;
+        public bool AllowOverflow { get { return allowOverflow; } }
+
+        /// <summary>
+        /// The total number of elements the buffer can store (grows).
+        /// </summary>
+        public int Capacity { get { return buffer.Length; } }
+
+        /// <summary>
+        /// The number of elements currently contained in the buffer.
+        /// </summary>
+        public int Size { get { return size; } }
+
+        /// <summary>
+        /// Retrieve the next item from the buffer.
+        /// </summary>
+        /// <returns>The oldest item added to the buffer.</returns>
+        public T Get() {
+            if(size == 0) throw new System.InvalidOperationException("Buffer is empty.");
+            T _item = buffer[head];
+            head = (head + 1) % Capacity;
+            size--;
+            return _item;
+        }
+
+        /// <summary>
+        /// Adds an item to the end of the buffer.
+        /// </summary>
+        /// <param name="item">The item to be added.</param>
+        public void Put(T item) {
+            // If tail & head are equal and the buffer is not empty, assume
+            // that it will overflow and throw an exception.
+            if(tail == head && size != 0) {
+                if(allowOverflow) {
+                    addToBuffer(item, true);
+                }
+                else {
+                    throw new System.InvalidOperationException("The RingBuffer is full");
+                }
+            }
+            // If the buffer will not overflow, just add the item.
+            else {
+                addToBuffer(item, false);
+            }
+        }
+
+        public void Put(T[] item)
+        {
+            foreach (var t in item)
+            {
+                Put(t);
+            }
+        }
+
+        protected void addToBuffer(T toAdd, bool overflow) {
+            if(overflow) {
+                head = (head + 1) % Capacity;
+            }
+            else {
+                size++;
+            }
+            buffer[tail] = toAdd;
+            tail = (tail + 1) % Capacity;
+        }
+
+        #region Constructors
+        // Default capacity is 4, default overflow behavior is false.
+        public RingBuffer() : this(4) { }
+
+        public RingBuffer(int capacity) : this(capacity, false) { }
+
+        public RingBuffer(int capacity, bool overflow) {
+            buffer = new T[capacity];
+            allowOverflow = overflow;
+        }
+        #endregion
+
+        #region IEnumerable Members
+        public IEnumerator<T> GetEnumerator() {
+            int _index = head;
+            for(int i = 0; i < size; i++, _index = (_index + 1) % Capacity) {
+                yield return buffer[_index];
+            }
+        }
+
+        IEnumerator<T> IEnumerable<T>.GetEnumerator() {
+            return GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator() {
+            return (IEnumerator)GetEnumerator();
+        }
+        #endregion
+
+        #region ICollection<T> Members
+        public int Count { get { return size; } }
+        public bool IsReadOnly { get { return false; } }
+
+        public void Add(T item) {
+            Put(item);
+        }
+        
+        /// <summary>
+        /// Determines whether the RingBuffer contains a specific value.
+        /// </summary>
+        /// <param name="item">The value to check the RingBuffer for.</param>
+        /// <returns>True if the RingBuffer contains <paramref name="item"/>
+        /// , false if it does not.
+        /// </returns>
+        public bool Contains(T item) {
+            EqualityComparer<T> comparer = EqualityComparer<T>.Default;
+            int _index = head;
+            for(int i = 0; i < size; i++, _index = (_index + 1) % Capacity) {
+                if(comparer.Equals(item, buffer[_index])) return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Removes all items from the RingBuffer.
+        /// </summary>
+        public void Clear() {
+            for(int i = 0; i < Capacity; i++) {
+                buffer[i] = default(T);
+            }
+            head = 0;
+            tail = 0;
+            size = 0;
+        }
+
+        /// <summary>
+        /// Copies the contents of the RingBuffer to <paramref name="array"/>
+        /// starting at <paramref name="arrayIndex"/>.
+        /// </summary>
+        /// <param name="array">The array to be copied to.</param>
+        /// <param name="arrayIndex">The index of <paramref name="array"/>
+        /// where the buffer should begin copying to.</param>
+        public void CopyTo(T[] array, int arrayIndex) {
+            int _index = head;
+            for(int i = 0; i < size; i++, arrayIndex++, _index = (_index + 1) %
+                Capacity) {
+                array[arrayIndex] = buffer[_index];
+            }
+        }
+
+        /// <summary>
+        /// Removes <paramref name="item"/> from the buffer.
+        /// </summary>
+        /// <param name="item"></param>
+        /// <returns>True if <paramref name="item"/> was found and 
+        /// successfully removed. False if <paramref name="item"/> was not
+        /// found or there was a problem removing it from the RingBuffer.
+        /// </returns>
+        public bool Remove(T item) {
+            int _index = head;
+            int _removeIndex = 0;
+            bool _foundItem = false;
+            EqualityComparer<T> _comparer = EqualityComparer<T>.Default;
+            for(int i = 0; i < size; i++, _index = (_index + 1) % Capacity) {
+                if(_comparer.Equals(item, buffer[_index])) {
+                    _removeIndex = _index;
+                    _foundItem = true;
+                    break;
+                }
+            }
+            if(_foundItem) {
+                T[] _newBuffer = new T[size - 1];
+                _index = head;
+                bool _pastItem = false;
+                for(int i = 0; i < size - 1; i++, _index = (_index + 1) % Capacity) {
+                    if(_index == _removeIndex) {
+                        _pastItem = true;
+                    }
+                    if(_pastItem) {
+                        _newBuffer[_index] = buffer[(_index + 1) % Capacity];
+                    }
+                    else {
+                        _newBuffer[_index] = buffer[_index];
+                    }
+                }
+                size--;
+                buffer = _newBuffer;
+                return true;
+            }
+            return false;
+        }
+        #endregion
+
+        #region ICollection Members
+        /// <summary>
+        /// Gets an object that can be used to synchronize access to the
+        /// RingBuffer.
+        /// </summary>
+        public Object SyncRoot { get { return this; } }
+
+        /// <summary>
+        /// Gets a value indicating whether access to the RingBuffer is 
+        /// synchronized (thread safe).
+        /// </summary>
+        public bool IsSynchronized { get { return false; } }
+
+        /// <summary>
+        /// Copies the elements of the RingBuffer to <paramref name="array"/>, 
+        /// starting at a particular Array <paramref name="index"/>.
+        /// </summary>
+        /// <param name="array">The one-dimensional Array that is the 
+        /// destination of the elements copied from RingBuffer. The Array must 
+        /// have zero-based indexing.</param>
+        /// <param name="index">The zero-based index in 
+        /// <paramref name="array"/> at which copying begins.</param>
+        void ICollection.CopyTo(Array array, int index) {
+            CopyTo((T[])array, index);
+        }
+        #endregion
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/RingBuffer.cs.meta

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

+ 15 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/UIElementDragger.cs

@@ -0,0 +1,15 @@
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+namespace Agora.Util
+{
+    public class UIElementDrag : EventTrigger
+    {
+
+        public override void OnDrag(PointerEventData eventData)
+        {
+            transform.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
+            base.OnDrag(eventData);
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/API-Example/Tools/UIElementDragger.cs.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code.meta

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

+ 8 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event.meta

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

+ 49 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/CloudAudioEngineEventHandler.cs

@@ -0,0 +1,49 @@
+namespace Agora.Rtc
+{
+    //public delegate void OnTokenWillExpireHandler();
+  
+    //public delegate void OnConnectionStateChangeHandler(SAE_CONNECTION_STATE_TYPE state, SAE_CONNECTION_CHANGED_REASON_TYPE reason);
+
+    //public delegate void OnTeammateLeftHandler(uint uid);
+
+    //public delegate void OnTeammateJoinedHandler(uint uid);
+
+    //public class CloudSpatialAudioEventHandler : ICloudSpatialAudioEventHandler
+    //{
+    //    public event OnTokenWillExpireHandler EventOnTokenWillExpire;
+    //    public event OnConnectionStateChangeHandler EventOnConnectionStateChange;
+    //    public event OnTeammateLeftHandler EventOnTeammateLeft;
+    //    public event OnTeammateJoinedHandler EventOnTeammateJoined;
+
+    //    private static CloudSpatialAudioEventHandler eventInstance = null;
+
+    //    public static CloudSpatialAudioEventHandler GetInstance()
+    //    {
+    //        return eventInstance ?? (eventInstance = new CloudSpatialAudioEventHandler());
+    //    }
+
+    //    public override void OnTokenWillExpire()
+    //    {
+    //        if (EventOnTokenWillExpire == null) return;
+    //        EventOnTokenWillExpire.Invoke();
+    //    }
+  
+    //    public override void OnConnectionStateChange(SAE_CONNECTION_STATE_TYPE state, SAE_CONNECTION_CHANGED_REASON_TYPE reason)
+    //    {
+    //        if (EventOnConnectionStateChange == null) return;
+    //        EventOnConnectionStateChange.Invoke(state, reason);
+    //    }
+
+    //    public override void OnTeammateLeft(uint uid)
+    //    {
+    //        if (EventOnTeammateLeft == null) return;
+    //        EventOnTeammateLeft.Invoke(uid);
+    //    }
+
+    //    public override void OnTeammateJoined(uint uid)
+    //    {
+    //        if (EventOnTeammateJoined == null) return;
+    //        EventOnTeammateJoined.Invoke(uid);
+    //    }
+    //}
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/CloudAudioEngineEventHandler.cs.meta

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

+ 98 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaPlayerSourceObserver.cs

@@ -0,0 +1,98 @@
+using System;
+
+namespace Agora.Rtc
+{
+    public delegate void OnPlayerSourceStateChangedHandler(MEDIA_PLAYER_STATE state, MEDIA_PLAYER_ERROR ec);
+
+    public delegate void OnPositionChangedHandler(Int64 position_ms);
+
+    public delegate void OnPlayerEventHandler(MEDIA_PLAYER_EVENT eventCode, Int64 elapsedTime, string message);
+
+    public delegate void OnMetaDataHandler(byte[] data, int length);
+
+    public delegate void OnPlayBufferUpdatedHandler(Int64 playCachedBuffer);
+
+    public delegate void OnCompletedHandler();
+
+    public delegate void OnAgoraCDNTokenWillExpireHandler();
+
+    public delegate void OnPlayerSrcInfoChangedHandler(SrcInfo from, SrcInfo to);
+
+    public delegate void OnPlayerInfoUpdatedHandler(PlayerUpdatedInfo info);
+
+    public delegate void MediaPlayerOnAudioVolumeIndicationHandler(int volume);
+    
+    public class MediaPlayerSourceObserver : IMediaPlayerSourceObserver
+    {
+        public event OnPlayerSourceStateChangedHandler EventOnPlayerSourceStateChanged;
+        public event OnPositionChangedHandler EventOnPositionChanged;
+        public event OnPlayerEventHandler EventOnPlayerEvent;
+        public event OnMetaDataHandler EventOnMetaData;
+        public event OnPlayBufferUpdatedHandler EventOnPlayBufferUpdated;
+        public event OnCompletedHandler EventOnCompleted;
+        public event OnAgoraCDNTokenWillExpireHandler EventOnAgoraCDNTokenWillExpire;
+        public event OnPlayerSrcInfoChangedHandler EventOnPlayerSrcInfoChanged;
+        public event OnPlayerInfoUpdatedHandler EventOnPlayerInfoUpdated;
+        public event MediaPlayerOnAudioVolumeIndicationHandler EventOnAudioVolumeIndication;
+
+        public override void OnPlayerSourceStateChanged(MEDIA_PLAYER_STATE state, MEDIA_PLAYER_ERROR ec)
+        {
+            if (EventOnPlayerSourceStateChanged == null) return;
+            EventOnPlayerSourceStateChanged.Invoke(state, ec);
+        }
+
+        public override void OnPositionChanged(Int64 position_ms)
+        {
+            if (EventOnPositionChanged == null) return;
+            EventOnPositionChanged.Invoke(position_ms);
+        }
+
+        public override void OnPlayerEvent(MEDIA_PLAYER_EVENT eventCode, Int64 elapsedTime, string message)
+        {
+            if (EventOnPlayerEvent == null) return;
+            EventOnPlayerEvent.Invoke(eventCode, elapsedTime, message);
+        }
+
+        public override void OnMetaData(byte[] data, int length)
+        {
+            if (EventOnMetaData == null) return;
+            EventOnMetaData.Invoke(data, length);
+        }
+
+        public override void OnPlayBufferUpdated(Int64 playCachedBuffer)
+        {
+            if (EventOnPlayBufferUpdated == null) return;
+            EventOnPlayBufferUpdated.Invoke(playCachedBuffer);
+        }
+
+        public override void OnCompleted()
+        {
+            if (EventOnCompleted == null) return;
+            EventOnCompleted.Invoke();
+        }
+
+        public override void OnAgoraCDNTokenWillExpire()
+        {
+            if (EventOnAgoraCDNTokenWillExpire == null) return;
+            EventOnAgoraCDNTokenWillExpire.Invoke();
+        }
+
+        public override void OnPlayerSrcInfoChanged(SrcInfo from, SrcInfo to)
+        {
+            if (EventOnPlayerSrcInfoChanged == null) return;
+            EventOnPlayerSrcInfoChanged.Invoke(from, to);
+        }
+
+        public override void OnPlayerInfoUpdated(PlayerUpdatedInfo info)
+        {
+            if (EventOnPlayerInfoUpdated == null) return;
+            EventOnPlayerInfoUpdated.Invoke(info);
+        }
+
+        public override void OnAudioVolumeIndication(int volume)
+        {
+            if (EventOnAudioVolumeIndication == null) return;
+            EventOnAudioVolumeIndication.Invoke(volume);
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaPlayerSourceObserver.cs.meta

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

+ 32 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaRecorderObserver.cs

@@ -0,0 +1,32 @@
+namespace Agora.Rtc
+{
+    public delegate void OnRecorderStateChangedHandler(RecorderState state, RecorderErrorCode error);
+
+    public delegate void OnRecorderInfoUpdatedHandler(RecorderInfo info);
+    
+    public class MediaRecorderObserver : IMediaRecorderObserver
+    {
+        public event OnRecorderStateChangedHandler EventOnRecorderStateChanged;
+
+        public event OnRecorderInfoUpdatedHandler EventOnRecorderInfoUpdated;
+
+        private static MediaRecorderObserver eventInstance = null;
+
+        public static MediaRecorderObserver GetInstance()
+        {
+            return eventInstance ?? (eventInstance = new MediaRecorderObserver());
+        }
+
+        public override void OnRecorderStateChanged(RecorderState state, RecorderErrorCode error)
+        {
+            if (EventOnRecorderStateChanged == null) return;
+            EventOnRecorderStateChanged.Invoke(state, error);
+        }
+
+        public override void OnRecorderInfoUpdated(RecorderInfo info)
+        {
+            if (EventOnRecorderInfoUpdated == null) return;
+            EventOnRecorderInfoUpdated.Invoke(info);
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/MediaRecorderObserver.cs.meta

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

+ 905 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/RtcEngineEventHandler.cs

@@ -0,0 +1,905 @@
+using System;
+
+namespace Agora.Rtc
+{
+    public delegate void OnJoinChannelSuccessHandler(RtcConnection connection, int elapsed);
+
+    public delegate void OnErrorHandler(int err, string msg);
+
+    public delegate void OnLeaveChannelHandler(RtcConnection connection, RtcStats stats);
+
+    public delegate void OnRejoinChannelSuccessHandler(RtcConnection connection, int elapsed);
+
+    public delegate void OnProxyConnectedHandler(string channel, uint uid, PROXY_TYPE proxyType, string localProxyIp, int elapsed);
+
+    public delegate void OnAudioQualityHandler(RtcConnection connection, uint remoteUid, int quality, UInt16 delay, UInt16 lost);
+
+    public delegate void OnLastmileProbeResultHandler(LastmileProbeResult result);
+
+    public delegate void OnAudioVolumeIndicationHandler(RtcConnection connection, AudioVolumeInfo[] speakers, uint speakerNumber, int totalVolume);
+
+    public delegate void OnRtcStatsHandler(RtcConnection connection, RtcStats stats);
+
+    public delegate void OnAudioDeviceStateChangedHandler(string deviceId, MEDIA_DEVICE_TYPE deviceType, MEDIA_DEVICE_STATE_TYPE deviceState);
+
+    public delegate void OnAudioMixingFinishedHandler();
+
+    public delegate void OnAudioEffectFinishedHandler(int soundId);
+
+    public delegate void OnVideoDeviceStateChangedHandler(string deviceId, MEDIA_DEVICE_TYPE deviceType, MEDIA_DEVICE_STATE_TYPE deviceState);
+
+    public delegate void OnMediaDeviceChangedHandler(MEDIA_DEVICE_TYPE deviceType);
+
+    public delegate void OnNetworkQualityHandler(RtcConnection connection, uint remoteUid, int txQuality, int rxQuality);
+
+    public delegate void OnIntraRequestReceivedHandler(RtcConnection connection);
+
+    public delegate void OnUplinkNetworkInfoUpdatedHandler(UplinkNetworkInfo info);
+
+    public delegate void OnDownlinkNetworkInfoUpdatedHandler(DownlinkNetworkInfo info);
+
+    public delegate void OnLastmileQualityHandler(int quality);
+
+    public delegate void OnFirstLocalVideoFrameHandler(RtcConnection connection, int width, int height, int elapsed);
+
+    public delegate void OnFirstLocalVideoFramePublishedHandler(RtcConnection connection, int elapsed);
+
+    public delegate void OnVideoSourceFrameSizeChangedHandler(RtcConnection connection, VIDEO_SOURCE_TYPE sourceType, int width, int height);
+
+    public delegate void OnFirstRemoteVideoDecodedHandler(RtcConnection connection, uint remoteUid, int width, int height, int elapsed);
+
+    public delegate void OnVideoSizeChangedHandler(RtcConnection connection, VIDEO_SOURCE_TYPE sourceType, uint uid, int width, int height, int rotation);
+
+    public delegate void OnContentInspectResultHandler(CONTENT_INSPECT_RESULT result);
+
+    public delegate void OnSnapshotTakenHandlerEx(RtcConnection connection, uint uid, string filePath, int width, int height, int errCode);
+
+    public delegate void OnLocalVideoStateChangedHandler(VIDEO_SOURCE_TYPE source, LOCAL_VIDEO_STREAM_STATE state, LOCAL_VIDEO_STREAM_ERROR errorCode);
+
+    public delegate void OnLocalVideoStateChangedHandlerEx(RtcConnection connection, LOCAL_VIDEO_STREAM_STATE state, LOCAL_VIDEO_STREAM_ERROR errorCode);
+
+    public delegate void OnRemoteVideoStateChangedHandler(RtcConnection connection, uint remoteUid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason, int elapsed);
+
+    public delegate void OnFirstRemoteVideoFrameHandler(RtcConnection connection, uint remoteUid, int width, int height, int elapsed);
+
+    public delegate void OnUserJoinedHandler(RtcConnection connection, uint remoteUid, int elapsed);
+
+    public delegate void OnUserOfflineHandler(RtcConnection connection, uint remoteUid, USER_OFFLINE_REASON_TYPE reason);
+
+    public delegate void OnUserMuteAudioHandler(RtcConnection connection, uint remoteUid, bool muted);
+
+    public delegate void OnUserMuteVideoHandler(RtcConnection connection, uint remoteUid, bool muted);
+
+    public delegate void OnUserEnableVideoHandler(RtcConnection connection, uint remoteUid, bool enabled);
+
+    public delegate void OnUserEnableLocalVideoHandler(RtcConnection connection, uint remoteUid, bool enabled);
+
+    public delegate void OnUserStateChangedHandler(RtcConnection connection, uint remoteUid, uint state);
+
+    public delegate void OnApiCallExecutedHandler(int err, string api, string result);
+
+    public delegate void OnLocalAudioStatsHandler(RtcConnection connection, LocalAudioStats stats);
+
+    public delegate void OnRemoteAudioStatsHandler(RtcConnection connection, RemoteAudioStats stats);
+
+    public delegate void OnLocalVideoStatsHandler(RtcConnection connection, LocalVideoStats stats);
+
+    public delegate void OnRemoteVideoStatsHandler(RtcConnection connection, RemoteVideoStats stats);
+
+    public delegate void OnCameraReadyHandler();
+
+    public delegate void OnCameraFocusAreaChangedHandler(int x, int y, int width, int height);
+
+    public delegate void OnCameraExposureAreaChangedHandler(int x, int y, int width, int height);
+
+    public delegate void OnFacePositionChangedHandler(int imageWidth, int imageHeight, Rectangle vecRectangle, int[] vecDistance, int numFaces);
+
+    public delegate void OnVideoStoppedHandler();
+
+    public delegate void OnAudioMixingStateChangedHandler(AUDIO_MIXING_STATE_TYPE state, AUDIO_MIXING_REASON_TYPE reason);
+
+    public delegate void OnRhythmPlayerStateChangedHandler(RHYTHM_PLAYER_STATE_TYPE state, RHYTHM_PLAYER_ERROR_TYPE errorCode);
+
+    public delegate void OnConnectionLostHandler(RtcConnection connection);
+
+    public delegate void OnConnectionInterruptedHandler(RtcConnection connection);
+
+    public delegate void OnConnectionBannedHandler(RtcConnection connection);
+
+    public delegate void OnStreamMessageHandler(RtcConnection connection, uint remoteUid, int streamId, byte[] data, uint length, UInt64 sentTs);
+
+    public delegate void OnStreamMessageErrorHandler(RtcConnection connection, uint remoteUid, int streamId, int code, int missed, int cached);
+
+    public delegate void OnRequestTokenHandler(RtcConnection connection);
+
+    public delegate void OnTokenPrivilegeWillExpireHandler(RtcConnection connection, string token);
+
+    public delegate void OnFirstLocalAudioFramePublishedHandler(RtcConnection connection, int elapsed);
+
+    public delegate void OnFirstRemoteAudioFrameHandler(RtcConnection connection, uint userId, int elapsed);
+
+    public delegate void OnFirstRemoteAudioDecodedHandler(RtcConnection connection, uint uid, int elapsed);
+
+    public delegate void OnLocalAudioStateChangedHandler(RtcConnection connection, LOCAL_AUDIO_STREAM_STATE state, LOCAL_AUDIO_STREAM_ERROR error);
+
+    public delegate void OnRemoteAudioStateChangedHandler(RtcConnection connection, uint remoteUid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason, int elapsed);
+
+    public delegate void OnActiveSpeakerHandler(RtcConnection connection, uint uid);
+
+    public delegate void OnClientRoleChangedHandler(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole);
+
+    public delegate void OnClientRoleChangeFailedHandler(RtcConnection connection, CLIENT_ROLE_CHANGE_FAILED_REASON reason, CLIENT_ROLE_TYPE currentRole);
+
+    public delegate void OnAudioDeviceVolumeChangedHandler(MEDIA_DEVICE_TYPE deviceType, int volume, bool muted);
+
+    public delegate void OnRtmpStreamingStateChangedHandler(string url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR_TYPE errCode);
+
+    public delegate void OnRtmpStreamingEventHandler(string url, RTMP_STREAMING_EVENT eventCode);
+
+    //public delegate void OnStreamPublishedHandler(string url, int error);
+
+    //public delegate void OnStreamUnpublishedHandler(string url);
+
+    public delegate void OnTranscodingUpdatedHandler();
+
+    public delegate void OnAudioRoutingChangedHandler(int routing);
+
+    public delegate void OnChannelMediaRelayStateChangedHandler(int state, int code);
+
+    public delegate void OnChannelMediaRelayEventHandler(int code);
+
+    public delegate void OnLocalPublishFallbackToAudioOnlyHandler(bool isFallbackOrRecover);
+
+    public delegate void OnRemoteSubscribeFallbackToAudioOnlyHandler(uint uid, bool isFallbackOrRecover);
+
+    public delegate void OnRemoteAudioTransportStatsHandler(RtcConnection connection, uint remoteUid, UInt16 delay, UInt16 lost, UInt16 rxKBitRate);
+
+    public delegate void OnRemoteVideoTransportStatsHandler(RtcConnection connection, uint remoteUid, UInt16 delay, UInt16 lost, UInt16 rxKBitRate);
+
+    public delegate void OnConnectionStateChangedHandler(RtcConnection connection, CONNECTION_STATE_TYPE state, CONNECTION_CHANGED_REASON_TYPE reason);
+
+    public delegate void OnWlAccMessageHandler(RtcConnection connection, WLACC_MESSAGE_REASON reason, WLACC_SUGGEST_ACTION action, string wlAccMsg);
+
+    public delegate void OnWlAccStatsHandler(RtcConnection connection, WlAccStats currentStats, WlAccStats averageStats);
+
+    public delegate void OnNetworkTypeChangedHandler(RtcConnection connection, NETWORK_TYPE type);
+
+    public delegate void OnEncryptionErrorHandler(RtcConnection connection, ENCRYPTION_ERROR_TYPE errorType);
+
+    public delegate void OnUploadLogResultHandler(RtcConnection connection, string requestId, bool success, UPLOAD_ERROR_REASON reason);
+
+    public delegate void OnUserAccountUpdatedHandler(RtcConnection connection, uint remoteUid, string userAccount);
+
+    public delegate void OnPermissionErrorHandler(PERMISSION_TYPE permissionType);
+
+    public delegate void OnLocalUserRegisteredHandler(uint uid, string userAccount);
+
+    public delegate void OnUserInfoUpdatedHandler(uint uid, UserInfo info);
+
+    public delegate void OnAudioSubscribeStateChangedHandler(string channel, uint uid, STREAM_SUBSCRIBE_STATE oldState, STREAM_SUBSCRIBE_STATE newState, int elapseSinceLastState);
+
+    public delegate void OnVideoSubscribeStateChangedHandler(string channel, uint uid, STREAM_SUBSCRIBE_STATE oldState, STREAM_SUBSCRIBE_STATE newState, int elapseSinceLastState);
+
+    public delegate void OnAudioPublishStateChangedHandler(string channel, STREAM_PUBLISH_STATE oldState, STREAM_PUBLISH_STATE newState, int elapseSinceLastState);
+
+    public delegate void OnVideoPublishStateChangedHandler(VIDEO_SOURCE_TYPE source, string channel, STREAM_PUBLISH_STATE oldState, STREAM_PUBLISH_STATE newState, int elapseSinceLastState);
+
+    public delegate void OnExtensionEventHandler(string provider, string extension, string key, string value);
+
+    public delegate void OnExtensionStartedHandler(string provider, string extension);
+
+    public delegate void OnExtensionStoppedHandler(string provider, string extension);
+
+    public delegate void OnExtensionErrorHandler(string provider, string extension, int error, string message);
+
+    public delegate void OnDirectCdnStreamingStateChangedHandler(DIRECT_CDN_STREAMING_STATE state, DIRECT_CDN_STREAMING_ERROR error, string message);
+
+    public delegate void OnDirectCdnStreamingStatsHandler(DirectCdnStreamingStats stats);
+
+    public class RtcEngineEventHandler : IRtcEngineEventHandler
+    {
+        public event OnJoinChannelSuccessHandler EventOnJoinChannelSuccess;
+        public event OnLeaveChannelHandler EventOnLeaveChannel;
+        public event OnErrorHandler EventOnError;
+        public event OnRejoinChannelSuccessHandler EventOnRejoinChannelSuccess;
+        public event OnProxyConnectedHandler EventOnProxyConnected;
+        public event OnAudioQualityHandler EventOnAudioQuality;
+        public event OnLastmileProbeResultHandler EventOnLastmileProbeResult;
+        public event OnAudioVolumeIndicationHandler EventOnAudioVolumeIndication;
+        public event OnRtcStatsHandler EventOnRtcStats;
+        public event OnAudioDeviceStateChangedHandler EventOnAudioDeviceStateChanged;
+        public event OnAudioMixingFinishedHandler EventOnAudioMixingFinished;
+        public event OnAudioEffectFinishedHandler EventOnAudioEffectFinished;
+        public event OnVideoDeviceStateChangedHandler EventOnVideoDeviceStateChanged;
+        public event OnMediaDeviceChangedHandler EventOnMediaDeviceChanged;
+        public event OnNetworkQualityHandler EventOnNetworkQuality;
+        public event OnIntraRequestReceivedHandler EventOnIntraRequestReceived;
+        public event OnUplinkNetworkInfoUpdatedHandler EventOnUplinkNetworkInfoUpdated;
+        public event OnDownlinkNetworkInfoUpdatedHandler EventOnDownlinkNetworkInfoUpdated;
+        public event OnLastmileQualityHandler EventOnLastmileQuality;
+        public event OnFirstLocalVideoFrameHandler EventOnFirstLocalVideoFrame;
+        public event OnFirstLocalVideoFramePublishedHandler EventOnFirstLocalVideoFramePublished;
+        public event OnVideoSourceFrameSizeChangedHandler EventOnVideoSourceFrameSizeChanged;
+        public event OnFirstRemoteVideoDecodedHandler EventOnFirstRemoteVideoDecoded;
+        public event OnVideoSizeChangedHandler EventOnVideoSizeChanged;
+        public event OnContentInspectResultHandler EventOnContentInspectResult;
+        public event OnSnapshotTakenHandlerEx EventOnSnapshotTakenEx;
+        public event OnLocalVideoStateChangedHandler EventOnLocalVideoStateChanged;
+        public event OnLocalVideoStateChangedHandlerEx EventOnLocalVideoStateChangedEx;
+        public event OnRemoteVideoStateChangedHandler EventOnRemoteVideoStateChanged;
+        public event OnFirstRemoteVideoFrameHandler EventOnFirstRemoteVideoFrame;
+        public event OnUserJoinedHandler EventOnUserJoined;
+        public event OnUserOfflineHandler EventOnUserOffline;
+        public event OnUserMuteAudioHandler EventOnUserMuteAudio;
+        public event OnUserMuteVideoHandler EventOnUserMuteVideo;
+        public event OnUserEnableVideoHandler EventOnUserEnableVideo;
+        public event OnUserEnableLocalVideoHandler EventOnUserEnableLocalVideo;
+        public event OnUserStateChangedHandler EventOnUserStateChanged;
+        public event OnApiCallExecutedHandler EventOnApiCallExecuted;
+        public event OnLocalAudioStatsHandler EventOnLocalAudioStats;
+        public event OnRemoteAudioStatsHandler EventOnRemoteAudioStats;
+        public event OnLocalVideoStatsHandler EventOnLocalVideoStats;
+        public event OnRemoteVideoStatsHandler EventOnRemoteVideoStats;
+        public event OnCameraReadyHandler EventOnCameraReady;
+        public event OnCameraFocusAreaChangedHandler EventOnCameraFocusAreaChanged;
+        public event OnCameraExposureAreaChangedHandler EventOnCameraExposureAreaChanged;
+        public event OnFacePositionChangedHandler EventOnFacePositionChanged;
+        public event OnVideoStoppedHandler EventOnVideoStopped;
+        public event OnAudioMixingStateChangedHandler EventOnAudioMixingStateChanged;
+        public event OnRhythmPlayerStateChangedHandler EventOnRhythmPlayerStateChanged;
+        public event OnConnectionLostHandler EventOnConnectionLost;
+        public event OnConnectionInterruptedHandler EventOnConnectionInterrupted;
+        public event OnConnectionBannedHandler EventOnConnectionBanned;
+        public event OnStreamMessageHandler EventOnStreamMessage;
+        public event OnStreamMessageErrorHandler EventOnStreamMessageError;
+        public event OnRequestTokenHandler EventOnRequestToken;
+        public event OnTokenPrivilegeWillExpireHandler EventOnTokenPrivilegeWillExpire;
+        public event OnFirstLocalAudioFramePublishedHandler EventOnFirstLocalAudioFramePublished;
+        public event OnFirstRemoteAudioFrameHandler EventOnFirstRemoteAudioFrame;
+        public event OnFirstRemoteAudioDecodedHandler EventOnFirstRemoteAudioDecoded;
+        public event OnLocalAudioStateChangedHandler EventOnLocalAudioStateChanged;
+        public event OnRemoteAudioStateChangedHandler EventOnRemoteAudioStateChanged;
+        public event OnActiveSpeakerHandler EventOnActiveSpeaker;
+        public event OnClientRoleChangedHandler EventOnClientRoleChanged;
+        public event OnClientRoleChangeFailedHandler EventOnClientRoleChangeFailed;
+        public event OnAudioDeviceVolumeChangedHandler EventOnAudioDeviceVolumeChanged;
+        public event OnRtmpStreamingStateChangedHandler EventOnRtmpStreamingStateChanged;
+        public event OnRtmpStreamingEventHandler EventOnRtmpStreamingEvent;
+        //public event OnStreamPublishedHandler EventOnStreamPublished;
+        //public event OnStreamUnpublishedHandler EventOnStreamUnpublished;
+        public event OnTranscodingUpdatedHandler EventOnTranscodingUpdated;
+        public event OnAudioRoutingChangedHandler EventOnAudioRoutingChanged;
+        public event OnChannelMediaRelayStateChangedHandler EventOnChannelMediaRelayStateChanged;
+        public event OnChannelMediaRelayEventHandler EventOnChannelMediaRelayEvent;
+        public event OnLocalPublishFallbackToAudioOnlyHandler EventOnLocalPublishFallbackToAudioOnly;
+        public event OnRemoteSubscribeFallbackToAudioOnlyHandler EventOnRemoteSubscribeFallbackToAudioOnly;
+        public event OnRemoteAudioTransportStatsHandler EventOnRemoteAudioTransportStats;
+        public event OnRemoteVideoTransportStatsHandler EventOnRemoteVideoTransportStats;
+        public event OnConnectionStateChangedHandler EventOnConnectionStateChanged;
+        public event OnWlAccMessageHandler EventOnWlAccMessage;
+        public event OnWlAccStatsHandler EventOnWlAccStats;
+        public event OnNetworkTypeChangedHandler EventOnNetworkTypeChanged;
+        public event OnEncryptionErrorHandler EventOnEncryptionError;
+        public event OnUploadLogResultHandler EventOnUploadLogResult;
+        public event OnUserAccountUpdatedHandler EventOnUserAccountUpdated;
+        public event OnPermissionErrorHandler EventOnPermissionError;
+        public event OnLocalUserRegisteredHandler EventOnLocalUserRegistered;
+        public event OnUserInfoUpdatedHandler EventOnUserInfoUpdated;
+        public event OnAudioSubscribeStateChangedHandler EventOnAudioSubscribeStateChanged;
+        public event OnVideoSubscribeStateChangedHandler EventOnVideoSubscribeStateChanged;
+        public event OnAudioPublishStateChangedHandler EventOnAudioPublishStateChanged;
+        public event OnVideoPublishStateChangedHandler EventOnVideoPublishStateChanged;
+        public event OnExtensionEventHandler EventOnExtensionEvent;
+        public event OnExtensionStartedHandler EventOnExtensionStarted;
+        public event OnExtensionStoppedHandler EventOnExtensionStopped;
+        public event OnExtensionErrorHandler EventOnExtensionErrored;
+        public event OnDirectCdnStreamingStateChangedHandler EventOnDirectCdnStreamingStateChanged;
+        public event OnDirectCdnStreamingStatsHandler EventOnDirectCdnStreamingStats;
+
+        private static RtcEngineEventHandler eventInstance = null;
+
+        public static RtcEngineEventHandler GetInstance()
+        {
+            if (eventInstance == null)
+            {
+                eventInstance = new RtcEngineEventHandler();
+            }
+
+            return eventInstance;
+        }
+
+        public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
+        {
+            if (EventOnJoinChannelSuccess == null) return;
+            EventOnJoinChannelSuccess.Invoke(connection, elapsed);
+        }
+
+        public override void OnError(int err, string msg)
+        {
+            if (EventOnError == null) return;
+            EventOnError.Invoke(err, msg);
+        }
+
+        public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
+        {
+            if (EventOnLeaveChannel == null) return;
+            EventOnLeaveChannel.Invoke(connection, stats);
+        }
+
+        public override void OnRejoinChannelSuccess(RtcConnection connection, int elapsed)
+        {
+            if (EventOnRejoinChannelSuccess == null) return;
+            EventOnRejoinChannelSuccess.Invoke(connection, elapsed);
+        }
+
+        public override void OnProxyConnected(string channel, uint uid, PROXY_TYPE proxyType, string localProxyIp, int elapsed)
+        {
+            if (EventOnProxyConnected == null) return;
+            EventOnProxyConnected.Invoke(channel, uid, proxyType, localProxyIp, elapsed);
+        }
+
+        public override void OnAudioQuality(RtcConnection connection, uint remoteUid, int quality, UInt16 delay, UInt16 lost)
+        {
+            if (EventOnAudioQuality == null) return;
+            EventOnAudioQuality.Invoke(connection, remoteUid, quality, delay, lost);
+        }
+
+        public override void OnLastmileProbeResult(LastmileProbeResult result)
+        {
+            if (EventOnLastmileProbeResult == null) return;
+            EventOnLastmileProbeResult.Invoke(result);
+        }
+
+        public override void OnAudioVolumeIndication(RtcConnection connection, AudioVolumeInfo[] speakers, uint speakerNumber, int totalVolume)
+        {
+            if (EventOnAudioVolumeIndication == null) return;
+            EventOnAudioVolumeIndication.Invoke(connection, speakers, speakerNumber, totalVolume);
+        }
+
+        public override void OnRtcStats(RtcConnection connection, RtcStats stats)
+        {
+            if (EventOnRtcStats == null) return;
+            EventOnRtcStats.Invoke(connection, stats);
+        }
+
+        public override void OnAudioDeviceStateChanged(string deviceId, MEDIA_DEVICE_TYPE deviceType, MEDIA_DEVICE_STATE_TYPE deviceState)
+        {
+            if (EventOnAudioDeviceStateChanged == null) return;
+            EventOnAudioDeviceStateChanged.Invoke(deviceId, deviceType, deviceState);
+        }
+
+        [Obsolete]
+        public override void OnAudioMixingFinished()
+        {
+            if (EventOnAudioMixingFinished == null) return;
+            EventOnAudioMixingFinished.Invoke();
+        }
+
+        public override void OnAudioEffectFinished(int soundId)
+        {
+            if (EventOnAudioEffectFinished == null) return;
+            EventOnAudioEffectFinished.Invoke(soundId);
+        }
+
+        public override void OnVideoDeviceStateChanged(string deviceId, MEDIA_DEVICE_TYPE deviceType, MEDIA_DEVICE_STATE_TYPE deviceState)
+        {
+            if (EventOnVideoDeviceStateChanged == null) return;
+            EventOnVideoDeviceStateChanged.Invoke(deviceId, deviceType, deviceState);
+        }
+
+        public override void OnMediaDeviceChanged(MEDIA_DEVICE_TYPE deviceType)
+        {
+            if (EventOnMediaDeviceChanged == null) return;
+            EventOnMediaDeviceChanged.Invoke(deviceType);
+        }
+
+        public override void OnNetworkQuality(RtcConnection connection, uint remoteUid, int txQuality, int rxQuality)
+        {
+            if (EventOnNetworkQuality == null) return;
+            EventOnNetworkQuality.Invoke(connection, remoteUid, txQuality, rxQuality);
+        }
+
+        public override void OnIntraRequestReceived(RtcConnection connection)
+        {
+            if (EventOnIntraRequestReceived == null) return;
+            EventOnIntraRequestReceived.Invoke(connection);
+        }
+
+        public override void OnUplinkNetworkInfoUpdated(UplinkNetworkInfo info)
+        {
+            if (EventOnUplinkNetworkInfoUpdated == null) return;
+            EventOnUplinkNetworkInfoUpdated.Invoke(info);
+        }
+
+        public override void OnDownlinkNetworkInfoUpdated(DownlinkNetworkInfo info)
+        {
+            if (EventOnDownlinkNetworkInfoUpdated == null) return;
+            EventOnDownlinkNetworkInfoUpdated.Invoke(info);
+        }
+
+        public override void OnLastmileQuality(int quality)
+        {
+            if (EventOnLastmileQuality == null) return;
+            EventOnLastmileQuality.Invoke(quality);
+        }
+
+        public override void OnFirstLocalVideoFrame(RtcConnection connection, int width, int height, int elapsed)
+        {
+            if (EventOnFirstLocalVideoFrame == null) return;
+            EventOnFirstLocalVideoFrame.Invoke(connection, width, height, elapsed);
+        }
+
+        public override void OnFirstLocalVideoFramePublished(RtcConnection connection, int elapsed)
+        {
+            if (EventOnFirstLocalVideoFramePublished == null) return;
+            EventOnFirstLocalVideoFramePublished.Invoke(connection, elapsed);
+        }
+
+        public override void OnVideoSourceFrameSizeChanged(RtcConnection connection, VIDEO_SOURCE_TYPE sourceType, int width, int height)
+        {
+            if (EventOnVideoSourceFrameSizeChanged == null) return;
+            EventOnVideoSourceFrameSizeChanged.Invoke(connection, sourceType, width, height);
+        }
+
+        public override void OnFirstRemoteVideoDecoded(RtcConnection connection, uint remoteUid, int width, int height, int elapsed)
+        {
+            if (EventOnFirstRemoteVideoDecoded == null) return;
+            EventOnFirstRemoteVideoDecoded.Invoke(connection, remoteUid, width, height, elapsed);
+        }
+
+        public override void OnVideoSizeChanged(RtcConnection connection, VIDEO_SOURCE_TYPE sourceType, uint uid, int width, int height, int rotation)
+        {
+            if (EventOnVideoSizeChanged == null) return;
+            EventOnVideoSizeChanged.Invoke(connection, sourceType, uid, width, height, rotation);
+        }
+
+        public override void OnContentInspectResult(CONTENT_INSPECT_RESULT result)
+        {
+            if (EventOnContentInspectResult == null) return;
+            EventOnContentInspectResult.Invoke(result);
+        }
+
+        public override void OnSnapshotTaken(RtcConnection connection, uint uid, string filePath, int width, int height, int errCode)
+        {
+            if (EventOnSnapshotTakenEx == null) return;
+            EventOnSnapshotTakenEx.Invoke(connection, uid, filePath, width, height, errCode);
+        }
+
+        public override void OnLocalVideoStateChanged(VIDEO_SOURCE_TYPE source, LOCAL_VIDEO_STREAM_STATE state, LOCAL_VIDEO_STREAM_ERROR errorCode)
+        {
+            if (EventOnLocalVideoStateChanged == null) return;
+            EventOnLocalVideoStateChanged.Invoke(source, state, errorCode);
+        }
+
+        public override void OnLocalVideoStateChanged(RtcConnection connection, LOCAL_VIDEO_STREAM_STATE state, LOCAL_VIDEO_STREAM_ERROR errorCode)
+        {
+            if (EventOnLocalVideoStateChangedEx == null) return;
+            EventOnLocalVideoStateChangedEx.Invoke(connection, state, errorCode);
+        }
+
+        public override void OnRemoteVideoStateChanged(RtcConnection connection, uint remoteUid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason, int elapsed)
+        {
+            if (EventOnRemoteVideoStateChanged == null) return;
+            EventOnRemoteVideoStateChanged.Invoke(connection, remoteUid, state, reason, elapsed);
+        }
+
+        public override void OnFirstRemoteVideoFrame(RtcConnection connection, uint remoteUid, int width, int height, int elapsed)
+        {
+            if (EventOnFirstRemoteVideoFrame == null) return;
+            EventOnFirstRemoteVideoFrame.Invoke(connection, remoteUid, width, height, elapsed);
+        }
+
+        public override void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed)
+        {
+            if (EventOnUserJoined == null) return;
+            EventOnUserJoined.Invoke(connection, remoteUid, elapsed);
+        }
+
+        public override void OnUserOffline(RtcConnection connection, uint remoteUid, USER_OFFLINE_REASON_TYPE reason)
+        {
+            if (EventOnUserOffline == null) return;
+            EventOnUserOffline.Invoke(connection, remoteUid, reason);
+        }
+
+        [Obsolete]
+        public override void OnUserMuteAudio(RtcConnection connection, uint remoteUid, bool muted)
+        {
+            if (EventOnUserMuteAudio == null) return;
+            EventOnUserMuteAudio.Invoke(connection, remoteUid, muted);
+        }
+
+        [Obsolete]
+        public override void OnUserMuteVideo(RtcConnection connection, uint remoteUid, bool muted)
+        {
+            if (EventOnUserMuteVideo == null) return;
+            EventOnUserMuteVideo.Invoke(connection, remoteUid, muted);
+        }
+
+        [Obsolete]
+        public override void OnUserEnableVideo(RtcConnection connection, uint remoteUid, bool enabled)
+        {
+            if (EventOnUserEnableVideo == null) return;
+            EventOnUserEnableVideo.Invoke(connection, remoteUid, enabled);
+        }
+
+        [Obsolete]
+        public override void OnUserEnableLocalVideo(RtcConnection connection, uint remoteUid, bool enabled)
+        {
+            if (EventOnUserEnableLocalVideo == null) return;
+            EventOnUserEnableLocalVideo.Invoke(connection, remoteUid, enabled);
+        }
+
+        public override void OnUserStateChanged(RtcConnection connection, uint remoteUid, uint state)
+        {
+            if (EventOnUserStateChanged == null) return;
+            EventOnUserStateChanged.Invoke(connection, remoteUid, state);
+        }
+
+        public override void OnApiCallExecuted(int err, string api, string result)
+        {
+            if (EventOnApiCallExecuted == null) return;
+            EventOnApiCallExecuted.Invoke(err, api, result);
+        }
+
+        public override void OnLocalAudioStats(RtcConnection connection, LocalAudioStats stats)
+        {
+            if (EventOnLocalAudioStats == null) return;
+            EventOnLocalAudioStats.Invoke(connection, stats);
+        }
+
+        public override void OnRemoteAudioStats(RtcConnection connection, RemoteAudioStats stats)
+        {
+            if (EventOnRemoteAudioStats == null) return;
+            EventOnRemoteAudioStats.Invoke(connection, stats);
+        }
+
+        public override void OnLocalVideoStats(RtcConnection connection, LocalVideoStats stats)
+        {
+            if (EventOnLocalVideoStats == null) return;
+            EventOnLocalVideoStats.Invoke(connection, stats);
+        }
+
+        public override void OnRemoteVideoStats(RtcConnection connection, RemoteVideoStats stats)
+        {
+            if (EventOnRemoteVideoStats == null) return;
+            EventOnRemoteVideoStats.Invoke(connection, stats);
+        }
+
+        public override void OnCameraReady()
+        {
+            if (EventOnCameraReady == null) return;
+            EventOnCameraReady.Invoke();
+        }
+
+        public override void OnCameraFocusAreaChanged(int x, int y, int width, int height)
+        {
+            if (EventOnCameraFocusAreaChanged == null) return;
+            EventOnCameraFocusAreaChanged.Invoke(x, y, width, height);
+        }
+
+        public override void OnCameraExposureAreaChanged(int x, int y, int width, int height)
+        {
+            if (EventOnCameraExposureAreaChanged == null) return;
+            EventOnCameraExposureAreaChanged.Invoke(x, y, width, height);
+        }
+
+        public override void OnFacePositionChanged(int imageWidth, int imageHeight, Rectangle vecRectangle, int[] vecDistance, int numFaces)
+        {
+            if (EventOnFacePositionChanged == null) return;
+            EventOnFacePositionChanged.Invoke(imageWidth, imageHeight, vecRectangle, vecDistance, numFaces);
+        }
+
+        public override void OnVideoStopped()
+        {
+            if (EventOnVideoStopped == null) return;
+            EventOnVideoStopped.Invoke();
+        }
+
+        public override void OnAudioMixingStateChanged(AUDIO_MIXING_STATE_TYPE state, AUDIO_MIXING_REASON_TYPE reason)
+        {
+            if (EventOnAudioMixingStateChanged == null) return;
+            EventOnAudioMixingStateChanged.Invoke(state, reason);
+        }
+
+        public override void OnRhythmPlayerStateChanged(RHYTHM_PLAYER_STATE_TYPE state, RHYTHM_PLAYER_ERROR_TYPE errorCode)
+        {
+            if (EventOnRhythmPlayerStateChanged == null) return;
+            EventOnRhythmPlayerStateChanged.Invoke(state, errorCode);
+        }
+
+        public override void OnConnectionLost(RtcConnection connection)
+        {
+            if (EventOnConnectionLost == null) return;
+            EventOnConnectionLost.Invoke(connection);
+        }
+
+        public override void OnConnectionInterrupted(RtcConnection connection)
+        {
+            if (EventOnConnectionInterrupted == null) return;
+            EventOnConnectionInterrupted.Invoke(connection);
+        }
+
+        public override void OnConnectionBanned(RtcConnection connection)
+        {
+            if (EventOnConnectionBanned == null) return;
+            EventOnConnectionBanned.Invoke(connection);
+        }
+
+        public override void OnStreamMessage(RtcConnection connection, uint remoteUid, int streamId, byte[] data, uint length, UInt64 sentTs)
+        {
+            if (EventOnStreamMessage == null) return;
+            EventOnStreamMessage.Invoke(connection, remoteUid, streamId, data, length, sentTs);
+        }
+
+        public override void OnStreamMessageError(RtcConnection connection, uint remoteUid, int streamId, int code, int missed, int cached)
+        {
+            if (EventOnStreamMessageError == null) return;
+            EventOnStreamMessageError.Invoke(connection, remoteUid, streamId, code, missed, cached);
+        }
+
+        public override void OnRequestToken(RtcConnection connection)
+        {
+            if (EventOnRequestToken == null) return;
+            EventOnRequestToken.Invoke(connection);
+        }
+
+        public override void OnTokenPrivilegeWillExpire(RtcConnection connection, string token)
+        {
+            if (EventOnTokenPrivilegeWillExpire == null) return;
+            EventOnTokenPrivilegeWillExpire.Invoke(connection, token);
+        }
+
+        public override void OnFirstLocalAudioFramePublished(RtcConnection connection, int elapsed)
+        {
+            if (EventOnFirstLocalAudioFramePublished == null) return;
+            EventOnFirstLocalAudioFramePublished.Invoke(connection, elapsed);
+        }
+
+        public override void OnFirstRemoteAudioFrame(RtcConnection connection, uint userId, int elapsed)
+        {
+            if (EventOnFirstRemoteAudioFrame == null) return;
+            EventOnFirstRemoteAudioFrame.Invoke(connection, userId, elapsed);
+        }
+
+        public override void OnFirstRemoteAudioDecoded(RtcConnection connection, uint uid, int elapsed)
+        {
+            if (EventOnFirstRemoteAudioDecoded == null) return;
+            EventOnFirstRemoteAudioDecoded.Invoke(connection, uid, elapsed);
+        }
+
+        public override void OnLocalAudioStateChanged(RtcConnection connection, LOCAL_AUDIO_STREAM_STATE state, LOCAL_AUDIO_STREAM_ERROR error)
+        {
+            if (EventOnLocalAudioStateChanged == null) return;
+            EventOnLocalAudioStateChanged.Invoke(connection, state, error);
+        }
+
+        public override void OnRemoteAudioStateChanged(RtcConnection connection, uint remoteUid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason, int elapsed)
+        {
+            if (EventOnRemoteAudioStateChanged == null) return;
+            EventOnRemoteAudioStateChanged.Invoke(connection, remoteUid, state, reason, elapsed);
+        }
+
+        public override void OnActiveSpeaker(RtcConnection connection, uint uid)
+        {
+            if (EventOnActiveSpeaker == null) return;
+            EventOnActiveSpeaker.Invoke(connection, uid);
+        }
+
+        public override void OnClientRoleChanged(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole)
+        {
+            if (EventOnClientRoleChanged == null) return;
+            EventOnClientRoleChanged.Invoke(connection, oldRole, newRole);
+        }
+
+        public override void OnClientRoleChangeFailed(RtcConnection connection, CLIENT_ROLE_CHANGE_FAILED_REASON reason, CLIENT_ROLE_TYPE currentRole)
+        {
+            if (EventOnClientRoleChangeFailed == null) return;
+            EventOnClientRoleChangeFailed.Invoke(connection, reason, currentRole);
+        }
+
+        public override void OnAudioDeviceVolumeChanged(MEDIA_DEVICE_TYPE deviceType, int volume, bool muted)
+        {
+            if (EventOnAudioDeviceVolumeChanged == null) return;
+            EventOnAudioDeviceVolumeChanged.Invoke(deviceType, volume, muted);
+        }
+
+        public override void OnRtmpStreamingStateChanged(string url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR_TYPE errCode)
+        {
+            if (EventOnRtmpStreamingStateChanged == null) return;
+            EventOnRtmpStreamingStateChanged.Invoke(url, state, errCode);
+        }
+
+        public override void OnRtmpStreamingEvent(string url, RTMP_STREAMING_EVENT eventCode)
+        {
+            if (EventOnRtmpStreamingEvent == null) return;
+            EventOnRtmpStreamingEvent.Invoke(url, eventCode);
+        }
+
+        //public override void OnStreamPublished(string url, int error)
+        //{
+        //    if (EventOnStreamPublished == null) return;
+        //    EventOnStreamPublished.Invoke(url, error);
+        //}
+
+        //[Obsolete]
+        //public override void OnStreamUnpublished(string url)
+        //{
+        //    if (EventOnStreamUnpublished == null) return;
+        //    EventOnStreamUnpublished.Invoke(url);
+        //}
+
+        public override void OnTranscodingUpdated()
+        {
+            if (EventOnTranscodingUpdated == null) return;
+            EventOnTranscodingUpdated.Invoke();
+        }
+
+        public override void OnAudioRoutingChanged(int routing)
+        {
+            if (EventOnAudioRoutingChanged == null) return;
+            EventOnAudioRoutingChanged.Invoke(routing);
+        }
+
+        //public override void OnAudioSessionRestrictionResume()
+        //{
+        //    if (EventOnAudioSessionRestrictionResume == null) return;
+        //    EventOnAudioSessionRestrictionResume.Invoke();
+        //}
+
+        public override void OnChannelMediaRelayStateChanged(int state, int code)
+        {
+            if (EventOnChannelMediaRelayStateChanged == null) return;
+            EventOnChannelMediaRelayStateChanged.Invoke(state, code);
+        }
+
+        public override void OnChannelMediaRelayEvent(int code)
+        {
+            if (EventOnChannelMediaRelayEvent == null) return;
+            EventOnChannelMediaRelayEvent.Invoke(code);
+        }
+
+        public override void OnLocalPublishFallbackToAudioOnly(bool isFallbackOrRecover)
+        {
+            if (EventOnLocalPublishFallbackToAudioOnly == null) return;
+            EventOnLocalPublishFallbackToAudioOnly.Invoke(isFallbackOrRecover);
+        }
+
+        public override void OnRemoteSubscribeFallbackToAudioOnly(uint uid, bool isFallbackOrRecover)
+        {
+            if (EventOnRemoteSubscribeFallbackToAudioOnly == null) return;
+            EventOnRemoteSubscribeFallbackToAudioOnly.Invoke(uid, isFallbackOrRecover);
+        }
+
+        public override void OnRemoteAudioTransportStats(RtcConnection connection, uint remoteUid, UInt16 delay, UInt16 lost, UInt16 rxKBitRate)
+        {
+            if (EventOnRemoteAudioTransportStats == null) return;
+            EventOnRemoteAudioTransportStats.Invoke(connection, remoteUid, delay, lost, rxKBitRate);
+        }
+
+        public override void OnRemoteVideoTransportStats(RtcConnection connection, uint remoteUid, UInt16 delay, UInt16 lost, UInt16 rxKBitRate)
+        {
+            if (EventOnRemoteVideoTransportStats == null) return;
+            EventOnRemoteVideoTransportStats.Invoke(connection, remoteUid, delay, lost, rxKBitRate);
+        }
+
+        public override void OnConnectionStateChanged(RtcConnection connection, CONNECTION_STATE_TYPE state, CONNECTION_CHANGED_REASON_TYPE reason)
+        {
+            if (EventOnConnectionStateChanged == null) return;
+            EventOnConnectionStateChanged.Invoke(connection, state, reason);
+        }
+
+        public override void OnWlAccMessage(RtcConnection connection, WLACC_MESSAGE_REASON reason, WLACC_SUGGEST_ACTION action, string wlAccMsg)
+        {
+            if (EventOnWlAccMessage == null) return;
+            EventOnWlAccMessage.Invoke(connection, reason, action, wlAccMsg);
+        }
+
+        public override void OnWlAccStats(RtcConnection connection, WlAccStats currentStats, WlAccStats averageStats)
+        {
+            if (EventOnWlAccStats == null) return;
+            EventOnWlAccStats.Invoke(connection, currentStats, averageStats);
+        }
+
+        public override void OnNetworkTypeChanged(RtcConnection connection, NETWORK_TYPE type)
+        {
+            if (EventOnNetworkTypeChanged == null) return;
+            EventOnNetworkTypeChanged.Invoke(connection, type);
+        }
+
+        public override void OnEncryptionError(RtcConnection connection, ENCRYPTION_ERROR_TYPE errorType)
+        {
+            if (EventOnEncryptionError == null) return;
+            EventOnEncryptionError.Invoke(connection, errorType);
+        }
+
+        public override void OnUploadLogResult(RtcConnection connection, string requestId, bool success, UPLOAD_ERROR_REASON reason)
+        {
+            if (EventOnUploadLogResult == null) return;
+            EventOnUploadLogResult.Invoke(connection, requestId, success, reason);
+        }
+
+        public override void OnUserAccountUpdated(RtcConnection connection, uint remoteUid, string userAccount)
+        {
+            if (EventOnUserAccountUpdated == null) return;
+            EventOnUserAccountUpdated.Invoke(connection, remoteUid, userAccount);
+        }
+
+        public override void OnPermissionError(PERMISSION_TYPE permissionType)
+        {
+            if (EventOnPermissionError == null) return;
+            EventOnPermissionError.Invoke(permissionType);
+        }
+
+        public override void OnLocalUserRegistered(uint uid, string userAccount)
+        {
+            if (EventOnLocalUserRegistered == null) return;
+            EventOnLocalUserRegistered.Invoke(uid, userAccount);
+        }
+
+        public override void OnUserInfoUpdated(uint uid, UserInfo info)
+        {
+            if (EventOnUserInfoUpdated == null) return;
+            EventOnUserInfoUpdated.Invoke(uid, info);
+        }
+
+        public override void OnAudioSubscribeStateChanged(string channel, uint uid, STREAM_SUBSCRIBE_STATE oldState, STREAM_SUBSCRIBE_STATE newState, int elapseSinceLastState)
+        {
+            if (EventOnAudioSubscribeStateChanged == null) return;
+            EventOnAudioSubscribeStateChanged.Invoke(channel, uid, oldState, newState, elapseSinceLastState);
+        }
+
+        public override void OnVideoSubscribeStateChanged(string channel, uint uid, STREAM_SUBSCRIBE_STATE oldState, STREAM_SUBSCRIBE_STATE newState, int elapseSinceLastState)
+        {
+            if (EventOnVideoSubscribeStateChanged == null) return;
+            EventOnVideoSubscribeStateChanged.Invoke(channel, uid, oldState, newState, elapseSinceLastState);
+        }
+
+        public override void OnAudioPublishStateChanged(string channel, STREAM_PUBLISH_STATE oldState, STREAM_PUBLISH_STATE newState, int elapseSinceLastState)
+        {
+            if (EventOnAudioPublishStateChanged == null) return;
+            EventOnAudioPublishStateChanged.Invoke(channel, oldState, newState, elapseSinceLastState);
+        }
+
+        public override void OnVideoPublishStateChanged(VIDEO_SOURCE_TYPE source, string channel, STREAM_PUBLISH_STATE oldState, STREAM_PUBLISH_STATE newState, int elapseSinceLastState)
+        {
+            if (EventOnVideoPublishStateChanged == null) return;
+            EventOnVideoPublishStateChanged.Invoke(source, channel, oldState, newState, elapseSinceLastState);
+        }
+
+        public override void OnExtensionEvent(string provider, string extension, string key, string value)
+        {
+            if (EventOnExtensionEvent == null) return;
+            EventOnExtensionEvent.Invoke(provider, extension, key, value);
+        }
+
+        public override void OnExtensionStarted(string provider, string extension)
+        {
+            if (EventOnExtensionStarted == null) return;
+            EventOnExtensionStarted.Invoke(provider, extension);
+        }
+
+        public override void OnExtensionStopped(string provider, string extension)
+        {
+            if (EventOnExtensionStopped == null) return;
+            EventOnExtensionStopped.Invoke(provider, extension);
+        }
+
+        public override void OnExtensionError(string provider, string extension, int error, string message)
+        {
+            if (EventOnExtensionErrored == null) return;
+            EventOnExtensionErrored.Invoke(provider, extension, error, message);
+        }
+
+        public override void OnDirectCdnStreamingStateChanged(DIRECT_CDN_STREAMING_STATE state, DIRECT_CDN_STREAMING_ERROR error, string message)
+        {
+            if (EventOnExtensionErrored == null) return;
+            EventOnDirectCdnStreamingStateChanged.Invoke(state, error, message);
+        }
+
+        public override void OnDirectCdnStreamingStats(DirectCdnStreamingStats stats)
+        {
+            if (EventOnExtensionErrored == null) return;
+            EventOnDirectCdnStreamingStats.Invoke(stats);
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/Event/RtcEngineEventHandler.cs.meta

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

+ 264 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioDeviceManager.cs

@@ -0,0 +1,264 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// Audio device management methods.
+    /// </summary>
+    ///
+    public abstract class IAudioDeviceManager
+    {
+        #region PlaybackDevices
+        ///
+        /// <summary>
+        /// Enumerates the audio playback devices.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Success: Returns a DeviceInfo array, which includes the device ID and device name of all the audio playback devices.Failure: NULL.
+        /// </returns>
+        ///
+        public abstract DeviceInfo[] EnumeratePlaybackDevices();
+
+        ///
+        /// <summary>
+        /// Sets the audio playback device.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> The ID of the specified audio playback device. You can get the device ID by calling EnumeratePlaybackDevices . Plugging or unplugging the audio device does not change the value of deviceId.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetPlaybackDevice(string deviceId);
+
+        ///
+        /// <summary>
+        /// Retrieves the audio playback device associated with the device ID.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> Output parameter. The device ID of the audio playback device. </param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetPlaybackDevice(ref string deviceId);
+
+        ///
+        /// <summary>
+        /// Retrieves the audio playback device associated with the device ID.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> The device ID of the recording device. </param>
+        ///
+        /// <param name="deviceName"> The device name of the recording device. </param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetPlaybackDeviceInfo(ref string deviceId, ref string deviceName);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetPlaybackDeviceVolume(int volume);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int GetPlaybackDeviceVolume(ref int volume);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetPlaybackDeviceMute(bool mute);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int GetPlaybackDeviceMute(ref bool mute);
+
+        ///
+        /// <summary>
+        /// Starts the audio playback device test.
+        /// This method tests whether the audio playback device works properly. Once a user starts the test, the SDK plays an audio file specified by the user. If the user can hear the audio, the playback device works properly.After calling this method, the SDK triggers the OnAudioVolumeIndication callback every 100 ms, reporting uid = 1 and the volume information of the playback device.Ensure that you call this method before joining a channel.
+        /// </summary>
+        ///
+        /// <param name="testAudioFilePath"> The path of the audio file. The data format is string in UTF-8.Supported file formats: wav, mp3, m4a, and aac.Supported file sample rates: 8000, 16000, 32000, 44100, and 48000 Hz.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StartPlaybackDeviceTest(string testAudioFilePath);
+
+        ///
+        /// <summary>
+        /// Stops the audio playback device test.
+        /// This method stops the audio playback device test. You must call this method to stop the test after calling the StartPlaybackDeviceTest method.Ensure that you call this method before joining a channel.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StopPlaybackDeviceTest();
+
+        ///
+        /// <summary>
+        /// Sets the audio playback device used by the SDK to follow the system default audio playback device.
+        /// </summary>
+        ///
+        /// <param name="enable"> Whether to follow the system default audio playback device:true: Follow. The SDK immediately switches the audio playback device when the system default audio playback device changes.false: Do not follow. The SDK switches the audio playback device to the system default audio playback device only when the currently used audio playback device is disconnected.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int FollowSystemPlaybackDevice(bool enable);
+        #endregion
+
+        #region RecordingDevices
+        ///
+        /// <summary>
+        /// Enumerates the audio capture devices.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Success: A DeviceInfo array, which includes the device ID and device name of all the audio capture devices.Failure: NULL.
+        /// </returns>
+        ///
+        public abstract DeviceInfo[] EnumerateRecordingDevices();
+
+        ///
+        /// <summary>
+        /// Sets the audio recording device.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> The ID of the audio recording device. You can get the device ID by calling EnumerateRecordingDevices . Plugging or unplugging the audio device does not change the value of deviceId.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetRecordingDevice(string deviceId);
+
+        ///
+        /// <summary>
+        /// Gets the current audio recording device.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> Output parameter. The device ID of the recording device. </param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetRecordingDevice(ref string deviceId);
+
+        ///
+        /// <summary>
+        /// Retrieves the volume of the audio recording device.
+        /// </summary>
+        ///
+        /// <param name="deviceId"> The device ID of the recording device. </param>
+        ///
+        /// <param name="deviceName"> The device name of the recording device. </param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetRecordingDeviceInfo(ref string deviceId, ref string deviceName);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetRecordingDeviceVolume(int volume);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int GetRecordingDeviceVolume(ref int volume);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetRecordingDeviceMute(bool mute);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int GetRecordingDeviceMute(ref bool mute);
+
+        ///
+        /// <summary>
+        /// Starts the audio capture device test.
+        /// This method tests whether the audio capture device works properly. After calling this method, the SDK triggers the OnAudioVolumeIndication callback at the time interval set in this method, which reports uid = 0 and the volume information of the capturing device.Ensure that you call this method before joining a channel.
+        /// </summary>
+        ///
+        /// <param name="indicationInterval"> The time interval (ms) at which the SDK triggers the OnAudioVolumeIndication callback. Agora recommends a setting greater than 200 ms. This value must not be less than 10 ms; otherwise, you can not receive the OnAudioVolumeIndication callback.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StartRecordingDeviceTest(int indicationInterval);
+
+        ///
+        /// <summary>
+        /// Stops the audio capture device test.
+        /// This method stops the audio capture device test. You must call this method to stop the test after calling the StartRecordingDeviceTest method.Ensure that you call this method before joining a channel.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StopRecordingDeviceTest();
+
+        ///
+        /// <summary>
+        /// Sets the audio recording device used by the SDK to follow the system default audio recording device.
+        /// </summary>
+        ///
+        /// <param name="enable"> Whether to follow the system default audio recording device:true: Follow. The SDK immediately switches the audio recording device when the system default audio recording device changes.false: Do not follow. The SDK switches the audio recording device to the system default audio recording device only when the currently used audio recording device is disconnected.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int FollowSystemRecordingDevice(bool enable);
+        #endregion
+
+        #region AudioDevice
+        ///
+        /// <summary>
+        /// Starts an audio device loopback test.
+        /// This method tests whether the local audio capture device and playback device are working properly. Once the test starts, the audio recording device records the local audio, and the audio playback device plays the captured audio. The SDK triggers two independent OnAudioVolumeIndication callbacks at the time interval set in this method, which reports the volume information of the capture device (uid = 0) and the volume information of the playback device (uid = 1) respectively.Ensure that you call this method before joining a channel.This method tests local audio devices and does not report the network conditions.
+        /// </summary>
+        ///
+        /// <param name="indicationInterval"> The time interval (ms) at which the SDK triggers the OnAudioVolumeIndication callback. Agora recommends setting a value greater than 200 ms. This value must not be less than 10 ms; otherwise, you can not receive the OnAudioVolumeIndication callback.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StartAudioDeviceLoopbackTest(int indicationInterval);
+
+        ///
+        /// <summary>
+        /// Stops the audio device loopback test.
+        /// Ensure that you call this method before joining a channel.Ensure that you call this method to stop the loopback test after calling the StartAudioDeviceLoopbackTest method.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int StopAudioDeviceLoopbackTest();
+        #endregion
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioDeviceManager.cs.meta

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

+ 66 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioEncodedFrameObserver.cs

@@ -0,0 +1,66 @@
+using System;
+
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The encoded audio observer.
+    /// </summary>
+    ///
+    public abstract class IAudioEncodedFrameObserver
+    {
+        ///
+        /// <summary>
+        /// Gets the encoded audio data of the local user.
+        /// After calling RegisterAudioEncodedFrameObserver and setting the encoded audio as AUDIO_ENCODED_FRAME_OBSERVER_POSITION_RECORD, you can get the encoded audio data of the local user from this callback.
+        /// </summary>
+        ///
+        /// <param name="frameBufferPtr"> The audio buffer.</param>
+        ///
+        /// <param name="length"> The data length (byte).</param>
+        ///
+        /// <param name="audioEncodedFrameInfo"> Audio information after encoding. See EncodedAudioFrameInfo .</param>
+        ///
+        public virtual void OnRecordAudioEncodedFrame(IntPtr frameBufferPtr, int length, 
+                                                    EncodedAudioFrameInfo audioEncodedFrameInfo)
+        {
+
+        }
+
+        ///
+        /// <summary>
+        /// Gets the encoded audio data of all remote users.
+        /// After calling RegisterAudioEncodedFrameObserver and setting the encoded audio as AUDIO_ENCODED_FRAME_OBSERVER_POSITION_PLAYBACK, you can get encoded audio data of all remote users through this callback.
+        /// </summary>
+        ///
+        /// <param name="frameBufferPtr"> The audio buffer.</param>
+        ///
+        /// <param name="length"> The data length (byte).</param>
+        ///
+        /// <param name="audioEncodedFrameInfo"> Audio information after encoding. See EncodedAudioFrameInfo .</param>
+        ///
+        public virtual void OnPlaybackAudioEncodedFrame(IntPtr frameBufferPtr, int length, 
+                                                    EncodedAudioFrameInfo audioEncodedFrameInfo)
+        {
+
+        }
+
+        ///
+        /// <summary>
+        /// Gets the mixed and encoded audio data of the local and all remote users.
+        /// After calling RegisterAudioEncodedFrameObserver and setting the audio profile as AUDIO_ENCODED_FRAME_OBSERVER_POSITION_MIXED, you can get the mixed and encoded audio data of the local and all remote users through this callback.
+        /// </summary>
+        ///
+        /// <param name="frameBufferPtr"> The audio buffer.</param>
+        ///
+        /// <param name="length"> The data length (byte).</param>
+        ///
+        /// <param name="audioEncodedFrameInfo"> Audio information after encoding. See EncodedAudioFrameInfo .</param>
+        ///
+        public virtual void OnMixedAudioEncodedFrame(IntPtr frameBufferPtr, int length, 
+                                                    EncodedAudioFrameInfo audioEncodedFrameInfo)
+        {
+
+        }
+    };
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioEncodedFrameObserver.cs.meta

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

+ 166 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioFrameObserver.cs

@@ -0,0 +1,166 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The audio frame observer.
+    /// </summary>
+    ///
+    public abstract class IAudioFrameObserver
+    {
+        ///
+        /// <summary>
+        /// Gets the captured audio frame.
+        /// If you want to set the format of the captured audio frame, Agora recommends that you call the RegisterAudioFrameObserver method to set the format of the audio frame after calling the GetRecordAudioParams method to register an audio frame observer. The SDK calculates the sampling interval according to the AudioParams set in the GetRecordAudioParams callback return value, and triggers the OnRecordAudioFrame callback according to the sampling interval.
+        /// </summary>
+        ///
+        /// <param name="audioFrame"> The raw audio data. See AudioFrame .</param>
+        ///
+        /// <param name="channelId"> The channel ID.</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnRecordAudioFrame(string channelId ,AudioFrame audioFrame)
+        {
+            return true;
+        }
+
+        ///
+        /// <summary>
+        /// Gets the audio frame for playback.
+        /// If you want to set the format of the audio frame for playback, Agora recommends that you call the RegisterAudioFrameObserver method to set the format of the audio frame after calling the SetPlaybackAudioFrameParameters method to register an audio frame observer.
+        /// </summary>
+        ///
+        /// <param name="audio_Frame"> The raw audio data. See AudioFrame .</param>
+        ///
+        /// <param name="channelId"> The channel ID.</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnPlaybackAudioFrame(string channelId, AudioFrame audio_frame)
+        {
+            return true;
+        }
+
+        ///
+        /// <summary>
+        /// Retrieves the mixed captured and playback audio frame.
+        /// This callback only returns the single-channel data.If you want to set the format of the mixed captured and playback audio frame, Agora recommends you call the RegisterAudioFrameObserver method to set the format of the audio frames after calling the SetMixedAudioFrameParameters method to register an audio frame observer.
+        /// </summary>
+        ///
+        /// <param name="audio_Frame"> The raw audio data. See AudioFrame .</param>
+        ///
+        /// <param name="channelId"> The channel ID.</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnMixedAudioFrame(string channelId, AudioFrame audio_frame)
+        {
+            return true;
+        }
+
+        ///
+        /// @ignore
+        ///
+        public virtual int GetObservedAudioFramePosition()
+        {
+            return (int)AUDIO_FRAME_POSITION.AUDIO_FRAME_POSITION_NONE; 
+        }
+
+        ///
+        /// <summary>
+        /// Sets the audio format for the OnPlaybackAudioFrame callback.
+        /// You need to register the callback when calling the RegisterAudioFrameObserver method. After you successfully register the audio observer, the SDK triggers this callback, and you can set the audio format in the return value of this callback.The SDK calculates the sample interval according to the AudioParams you set in the return value of this callback.Sample interval = samplePerCall/(sampleRate × channel).Ensure that the sample interval ≥ 0.01 (s).The SDK triggers the OnPlaybackAudioFrame callback according to the sampling interval.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Sets the audio format. See AudioParams .
+        /// </returns>
+        ///
+        public virtual AudioParams GetPlaybackAudioParams()
+        {
+            return new AudioParams();
+        }
+
+        ///
+        /// <summary>
+        /// Sets the audio format for the OnRecordAudioFrame callback.
+        /// You need to register the callback when calling the RegisterAudioFrameObserver method. After you successfully register the audio observer, the SDK triggers this callback, and you can set the audio format in the return value of this callback.The SDK calculates the sample interval according to the AudioParams you set in the return value of this callback.Sample interval = samplePerCall/(sampleRate × channel).Ensure that the sample interval ≥ 0.01 (s).The SDK triggers the OnRecordAudioFrame callback according to the sampling interval.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Sets the audio format. See AudioParams .
+        /// </returns>
+        ///
+        public virtual AudioParams GetRecordAudioParams()
+        {
+            return new AudioParams();
+        }
+
+        ///
+        /// <summary>
+        /// Sets the audio format for the OnMixedAudioFrame callback.
+        /// You need to register the callback when calling the RegisterAudioFrameObserver method. After you successfully register the audio observer, the SDK triggers this callback, and you can set the audio format in the return value of this callback.The SDK calculates the sample interval according to the AudioParams you set in the return value of this callback.Sample interval = samplePerCall/(sampleRate × channel).Ensure that the sample interval ≥ 0.01 (s).The SDK triggers the OnMixedAudioFrame callback according to the sampling interval.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Sets the audio format. See AudioParams .
+        /// </returns>
+        ///
+        public virtual AudioParams GetMixedAudioParams()
+        {
+            return new AudioParams();
+        }
+
+        ///
+        /// <summary>
+        /// Retrieves the audio frame of a specified user before mixing.
+        /// </summary>
+        ///
+        /// <param name="channel_id"> The channel ID.</param>
+        ///
+        /// <param name="uid"> The user ID of the specified user.</param>
+        ///
+        /// <param name="audio_Frame"> The raw audio data. See AudioFrame .</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnPlaybackAudioFrameBeforeMixing(string channel_id,
+                                                        uint uid,
+                                                        AudioFrame audio_frame)
+        {
+            return false;
+        }
+
+        ///
+        /// <summary>
+        /// Retrieves the audio frame of a specified user before mixing.
+        /// </summary>
+        ///
+        /// <param name="channel_id"> The channel name that the audio frame came from.</param>
+        ///
+        /// <param name="uid"> The ID of the user sending the audio frame.</param>
+        ///
+        /// <param name="audio_Frame"> The raw audio data. See AudioFrame .</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnPlaybackAudioFrameBeforeMixing(string channel_id,
+                                                        string uid,
+                                                        AudioFrame audio_frame)
+        {
+            return false;
+        }
+    }
+
+
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioFrameObserver.cs.meta

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

+ 46 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioSpectrumObserver.cs

@@ -0,0 +1,46 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The audio spectrum observer.
+    /// </summary>
+    ///
+    public abstract class IAudioSpectrumObserver
+    {
+        ///
+        /// <summary>
+        /// Gets the statistics of a local audio spectrum.
+        /// After successfully calling RegisterAudioSpectrumObserver to implement the OnLocalAudioSpectrum callback in IAudioSpectrumObserver and calling EnableAudioSpectrumMonitor to enable audio spectrum monitoring, the SDK will trigger the callback as the time interval you set to report the received remote audio data spectrum.
+        /// </summary>
+        ///
+        /// <param name="data"> The audio spectrum data of the local user. See AudioSpectrumData .</param>
+        ///
+        /// <returns>
+        /// Whether you have received the spectrum data:true: Spectrum data is received.false: No spectrum data is received.
+        /// </returns>
+        ///
+        public virtual bool OnLocalAudioSpectrum(AudioSpectrumData data)
+        {
+            return true;
+        }
+
+        ///
+        /// <summary>
+        /// Gets the remote audio spectrum.
+        /// After successfully calling RegisterAudioSpectrumObserver to implement the OnRemoteAudioSpectrum callback in the IAudioSpectrumObserver and calling EnableAudioSpectrumMonitor to enable audio spectrum monitoring, the SDK will trigger the callback as the time interval you set to report the received remote audio data spectrum.
+        /// </summary>
+        ///
+        /// <param name="spectrums"> The audio spectrum information of the remote user, see UserAudioSpectrumInfo . The number of arrays is the number of remote users monitored by the SDK. If the array is null, it means that no audio spectrum of remote users is detected.</param>
+        ///
+        /// <param name="spectrumNumber"> The number of remote users.</param>
+        ///
+        /// <returns>
+        /// Whether you have received the spectrum data:true: Spectrum data is received.false: No spectrum data is received.
+        /// </returns>
+        ///
+        public virtual bool OnRemoteAudioSpectrum(UserAudioSpectrumInfo[] spectrums, uint spectrumNumber)
+        {
+            return true;
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IAudioSpectrumObserver.cs.meta

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

+ 651 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayer.cs

@@ -0,0 +1,651 @@
+using System;
+
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// This class provides media player functions and supports multiple instances.
+    /// </summary>
+    ///
+    public abstract class IMediaPlayer
+    {
+        ///
+        /// <summary>
+        /// Releases all the resources occupied by the media player.
+        /// </summary>
+        ///
+        public abstract void Dispose();
+
+        ///
+        /// <summary>
+        /// Gets the ID of the media player.
+        /// </summary>
+        ///
+        /// <returns>
+        /// >= 0: Success. The ID of the media player.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetId();
+
+        ///
+        /// <summary>
+        /// Adds callback event for media player.
+        /// </summary>
+        ///
+        /// <param name="engineEventHandler"> Callback events to be added. </param>
+        ///
+        public abstract void InitEventHandler(IMediaPlayerSourceObserver engineEventHandler);
+
+        ///
+        /// <summary>
+        /// Registers an audio frame observer object.
+        /// You need to implement the IMediaPlayerAudioFrameObserver class in this method and register callbacks according to your scenarios. After you successfully register the video frame observer, the SDK triggers the registered callbacks each time a video frame is received.
+        /// </summary>
+        ///
+        /// <param name="observer"> The audio frame observer, reporting the reception of each audio frame. See IMediaPlayerAudioFrameObserver .</param>
+        ///
+        public abstract void RegisterAudioFrameObserver(IMediaPlayerAudioFrameObserver observer);
+
+        ///
+        /// <summary>
+        /// Registers an audio frame observer object.
+        /// </summary>
+        ///
+        /// <param name="observer"> The audio frame observer, reporting the reception of each audio frame. See IAudioFrameObserver .</param>
+        ///
+        /// <param name="mode"> The use mode of the audio frame. See RAW_AUDIO_FRAME_OP_MODE_TYPE .</param>
+        ///
+        public abstract void RegisterAudioFrameObserver(IMediaPlayerAudioFrameObserver observer, RAW_AUDIO_FRAME_OP_MODE_TYPE mode);
+
+        ///
+        /// <summary>
+        /// Unregisters an audio frame observer.
+        /// </summary>
+        ///
+        public abstract void UnregisterAudioFrameObserver();
+
+        ///
+        /// @ignore
+        ///
+        public abstract void RegisterMediaPlayerAudioSpectrumObserver(IAudioSpectrumObserver observer, int intervalInMS);
+
+        ///
+        /// @ignore
+        ///
+        public abstract void UnregisterMediaPlayerAudioSpectrumObserver();
+
+        ///
+        /// <summary>
+        /// Opens the media resource.
+        /// This method is called asynchronously. If you need to play a media file, make sure you receive the OnPlayerSourceStateChanged callback reporting PLAYER_STATE_OPEN_COMPLETED before calling the Play method to play the file.
+        /// </summary>
+        ///
+        /// <param name="url"> The path of the media file. Both local path and online path are supported.On the Android platform, if you need to open a file in URI format, use Open .</param>
+        ///
+        /// <param name="startPos"> The starting position (ms) for playback. Default value is 0.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Open(string url, Int64 startPos);
+
+        ///
+        /// <summary>
+        /// Opens the custom media resource file.
+        /// Deprecated:This method is deprecated. This method allows you to open custom media resource files. For example, you can call this method to open encrypted media resources.
+        /// </summary>
+        ///
+        /// <param name="playerId"> The ID of the media player.</param>
+        ///
+        /// <param name="startPos"> The starting position (ms) for playback. The default value is 0.</param>
+        ///
+        /// <param name="provider"> The callback for custom media resource files. See IMediaPlayerCustomDataProvider .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int OpenWithCustomSource(Int64 startPos, IMediaPlayerCustomDataProvider provider);
+
+        ///
+        /// <summary>
+        /// Opens a media file and configures the playback scenarios.
+        /// This method supports opening media files of different sources, including a custom media source, and allows you to configure the playback scenarios.
+        /// </summary>
+        ///
+        /// <param name="source"> Media resources. See MediaSource .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int OpenWithMediaSource(MediaSource source);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetSoundPositionParams(float pan, float gain);
+
+        ///
+        /// <summary>
+        /// Plays the media file.
+        /// After calling Open or Seek, you can call this method to play the media file.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Play();
+
+        ///
+        /// <summary>
+        /// Pauses the playback.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Pause();
+
+        ///
+        /// <summary>
+        /// Stops playing the media track.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Stop();
+
+        ///
+        /// <summary>
+        /// Resumes playing the media file.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Resume();
+
+        ///
+        /// <summary>
+        /// Seeks to a new playback position.
+        /// After successfully calling this method, you will receive the OnPlayerEvent callback, reporting the result of the seek operation to the new playback position.To play the media file from a specific position, do the following:Call this method to seek to the position you want to begin playback.Call the Play method to play the media file.
+        /// </summary>
+        ///
+        /// <param name="newPos"> The new playback position (ms).</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Seek(Int64 newPos);
+
+        ///
+        /// <summary>
+        /// Gets the duration of the media resource.
+        /// </summary>
+        ///
+        /// <param name="duration"> Output parameter. The total duration (ms) of the media file.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetDuration(ref Int64 duration);
+
+        ///
+        /// <summary>
+        /// Gets current local playback progress.
+        /// </summary>
+        ///
+        /// <param name="pos"> The playback position (ms) of the audio effect file.</param>
+        ///
+        /// <returns>
+        /// Returns the current playback progress (ms) if the call succeeds.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int GetPlayPosition(ref Int64 pos);
+
+        ///
+        /// <summary>
+        /// Gets the number of the media streams in the media resource.
+        /// Call this method after calling Open .
+        /// </summary>
+        ///
+        /// <param name="count"> Output parameter. The number of the media streams in the media resource.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int GetStreamCount(ref Int64 count);
+
+        ///
+        /// <summary>
+        /// Gets the detailed information of the media stream.
+        /// Call this method after calling GetStreamCount .
+        /// </summary>
+        ///
+        /// <param name="index"> The index of the media stream.</param>
+        ///
+        /// <param name="info"> An output parameter. The detailed information of the media stream. See PlayerStreamInfo .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetStreamInfo(Int64 index, ref PlayerStreamInfo info);
+
+        ///
+        /// <summary>
+        /// Sets the loop playback.
+        /// If you want to loop, call this method and set the number of the loops.When the loop finishes, the SDK triggers OnPlayerSourceStateChanged and reports the playback state as PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED.
+        /// </summary>
+        ///
+        /// <param name="loopCount"> The number of times the audio effect loops:</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetLoopCount(int loopCount);
+
+        ///
+        /// <summary>
+        /// Sets the channel mode of the current audio file.
+        /// Call this method after calling Open .
+        /// </summary>
+        ///
+        /// <param name="speed"> The playback speed. Agora recommends that you limit this value to between 50 and 400, defined as follows:50: Half the original speed.100: The original speed.400: 4 times the original speed.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetPlaybackSpeed(int speed);
+
+        ///
+        /// <summary>
+        /// Selects the audio track used during playback.
+        /// After getting the track index of the audio file, you can call this method to specify any track to play. For example, if different tracks of a multi-track file store songs in different languages, you can call this method to set the playback language.You need to call this method after calling GetStreamInfo to get the audio stream index value.
+        /// </summary>
+        ///
+        /// <param name="index"> The index of the audio track.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SelectAudioTrack(int index);
+
+        ///
+        /// <summary>
+        /// Sets the private options for the media player.
+        /// The media player supports setting private options by key and value. Under normal circumstances, you do not need to know the private option settings, and just use the default option settings.Ensure that you call this method before Open .If you need to push streams with SEI into the CDN, callSetPlayerOption [1/2] ("sei_data_with_uuid", 1); otherwise, the loss of SEI might occurs.
+        /// </summary>
+        ///
+        /// <param name="key"> The key of the option.</param>
+        ///
+        /// <param name="value"> The value of the key.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetPlayerOption(string key, int value);
+
+        ///
+        /// <summary>
+        /// Sets the private options for the media player.
+        /// The media player supports setting private options by key and value. Under normal circumstances, you do not need to know the private option settings, and just use the default option settings. Ensure that you call this method before Open .
+        /// If you need to push streams with SEI into the CDN, callSetPlayerOption [1/2] ("sei_data_with_uuid", 1); otherwise, the loss of SEI might occurs.
+        /// </summary>
+        ///
+        /// <param name="key"> The key of the option.</param>
+        ///
+        /// <param name="value"> The value of the key.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetPlayerOption(string key, string value);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int TakeScreenshot(string filename);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SelectInternalSubtitle(int index);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetExternalSubtitle(string url);
+
+        ///
+        /// <summary>
+        /// Gets current playback state.
+        /// </summary>
+        ///
+        /// <returns>
+        /// The current playback state. See MEDIA_PLAYER_STATE .
+        /// </returns>
+        ///
+        public abstract MEDIA_PLAYER_STATE GetState();
+
+        ///
+        /// <summary>
+        /// Sets whether to mute the media file.
+        /// </summary>
+        ///
+        /// <param name="muted"> Whether to mute the media file:true: Mute the media file.false: (Default) Unmute the media file.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int Mute(bool muted);
+
+        ///
+        /// <summary>
+        /// Reports whether the media resource is muted.
+        /// </summary>
+        ///
+        /// <param name="muted"> Output parameter. Whether the media file is muted:true: Mute the media file.false: The media file is unmuted.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetMute(ref bool muted);
+
+        ///
+        /// <summary>
+        /// Adjusts the local playback volume.
+        /// </summary>
+        ///
+        /// <param name="volume"> The local playback volume, which ranges from 0 to 100:0: Mute.100: (Default) The original volume.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int AdjustPlayoutVolume(int volume);
+
+        ///
+        /// <summary>
+        /// Gets the local playback volume.
+        /// </summary>
+        ///
+        /// <param name="volume"> Output parameter. The local playback volume, which ranges from 0 to 100:0: Mute.100: (Default) The original volume.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetPlayoutVolume(ref int volume);
+
+        ///
+        /// <summary>
+        /// Adjusts the volume of the media file for publishing.
+        /// After connected to the Agora server, you can call this method to adjust the volume of the media file heard by the remote user.
+        /// </summary>
+        ///
+        /// <param name="volume"> The volume, which ranges from 0 to 400:0: Mute.100: (Default) The original volume.400: Four times the original volume (amplifying the audio signals by four times).</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int AdjustPublishSignalVolume(int volume);
+
+        ///
+        /// <summary>
+        /// Gets the volume of the media file for publishing.
+        /// </summary>
+        ///
+        /// <param name="volume"> Output parameter. The remote playback volume.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetPublishSignalVolume(ref int volume);
+
+        ///
+        /// <summary>
+        /// Sets the view.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetView();
+
+        ///
+        /// <summary>
+        /// Sets the render mode of the media player.
+        /// </summary>
+        ///
+        /// <param name="renderMode"> Sets the render mode of the view. See RENDER_MODE_TYPE .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetRenderMode(RENDER_MODE_TYPE renderMode);
+
+        ///
+        /// <summary>
+        /// Sets the channel mode of the current audio file.
+        /// In a stereo music file, the left and right channels can store different audio data. According to your needs, you can set the channel mode to original mode, left channel mode, right channel mode, or mixed channel mode. For example, in the KTV scenario, the left channel of the music file stores the musical accompaniment, and the right channel stores the singing voice. If you only need to listen to the accompaniment, call this method to set the channel mode of the music file to left channel mode; if you need to listen to the accompaniment and the singing voice at the same time, call this method to set the channel mode to mixed channel mode.Call this method after calling Open .This method only applies to stereo audio files.
+        /// </summary>
+        ///
+        /// <param name="mode"> The channel mode. See AUDIO_DUAL_MONO_MODE .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetAudioDualMonoMode(AUDIO_DUAL_MONO_MODE mode);
+
+        ///
+        /// @ignore
+        ///
+        public abstract string GetPlayerSdkVersion();
+
+        ///
+        /// @ignore
+        ///
+        public abstract string GetPlaySrc();
+
+        ///
+        /// <summary>
+        /// Sets the pitch of the current media resource.
+        /// Call this method after calling Open .
+        /// </summary>
+        ///
+        /// <param name="pitch"> Sets the pitch of the local music file by the chromatic scale. The default value is 0, which means keeping the original pitch. The value ranges from -12 to 12, and the pitch value between consecutive values is a chromatic value. The greater the absolute value of this parameter, the higher or lower the pitch of the local music file.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetAudioPitch(int pitch);
+
+        ///
+        /// @ignore
+        ///
+        public abstract int SetSpatialAudioParams(SpatialAudioParams spatial_audio_params);
+
+        ///
+        /// <summary>
+        /// Opens a media resource and requests all the CDN routes of the media resources through the self-developed scheduling center.
+        /// This method is called asynchronously. If you need to play a media file, make sure you receive the OnPlayerSourceStateChanged callback reporting PLAYER_STATE_OPEN_COMPLETED before calling the Play method to play the file.After you call this method, Agora opens the media resources and tries to obtain all the CDN routes for playing the media resource. By default, Agora uses the first CDN route for playing, and you can call the SwitchAgoraCDNLineByIndex method to switch routes.If you want to ensure the security of the connection and media files, to determine the sign and the ts fields for authentication. Once the fields are determined, use them as the query parameter of the URL to update the URL of the media resource. For example:The URL of the media file to be opened: rtmp://$domain/$appName/$streamNameThe URL updated by the authentication of the media file to be opened: rtmp://$domain/$appName/$streamName?ts=$ts&sign=$signAuthentication information:sign: An encrypted string calculated according to the MD5 algorithm based on authKey, appName, streamName, and ts. You need to for your authKey.ts: The timestamp when the authentication information expires. You can set the validity period of the authentication information according to your scenarios. For example, 24h or 1h30m20s.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <param name="startPos"> The starting position (ms) for playback. The default value is 0. This value can be empty if the media resource to be played is live streams.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int OpenWithAgoraCDNSrc(string src, Int64 startPos);
+
+        ///
+        /// <summary>
+        /// Gets the number of CDN routes for the media resource.
+        /// </summary>
+        ///
+        /// <returns>
+        /// Returns the number of CDN routes for the media resource, if the method call succeeds.≤ 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetAgoraCDNLineCount();
+
+        ///
+        /// <summary>
+        /// Changes the CDN route for playing the media resource.
+        /// After calling OpenWithAgoraCDNSrc to open the media resource, you can call this method if you want to change the CDN routes for playing the media resource.Call this method after calling OpenWithAgoraCDNSrc .You can call this method either before or after Play . If you call this method before Play, the switch does not take effect immediately. The SDK waits for the playback to complete before switching the CDN line of the media resource.
+        /// </summary>
+        ///
+        /// <param name="index"> The index of the CDN routes.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SwitchAgoraCDNLineByIndex(int index);
+
+        ///
+        /// <summary>
+        /// Gets the CDN routes index of the current media resource.
+        /// </summary>
+        ///
+        /// <returns>
+        /// The number of CDN routes for the media resource, if the method call succeeds. The value range is [0, GetAgoraCDNLineCount()).&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int GetCurrentAgoraCDNIndex();
+
+        ///
+        /// <summary>
+        /// Enables/Disables the automatic switch of the CDN routes for playing the media resource.
+        /// You can call this method if you want the SDK to automatically switch the CDN routes according to your network conditions.Call this method before OpenWithAgoraCDNSrc .
+        /// </summary>
+        ///
+        /// <param name="enable"> Whether to enable the automatic switch of the CDN routes for playing the media resource:true: Enables the automatic switch of the CDN routes.false: (Default) Disables the automatic switch of the CDN routes.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int EnableAutoSwitchAgoraCDN(bool enable);
+
+        ///
+        /// <summary>
+        /// Renew the authentication information for the URL of the media resource to be played.
+        /// When the authentication information expires (exceeds the ts field), you can call the OpenWithAgoraCDNSrc method to reopen the media resource or the SwitchAgoraCDNSrc method to switch the media resource, and then pass in the authenticated URL (with the ts field updated) of the media resource.If your authentication information expires when you call the SwitchAgoraCDNLineByIndex to switch the CDN route for playing the media resource, you need to call this method to pass in the updated authentication information to update the authentication information of the media resource URL. After updating the authentication information, you need to call SwitchAgoraCDNLineByIndex to complete the route switching.To avoid frequent expiration of authentication information, ensure that you set the ts field appropriately or according to the scenario requirements.
+        /// </summary>
+        ///
+        /// <param name="token"> The authentication field. See the sign field of the authentication information.</param>
+        ///
+        /// <param name="ts"> The timestamp when the authentication information expires. See the ts field of the authentication information.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int RenewAgoraCDNSrcToken(string token, Int64 ts);
+
+        ///
+        /// <summary>
+        /// Switches the media resource being played.
+        /// If you want to ensure the security of the connection and media files, to determine the sign and the ts fields for authentication. Once the fields are determined, use them as the query parameter of the URL to update the URL of the media resource. For example:The URL of the media file to be opened: rtmp://$domain/$appName/$streamNameThe URL updated by the authentication of the media file to be opened: rtmp://$domain/$appName/$streamName?ts=$ts&sign=$signAuthentication information:sign: An encrypted string calculated according to the MD5 algorithm based on authKey, appName, streamName, and ts. You need to for your authKey.ts: The timestamp when the authentication information expires. You can set the validity period of the authentication information according to your scenarios. For example, 24h or 1h30m20s.If you want to customize the CDN routes for playing the media resource, call this method to switch media resources. Agora changes the CDN route through the self-developed scheduling center to improve the viewing experience. If you do not need to customize CDN routes for playing the media resource, call the SwitchSrc method to switch media resources.
+        /// Call this method after calling OpenWithAgoraCDNSrc .You can call this method either before or after Play . If you call this method before Play, the SDK waits for you to call Play before completing the route switch.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <param name="syncPts"> Whether to synchronize the playback position (ms) before and after the switch:true: Synchronize the playback position before and after the switch.false: (Default) Do not synchronize the playback position before and after the switch.falseMake sure to set this parameter as if you need to play live streams, or the switch fails. If you need to play on-demand streams, you can set the value of this parameter according to your scenarios.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SwitchAgoraCDNSrc(string src, bool syncPts = false);
+
+        ///
+        /// <summary>
+        /// Switches the media resource being played.
+        /// You can call this method to switch the media resource to be played according to the current network status. For example:When the network is poor, the media resource to be played is switched to a media resource address with a lower bitrate.When the network is good, the media resource to be played is switched to a media resource address with a higher bitrate.After calling this method, if you receive the OnPlayerEvent event in the PLAYER_EVENT_SWITCH_COMPLETE callback, the switch is successful; If you receive the OnPlayerEvent event in the PLAYER_EVENT_SWITCH_ERROR callback, the switch fails.Ensure that you call this method after Open .To ensure normal playback, pay attention to the following when calling this method:Do not call this method when playback is paused.Do not call the Seek method during switching.Before switching the media resource, make sure that the playback position does not exceed the total duration of the media resource to be switched.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <param name="syncPts"> Whether to synchronize the playback position (ms) before and after the switch:true: Synchronize the playback position before and after the switch.false: (Default) Do not synchronize the playback position before and after the switch.Make sure to set this parameter as false if you need to play live streams, or the switch fails. If you need to play on-demand streams, you can set the value of this parameter according to your scenarios.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SwitchSrc(string src, bool syncPts = true);
+
+        ///
+        /// <summary>
+        /// Preloads a media resource.
+        /// You can call this method to preload a media resource into the playlist. If you need to preload multiple media resources, you can call this method multiple times.If the preload is successful and you want to play the media resource, call PlayPreloadedSrc ; if you want to clear the playlist, call Stop .Agora does not support preloading duplicate media resources to the playlist. However, you can preload the media resources that are being played to the playlist again.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <param name="startPos"> The starting position (ms) for playing after the media resource is preloaded to the playlist. When preloading a live stream, set this parameter to 0.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int PreloadSrc(string src, Int64 startPos);
+
+        ///
+        /// <summary>
+        /// Plays preloaded media resources.
+        /// After calling the PreloadSrc method to preload the media resource into the playlist, you can call this method to play the preloaded media resource. After calling this method, if you receive the OnPlayerSourceStateChanged callback which reports the PLAYER_STATE_PLAYING state, the playback is successful.If you want to change the preloaded media resource to be played, you can call this method again and specify the URL of the new media resource that you want to preload. If you want to replay the media resource, you need to call PreloadSrc to preload the media resource to the playlist again before playing. If you want to clear the playlist, call the Stop method.If you call this method when playback is paused, this method does not take effect until playback is resumed.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource in the playlist must be consistent with the src set by the PreloadSrc method; otherwise, the media resource cannot be played.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int PlayPreloadedSrc(string src);
+
+        ///
+        /// <summary>
+        /// Unloads media resources that are preloaded.
+        /// This method cannot release the media resource being played.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int UnloadSrc(string src);
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayer.cs.meta

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

+ 158 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCacheManager.cs

@@ -0,0 +1,158 @@
+using System;
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// This class provides methods to manage cached media files.
+    /// </summary>
+    ///
+    public abstract class IMediaPlayerCacheManager
+    {
+        ///
+        /// <summary>
+        /// Deletes all cached media files in the media player.
+        /// The cached media file currently being played will not be deleted.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int RemoveAllCaches();
+      
+        ///
+        /// <summary>
+        /// Deletes a cached media file that is the least recently used.
+        /// You can call this method to delete a cached media file when the storage space for the cached files is about to reach its limit. After you call this method, the SDK deletes the cached media file that is least used.The cached media file currently being played will not be deleted.
+        /// </summary>
+        ///
+        /// <returns>
+        /// 0: Success.
+        /// &lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int RemoveOldCache();
+     
+        ///
+        /// <summary>
+        /// Deletes a cached media file.
+        /// The cached media file currently being played will not be deleted.
+        /// </summary>
+        ///
+        /// <param name="uri"> The URI (Uniform Resource Identifier) of the media file to be deleted.</param>
+        ///
+        /// <returns>
+        /// 0: Success.
+        /// &lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int RemoveCacheByUri(string uri) ;
+      
+        ///
+        /// <summary>
+        /// Sets the storage path for the media files that you want to cache.
+        /// Make sure IRtcEngine is initialized before you call this method.
+        /// </summary>
+        ///
+        /// <param name="path"> The absolute path of the media files to be cached. Ensure that the directory for the media files exists and is writable.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int SetCacheDir(string path) ;
+      
+        ///
+        /// <summary>
+        /// Sets the maximum number of media files that can be cached.
+        /// </summary>
+        ///
+        /// <param name="count"> The maximum number of media files that can be cached. The default value is 1,000.</param>
+        ///
+        /// <returns>
+        /// 0: Success.
+        /// &lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int SetMaxCacheFileCount(int count);
+     
+        ///
+        /// <summary>
+        /// Sets the maximum size of the aggregate storage space for cached media files.
+        /// </summary>
+        ///
+        /// <param name="cacheSize"> The maximum size (bytes) of the aggregate storage space for cached media files. The default value is 1 GB.</param>
+        ///
+        /// <returns>
+        /// 0: Success.
+        /// &lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int SetMaxCacheFileSize(Int64 cacheSize);
+       
+        ///
+        /// <summary>
+        /// Sets whether to delete cached media files automatically.
+        /// If you enable this function to remove cached media files automatically, when the cached media files exceed either the number or size limit you set, the SDK automatically deletes the least recently used cache file.
+        /// </summary>
+        ///
+        /// <param name="enable"> Whether to enable the SDK to delete cached media files automatically:true: Delete cached media files automatically.false: (Default) Do not delete cached media files automatically.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int EnableAutoRemoveCache(bool enable);
+      
+        ///
+        /// <summary>
+        /// Gets the storage path of the cached media files.
+        /// If you have not called the SetCacheDir method to set the storage path for the media files to be cached before calling this method, you get the default storage path used by the SDK.
+        /// </summary>
+        ///
+        /// <param name="path"> An output parameter; the storage path for the media file to be cached.</param>
+        ///
+        /// <param name="length"> An input parameter; the maximum length of the cache file storage path string. Fill in according to the cache file storage path string you obtained from path.</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int GetCacheDir(out string path, int length);
+      
+        ///
+        /// <summary>
+        /// Gets the maximum number of media files that can be cached.
+        /// By default, the maximum number of media files that can be cached is 1,000.
+        /// </summary>
+        ///
+        /// <returns>
+        /// > 0: The call succeeds and returns the maximum number of media files that can be cached.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int GetMaxCacheFileCount();
+       
+        ///
+        /// <summary>
+        /// Gets the maximum size of the aggregate storage space for cached media files.
+        /// By default, the maximum size of the aggregate storage space for cached media files is 1 GB. You can call the SetMaxCacheFileSize method to set the limit according to your scenarios.
+        /// </summary>
+        ///
+        /// <returns>
+        /// > 0: The call succeeds and returns the maximum size (in bytes) of the aggregate storage space for cached media files.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract Int64 GetMaxCacheFileSize();
+       
+        ///
+        /// <summary>
+        /// Gets the number of media files that are cached.
+        /// </summary>
+        ///
+        /// <returns>
+        /// >= 0: The call succeeds and returns the number of media files that are cached.&lt; 0: Failure. See MEDIA_PLAYER_ERROR .
+        /// </returns>
+        ///
+        public abstract int GetCacheFileCount();
+    };
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCacheManager.cs.meta

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

+ 48 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCustomDataProvider.cs

@@ -0,0 +1,48 @@
+using System;
+
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The callback for custom media resource files.
+    /// </summary>
+    ///
+    public abstract class IMediaPlayerCustomDataProvider
+    {
+        ///
+        /// <summary>
+        /// Occurs when the SDK seeks the media resource data.
+        /// </summary>
+        ///
+        /// <param name="offset"> An input parameter. The offset of the target position relative to the starting point, in bytes. The value can be positive or negative.</param>
+        ///
+        /// <param name="whence"> An input parameter. The starting point. You can set it as one of the following values:0: The starting point is the head of the data, and the actual data offset after seeking is offset.1: The starting point is the current position, and the actual data offset after seeking is the current position plus offset.2: The starting point is the end of the data, and the actual data offset after seeking is the whole data length plus offset.65536: Do not perform position seeking, return the file size. Agora recommends that you use this parameter value when playing pure audio files such as MP3 and WAV.</param>
+        ///
+        /// <returns>
+        /// When when ce is 65536, the media file size is returned.When when ce is 0, 1, or 2, the actual data offset after the seeking is returned.-1: Seeking failed.
+        /// </returns>
+        ///
+        public virtual Int64 OnSeek(Int64 offset, int whence)
+        {
+            return 0;
+        }
+
+        ///
+        /// <summary>
+        /// Occurs when the SDK reads the media resource data.
+        /// </summary>
+        ///
+        /// <param name="bufferPtr"> An input parameter. Data buffer (bytes). Write the bufferSize data reported by the SDK into this parameter.</param>
+        ///
+        /// <param name="bufferSize"> The length of the data buffer (bytes).</param>
+        ///
+        /// <returns>
+        /// If the data is read successfully, pass in the length of the data (bytes) you actually read in the return value.If reading the data fails, pass in 0 in the return value.
+        /// </returns>
+        ///
+        public virtual int OnReadData(IntPtr bufferPtr, int bufferSize)
+        {
+            return 0;
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerCustomDataProvider.cs.meta

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

+ 27 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerFrameObserver.cs

@@ -0,0 +1,27 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The audio frame observer for the media player.
+    /// </summary>
+    ///
+    public abstract class IMediaPlayerAudioFrameObserver
+    {
+        ///
+        /// <summary>
+        /// Occurs each time the player receives an audio frame.
+        /// After registering the audio frame observer, the callback occurs every time the player receives an audio frame, reporting the detailed information of the audio frame.
+        /// </summary>
+        ///
+        /// <param name="videoFrame"> Audio frame information. See AudioPcmFrame .</param>
+        ///
+        /// <returns>
+        /// Reserved for future use.
+        /// </returns>
+        ///
+        public virtual bool OnFrame(AudioPcmFrame videoFrame)
+        {
+            return true;
+        }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerFrameObserver.cs.meta

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

+ 127 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerSourceObserver.cs

@@ -0,0 +1,127 @@
+using System;
+
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// Provides callbacks for media players.
+    /// </summary>
+    ///
+    public abstract class IMediaPlayerSourceObserver
+    {
+        ///
+        /// <summary>
+        /// Reports the playback state change.
+        /// When the state of the media player changes, the SDK triggers this callback to report the current playback state.
+        /// </summary>
+        ///
+        /// <param name="state"> The playback state, see MEDIA_PLAYER_STATE .</param>
+        ///
+        /// <param name="ec"> The error code. See MEDIA_PLAYER_ERROR .</param>
+        ///
+        public virtual void OnPlayerSourceStateChanged(MEDIA_PLAYER_STATE state, MEDIA_PLAYER_ERROR ec) { }
+
+        ///
+        /// <summary>
+        /// Reports current playback progress.
+        /// When playing media files, the SDK triggers this callback every one second to report current playback progress.
+        /// </summary>
+        ///
+        /// <param name="position_ms"> The playback position (ms) of media files.</param>
+        ///
+        public virtual void OnPositionChanged(Int64 position_ms) { }
+
+        ///
+        /// <summary>
+        /// Reports the playback event.
+        /// After calling the Seek method, the SDK triggers the callback to report the results of the seek operation.
+        /// </summary>
+        ///
+        /// <param name="eventCode"> The playback event. See MEDIA_PLAYER_EVENT .</param>
+        ///
+        /// <param name="elapsedTime"> The time (ms) when the event occurs.</param>
+        ///
+        /// <param name="message"> Information about the event.</param>
+        ///
+        public virtual void OnPlayerEvent(MEDIA_PLAYER_EVENT eventCode, Int64 elapsedTime, string message) { }
+
+        ///
+        /// <summary>
+        /// Occurs when the media metadata is received.
+        /// The callback occurs when the player receives the media metadata and reports the detailed information of the media metadata.
+        /// </summary>
+        ///
+        /// <param name="data"> The detailed data of the media metadata.</param>
+        ///
+        /// <param name="length"> The data length (bytes).</param>
+        ///
+        public virtual void OnMetaData(byte[] data, int length) { }
+
+        ///
+        /// <summary>
+        /// Reports the playback duration that the buffered data can support.
+        /// When playing online media resources, the SDK triggers this callback every two seconds to report the playback duration that the currently buffered data can support.When the playback duration supported by the buffered data is less than the threshold (0 by default), the SDK returns PLAYER_EVENT_BUFFER_LOW.When the playback duration supported by the buffered data is greater than the threshold (0 by default), the SDK returns PLAYER_EVENT_BUFFER_RECOVER.
+        /// </summary>
+        ///
+        /// <param name="playCachedBuffer"> The playback duration (ms) that the buffered data can support.</param>
+        ///
+        public virtual void OnPlayBufferUpdated(Int64 playCachedBuffer) { }
+
+        ///
+        /// <summary>
+        /// Reports the events of preloaded media resources.
+        /// </summary>
+        ///
+        /// <param name="src"> The URL of the media resource.</param>
+        ///
+        /// <param name="@event"> Events that occur when media resources are preloaded. See PLAYER_PRELOAD_EVENT .</param>
+        ///
+        public virtual void OnPreloadEvent(string src, PLAYER_PRELOAD_EVENT @event) { }
+
+        ///
+        /// <summary>
+        /// Occurs when the media file is played once.
+        /// </summary>
+        ///
+        public virtual void OnCompleted() { }
+
+        ///
+        /// <summary>
+        /// Occurs when the token is about to expire.
+        /// If the ts is about to expire when you call the SwitchAgoraCDNLineByIndex method to switch the CDN route for playing the media resource, the SDK triggers this callback to remind you to renew the authentication information. You need to call the RenewAgoraCDNSrcToken method to pass in the updated authentication information to update the authentication information of the media resource URL. After updating the authentication information, you need to call SwitchAgoraCDNLineByIndex to complete the route switching.
+        /// </summary>
+        ///
+        public virtual void OnAgoraCDNTokenWillExpire() { }
+
+        ///
+        /// <summary>
+        /// Occurs when the video bitrate of the media resource changes.
+        /// </summary>
+        ///
+        /// <param name="from"> Information about the video bitrate of the media resource being played. See SrcInfo .</param>
+        ///
+        /// <param name="to"> Information about the changed video bitrate of media resource being played. See SrcInfo .</param>
+        ///
+        public virtual void OnPlayerSrcInfoChanged(SrcInfo from, SrcInfo to) { }
+
+        ///
+        /// <summary>
+        /// Occurs when information related to the media player changes.
+        /// When the information about the media player changes, the SDK triggers this callback. You can use this callback for troubleshooting.
+        /// </summary>
+        ///
+        /// <param name="info"> Information related to the media player. See PlayerUpdatedInfo .</param>
+        ///
+        public virtual void OnPlayerInfoUpdated(PlayerUpdatedInfo info) { }
+
+        ///
+        /// <summary>
+        /// Reports the volume of the media player.
+        /// The SDK triggers this callback every 200 milliseconds to report the current volume of the media player.
+        /// </summary>
+        ///
+        /// <param name="volume"> The volume of the media player. The value ranges from 0 to 255.</param>
+        ///
+        public virtual void OnAudioVolumeIndication(int volume) { }
+    }
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaPlayerSourceObserver.cs.meta

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

+ 58 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorder.cs

@@ -0,0 +1,58 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// Used for recording audio and video on the client.
+    /// IMediaRecorder can record the following:
+    /// The audio captured by the local microphone and encoded in AAC format.The video captured by the local camera and encoded by the SDK.
+    /// </summary>
+    ///
+    public abstract class IMediaRecorder
+    {
+        ///
+        /// <summary>
+        /// Registers one IMediaRecorderObserver object.
+        /// Make sure the IRtcEngine is initialized before you call this method.
+        /// </summary>
+        ///
+        /// <param name="connection"> The connection information. See RtcConnection .</param>
+        ///
+        /// <param name="callback"> The callbacks for recording local audio and video streams. See IMediaRecorderObserver .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.
+        /// </returns>
+        ///
+        public abstract int SetMediaRecorderObserver(RtcConnection connection, IMediaRecorderObserver callback);
+
+        ///
+        /// <summary>
+        /// Starts recording the local audio and video.
+        /// After successfully getting the IMediaRecorder object by calling GetMediaRecorder , you can call this method to enable the recoridng of the local audio and video.This method can record the audio captured by the local microphone and encoded in AAC format, and the video captured by the local camera and encoded in H.264 format. The SDK can generate a recording file only when it detects audio and video streams; when there are no audio and video streams to be recorded or the audio and video streams are interrupted for more than five seconds, the SDK stops the recording and triggers the OnRecorderStateChanged(RECORDER_STATE_ERROR, RECORDER_ERROR_NO_STREAM) callback.Once the recording is started, if the video resolution is changed, the SDK stops the recording; if the sampling rate and audio channel changes, the SDK continues recording and generates audio files respectively.Call this method after joining a channel.
+        /// </summary>
+        ///
+        /// <param name="connection"> The connection information. See RtcConnection .</param>
+        ///
+        /// <param name="config"> The recording configuration. See MediaRecorderConfiguration .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.2: The parameter is invalid. Ensure the following:The specified path of the recording file exists and is writable.The specified format of the recording file is supported.The maximum recording duration is correctly set.4: IRtcEngine does not support the request. The recording is ongoing or the recording stops because an error occurs.7: A method is called before IRtcEngine is initialized.
+        /// </returns>
+        ///
+        public abstract int StartRecording(RtcConnection connection, MediaRecorderConfiguration config);
+
+        ///
+        /// <summary>
+        /// Stops recording the local audio and video.
+        /// After calling StartRecording , if you want to stop the recording, you must call this method; otherwise, the generated recording files may not be playable.
+        /// </summary>
+        ///
+        /// <param name="connection"> The connection information. See RtcConnection .</param>
+        ///
+        /// <returns>
+        /// 0: Success.&lt; 0: Failure.-7: A method is called before IRtcEngine is initialized.
+        /// </returns>
+        ///
+        public abstract int StopRecording(RtcConnection connection);
+    };
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorder.cs.meta

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

+ 32 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorderObserver.cs

@@ -0,0 +1,32 @@
+namespace Agora.Rtc
+{
+    ///
+    /// <summary>
+    /// The IMediaRecorderObserver class.
+    /// </summary>
+    ///
+    public abstract class IMediaRecorderObserver
+    {
+        ///
+        /// <summary>
+        /// Occurs when the recording state changes.
+        /// When the local audio or video recording state changes, the SDK triggers this callback to report the current recording state and the reason for the change.
+        /// </summary>
+        ///
+        /// <param name="state"> The current recording state. See RecorderState .</param>
+        ///
+        /// <param name="error"> The reason for the state change. See RecorderErrorCode .</param>
+        ///
+        public virtual void OnRecorderStateChanged(RecorderState state, RecorderErrorCode error) {}
+
+        ///
+        /// <summary>
+        /// Occurs when the recording information is updated.
+        /// After you successfully enable the local audio and video recording, the SDK periodically triggers this callback based on the value of recorderInfoUpdateInterval set in MediaRecorderConfiguration . This callback reports the file name, duration, and size of the current recording file.
+        /// </summary>
+        ///
+        /// <param name="info"> The information about the file that is recorded. See RecorderInfo .</param>
+        ///
+        public virtual void OnRecorderInfoUpdated(RecorderInfo info) {}
+    };
+}

+ 11 - 0
Assets/Remote30/Agora-RTC-Plugin/Agora-Unity-RTC-SDK/Code/IMediaRecorderObserver.cs.meta

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

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