Compare commits

..

No commits in common. "7a000ac9e22b2f8ef18594cd76de46f851e612a4" and "15db99b032ea0af63efd115ebc4ccbbfb972d6a8" have entirely different histories.

12 changed files with 203 additions and 721 deletions

View File

@ -2,5 +2,6 @@
} }
.expandable { .expandable {
flex-grow: 1;
white-space: normal; white-space: normal;
} }

View File

@ -1,10 +1,11 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/_Client/GUI/Main.uss?fileID=7433441132597879392&amp;guid=fe550b4c3daa62b448a38ddf615910a6&amp;type=3#Main" /> <Style src="project://database/Assets/_Client/GUI/Main.uss?fileID=7433441132597879392&amp;guid=fe550b4c3daa62b448a38ddf615910a6&amp;type=3#Main" />
<ui:VisualElement name="VE_Panel" style="flex-grow: 1;"> <ui:VisualElement name="VE_Panel" style="flex-grow: 1;">
<ui:Button text="Falar..." name="B_Talk" /> <ui:Button text="Iniciar sessão" name="B_Session" />
<ui:Label text="Chat:" />
<ui:TextField placeholder-text="Digite sua mensagem" name="TF_ChatInput" class="expandable" />
<ui:Button text="Enviar mensagem" name="B_SendChat" />
<ui:ProgressBar value="0" title="Processando... Por favor, espere..." name="PB_Progress" enabled="true" /> <ui:ProgressBar value="0" title="Processando... Por favor, espere..." name="PB_Progress" enabled="true" />
<ui:ScrollView> <ui:TextField placeholder-text="response" multiline="true" readonly="true" name="TF_ChatOutput" class="expandable" />
<ui:TextField placeholder-text="response" multiline="true" readonly="true" name="TF_Dialogue" class="expandable" />
</ui:ScrollView>
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@ -1,6 +1,6 @@
%YAML 1.1 %YAML 1.1
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!1 &164669483031671566 --- !u!1 &3050228793350555746
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -8,32 +8,84 @@ GameObject:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 7970807069023951264} - component: {fileID: 3228149243574310962}
- component: {fileID: 5034104198302478614}
- component: {fileID: 2870540532630303239}
- component: {fileID: 3085863286867829983}
m_Layer: 0 m_Layer: 0
m_Name: -- Audio Manager -- m_Name: -- GAME MANAGER --
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 1
--- !u!4 &7970807069023951264 --- !u!4 &3228149243574310962
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 164669483031671566} m_GameObject: {fileID: 3050228793350555746}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children:
- {fileID: 7625920793580372814}
- {fileID: 8663494998515940154} - {fileID: 8663494998515940154}
- {fileID: 4128215114116466198} m_Father: {fileID: 0}
m_Father: {fileID: 3228149243574310962}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1759505303048597376 --- !u!114 &5034104198302478614
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3050228793350555746}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
m_PanelSettings: {fileID: 11400000, guid: 08c29b4a94427e44598b2f1d4bc32893, type: 2}
m_ParentUI: {fileID: 0}
sourceAsset: {fileID: 9197481963319205126, guid: 394ce53ae03aab84c98352e044c8bed4, type: 3}
m_SortingOrder: 0
m_Position: 0
m_WorldSpaceSizeMode: 1
m_WorldSpaceWidth: 1920
m_WorldSpaceHeight: 1080
m_PivotReferenceSize: 0
m_Pivot: 0
m_WorldSpaceCollider: {fileID: 0}
--- !u!114 &2870540532630303239
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3050228793350555746}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 177140e4f5a62c145a88b74bb8f02f59, type: 3}
m_Name:
m_EditorClassIdentifier: PpgiaX540P3::PPGIA.X540.Project3.UIController
--- !u!114 &3085863286867829983
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3050228793350555746}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7a1ca38af0a96524893a60d620fa5791, type: 3}
m_Name:
m_EditorClassIdentifier: PpgiaX540P3::PPGIA.X540.Project3.AppManager
_uiController: {fileID: 2870540532630303239}
_apiManager: {fileID: 4693018637014637836}
--- !u!1 &4601626619299515270
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -41,46 +93,47 @@ GameObject:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 4128215114116466198} - component: {fileID: 7625920793580372814}
- component: {fileID: 7584847903250953468} - component: {fileID: 1118623755729130604}
- component: {fileID: 4693018637014637836}
m_Layer: 0 m_Layer: 0
m_Name: Audio Output m_Name: -- API Manager --
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 1
--- !u!4 &4128215114116466198 --- !u!4 &7625920793580372814
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1759505303048597376} m_GameObject: {fileID: 4601626619299515270}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 7970807069023951264} m_Father: {fileID: 3228149243574310962}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!82 &7584847903250953468 --- !u!82 &1118623755729130604
AudioSource: AudioSource:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1759505303048597376} m_GameObject: {fileID: 4601626619299515270}
m_Enabled: 1 m_Enabled: 1
serializedVersion: 4 serializedVersion: 4
OutputAudioMixerGroup: {fileID: 4597973050289367049, guid: b4346293b16e5254aadce52e891ff5e9, type: 2} OutputAudioMixerGroup: {fileID: 4597973050289367049, guid: b4346293b16e5254aadce52e891ff5e9, type: 2}
m_audioClip: {fileID: 0} m_audioClip: {fileID: 0}
m_Resource: {fileID: 0} m_Resource: {fileID: 8300000, guid: 6613d523ef2496349a24abd07925f85a, type: 3}
m_PlayOnAwake: 0 m_PlayOnAwake: 0
m_Volume: 1 m_Volume: 1
m_Pitch: 1 m_Pitch: 1
Loop: 0 Loop: 1
Mute: 0 Mute: 0
Spatialize: 0 Spatialize: 0
SpatializePostEffects: 0 SpatializePostEffects: 0
@ -162,88 +215,6 @@ AudioSource:
m_PreInfinity: 2 m_PreInfinity: 2
m_PostInfinity: 2 m_PostInfinity: 2
m_RotationOrder: 4 m_RotationOrder: 4
--- !u!1 &3050228793350555746
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3228149243574310962}
- component: {fileID: 3085863286867829983}
m_Layer: 0
m_Name: -- GAME MANAGER --
m_TagString: GameController
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3228149243574310962
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3050228793350555746}
serializedVersion: 2
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: 7625920793580372814}
- {fileID: 7970807069023951264}
- {fileID: 5087449153445061889}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &3085863286867829983
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3050228793350555746}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7a1ca38af0a96524893a60d620fa5791, type: 3}
m_Name:
m_EditorClassIdentifier: PpgiaX540P3::PPGIA.X540.Project3.AppManager
_uiController: {fileID: 3705417928890449656}
_apiManager: {fileID: 4693018637014637836}
_audioCapture: {fileID: 1938294408165125026}
--- !u!1 &4601626619299515270
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7625920793580372814}
- component: {fileID: 4693018637014637836}
m_Layer: 0
m_Name: -- API Manager --
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7625920793580372814
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4601626619299515270}
serializedVersion: 2
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: 3228149243574310962}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &4693018637014637836 --- !u!114 &4693018637014637836
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -264,16 +235,14 @@ MonoBehaviour:
_chatEndpoint: /chat/ _chatEndpoint: /chat/
_llmAgentEndpoint: /agent/ask _llmAgentEndpoint: /agent/ask
_ttsEndpoint: /tts/synthesize _ttsEndpoint: /tts/synthesize
_sttUploadEndpoint: /transcript/get-upload-url _sttEndpoint: /stt/upload
_sttStartEndpoint: /transcript/start
_sttDownloadEndpoint: /transcript/download
_clientId: unity-client _clientId: unity-client
_timeoutInSeconds: 10 _timeoutInSeconds: 10
_query: "Ah, guru! Como \xE9 bom poder contar com suas orienta\xE7\xF5es!" _query: "Ah, guru! Como \xE9 bom poder contar com suas orienta\xE7\xF5es!"
_session: _session:
session_id: 9686ca2a-302a-4ac8-8709-a98067d37530 session_id: 9686ca2a-302a-4ac8-8709-a98067d37530
created_at: 1763908462 created_at: 1763908462
_audioSource: {fileID: 7584847903250953468} _audioSource: {fileID: 1118623755729130604}
--- !u!1 &5836695571582163658 --- !u!1 &5836695571582163658
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -283,10 +252,10 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 8663494998515940154} - component: {fileID: 8663494998515940154}
- component: {fileID: 796320736253214861}
- component: {fileID: 1938294408165125026} - component: {fileID: 1938294408165125026}
- component: {fileID: 796320736253214861}
m_Layer: 0 m_Layer: 0
m_Name: Audio Input m_Name: -- AudioManager --
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -305,8 +274,22 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 7970807069023951264} m_Father: {fileID: 3228149243574310962}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1938294408165125026
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5836695571582163658}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9523fc2f4430eb549ab3da789eaf70c1, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PPGIA.X540.Project3.AudioCapture
_sampleRateInHz: 16000
_playingBack: 0
--- !u!82 &796320736253214861 --- !u!82 &796320736253214861
AudioSource: AudioSource:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -316,7 +299,7 @@ AudioSource:
m_GameObject: {fileID: 5836695571582163658} m_GameObject: {fileID: 5836695571582163658}
m_Enabled: 1 m_Enabled: 1
serializedVersion: 4 serializedVersion: 4
OutputAudioMixerGroup: {fileID: -7600268988427216071, guid: b4346293b16e5254aadce52e891ff5e9, type: 2} OutputAudioMixerGroup: {fileID: 4597973050289367049, guid: b4346293b16e5254aadce52e891ff5e9, type: 2}
m_audioClip: {fileID: 0} m_audioClip: {fileID: 0}
m_Resource: {fileID: 0} m_Resource: {fileID: 0}
m_PlayOnAwake: 1 m_PlayOnAwake: 1
@ -404,91 +387,3 @@ AudioSource:
m_PreInfinity: 2 m_PreInfinity: 2
m_PostInfinity: 2 m_PostInfinity: 2
m_RotationOrder: 4 m_RotationOrder: 4
--- !u!114 &1938294408165125026
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5836695571582163658}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9523fc2f4430eb549ab3da789eaf70c1, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PPGIA.X540.Project3.AudioCapture
_sampleRateInHz: 16000
_maxRecordingSeconds: 300
_fileName: RecordedAudio.wav
_playbackVolume: 1
_enableMonitoring: 0
_monitorLatencyMs: 80
_microphones: []
_selectedMicrophoneIndex: 0
--- !u!1 &7800601072168794597
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5087449153445061889}
- component: {fileID: 1529497273491449657}
- component: {fileID: 3705417928890449656}
m_Layer: 0
m_Name: -- UI Manager --
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5087449153445061889
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7800601072168794597}
serializedVersion: 2
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: 3228149243574310962}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1529497273491449657
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7800601072168794597}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
m_PanelSettings: {fileID: 11400000, guid: 08c29b4a94427e44598b2f1d4bc32893, type: 2}
m_ParentUI: {fileID: 0}
sourceAsset: {fileID: 9197481963319205126, guid: 394ce53ae03aab84c98352e044c8bed4, type: 3}
m_SortingOrder: 0
m_Position: 0
m_WorldSpaceSizeMode: 1
m_WorldSpaceWidth: 1920
m_WorldSpaceHeight: 1080
m_PivotReferenceSize: 0
m_Pivot: 0
m_WorldSpaceCollider: {fileID: 0}
--- !u!114 &3705417928890449656
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7800601072168794597}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 177140e4f5a62c145a88b74bb8f02f59, type: 3}
m_Name:
m_EditorClassIdentifier: PpgiaX540P3::PPGIA.X540.Project3.UIController

View File

@ -440,9 +440,21 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 0} m_TransformParent: {fileID: 0}
m_Modifications: m_Modifications:
- target: {fileID: 796320736253214861, guid: 004ea84725223334994cf72d2115c180, type: 3}
propertyPath: OutputAudioMixerGroup
value:
objectReference: {fileID: -7600268988427216071, guid: b4346293b16e5254aadce52e891ff5e9, type: 2}
- target: {fileID: 1938294408165125026, guid: 004ea84725223334994cf72d2115c180, type: 3}
propertyPath: _fileName
value: RecordedAudio.wav
objectReference: {fileID: 0}
- target: {fileID: 1938294408165125026, guid: 004ea84725223334994cf72d2115c180, type: 3}
propertyPath: _selectedMicrophoneIndex
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3050228793350555746, guid: 004ea84725223334994cf72d2115c180, type: 3} - target: {fileID: 3050228793350555746, guid: 004ea84725223334994cf72d2115c180, type: 3}
propertyPath: m_Name propertyPath: m_Name
value: -- APP MANAGER -- value: -- GAME MANAGER --
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 3228149243574310962, guid: 004ea84725223334994cf72d2115c180, type: 3} - target: {fileID: 3228149243574310962, guid: 004ea84725223334994cf72d2115c180, type: 3}
propertyPath: m_LocalPosition.x propertyPath: m_LocalPosition.x

View File

@ -1,6 +1,6 @@
using System; using System;
using System.IO;
using System.Collections; using System.Collections;
using System.IO;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
@ -56,6 +56,12 @@ namespace PPGIA.X540.Project3.API
request.downloadHandler = new DownloadHandlerBuffer(); request.downloadHandler = new DownloadHandlerBuffer();
// Debug.Log($"Sending {method} request to {url}");
// Debug.Log(
// payload != null ?
// $"Payload: {JsonUtility.ToJson(payload)}" :
// "No payload.");
var op = request.SendWebRequest(); var op = request.SendWebRequest();
yield return WaitForTimeout(op, timeoutInSeconds, () => yield return WaitForTimeout(op, timeoutInSeconds, () =>
{ {
@ -111,170 +117,6 @@ Response Body: {body}";
url, "DELETE", null, timeoutInSeconds, callbackOnSuccess); url, "DELETE", null, timeoutInSeconds, callbackOnSuccess);
} }
internal static IEnumerator UploadAudioDataCoroutine(
string url,
string filePath,
float timeoutInSeconds,
Action<UnityWebRequest> callbackOnSuccess)
{
// PUT the audio data as binary
byte[] audioData = File.ReadAllBytes(filePath);
string fileName = Path.GetFileName(filePath);
using (UnityWebRequest request = UnityWebRequest.Put(url, audioData))
{
request.SetRequestHeader("Content-Type", "audio/wav");
var op = request.SendWebRequest();
yield return WaitForTimeout(op, timeoutInSeconds, () =>
{
Debug.LogError("Request timed out.");
});
if (request.result == UnityWebRequest.Result.Success)
{
callbackOnSuccess?.Invoke(request);
}
else
{
var body = request.downloadHandler?.text ?? string.Empty;
Debug.LogError($"Failed to upload audio data: {request.error} (HTTP {request.responseCode})\nBody: {body}");
}
}
}
internal static IEnumerator UploadAudioCoroutine(
string url,
AudioClip audioClip,
float timeoutInSeconds,
Action<UnityWebRequest> callbackOnSuccess)
{
// Convert AudioClip to WAV (PCM 16-bit little endian) without external utility.
byte[] audioData = AudioClipToWavBytes(audioClip);
string fileName = $"{audioClip.name}.wav";
string fieldName = "file";
yield return UploadFileCoroutine(
url, audioData, fileName, fieldName, timeoutInSeconds, callbackOnSuccess);
}
// Writes a WAV file header + PCM 16-bit data for the provided AudioClip.
// Supports mono or multi-channel clips. Assumes clip.samples * channels fits in int32.
private static byte[] AudioClipToWavBytes(AudioClip clip)
{
if (clip == null)
{
Debug.LogError("AudioClipToWavBytes: clip is null");
return Array.Empty<byte>();
}
int channels = clip.channels;
int sampleCount = clip.samples * channels; // total samples across channels
int sampleRate = clip.frequency;
// Get float data
float[] floatData = new float[sampleCount];
clip.GetData(floatData, 0);
// Convert to 16-bit PCM
// Each sample -> 2 bytes
byte[] pcmData = new byte[sampleCount * 2];
int pcmIndex = 0;
for (int i = 0; i < sampleCount; i++)
{
// Clamp just in case
float f = Mathf.Clamp(floatData[i], -1f, 1f);
short s = (short)Mathf.RoundToInt(f * 32767f);
pcmData[pcmIndex++] = (byte)(s & 0xFF); // little endian
pcmData[pcmIndex++] = (byte)((s >> 8) & 0xFF);
}
// WAV header size is 44 bytes
int headerSize = 44;
int fileSize = headerSize + pcmData.Length;
byte[] wav = new byte[fileSize];
// Helper local to write int/short little endian
void WriteInt32LE(int offset, int value)
{
wav[offset] = (byte)(value & 0xFF);
wav[offset + 1] = (byte)((value >> 8) & 0xFF);
wav[offset + 2] = (byte)((value >> 16) & 0xFF);
wav[offset + 3] = (byte)((value >> 24) & 0xFF);
}
void WriteInt16LE(int offset, short value)
{
wav[offset] = (byte)(value & 0xFF);
wav[offset + 1] = (byte)((value >> 8) & 0xFF);
}
// ChunkID "RIFF"
wav[0] = (byte)'R'; wav[1] = (byte)'I'; wav[2] = (byte)'F'; wav[3] = (byte)'F';
// ChunkSize = 36 + Subchunk2Size
int subchunk2Size = pcmData.Length; // NumSamples * NumChannels * BitsPerSample/8
WriteInt32LE(4, 36 + subchunk2Size);
// Format "WAVE"
wav[8] = (byte)'W'; wav[9] = (byte)'A'; wav[10] = (byte)'V'; wav[11] = (byte)'E';
// Subchunk1ID "fmt "
wav[12] = (byte)'f'; wav[13] = (byte)'m'; wav[14] = (byte)'t'; wav[15] = (byte)' ';
// Subchunk1Size (16 for PCM)
WriteInt32LE(16, 16);
// AudioFormat (1 = PCM)
WriteInt16LE(20, 1);
// NumChannels
WriteInt16LE(22, (short)channels);
// SampleRate
WriteInt32LE(24, sampleRate);
// ByteRate = SampleRate * NumChannels * BitsPerSample/8
int byteRate = sampleRate * channels * 2;
WriteInt32LE(28, byteRate);
// BlockAlign = NumChannels * BitsPerSample/8
WriteInt16LE(32, (short)(channels * 2));
// BitsPerSample
WriteInt16LE(34, 16);
// Subchunk2ID "data"
wav[36] = (byte)'d'; wav[37] = (byte)'a'; wav[38] = (byte)'t'; wav[39] = (byte)'a';
// Subchunk2Size
WriteInt32LE(40, subchunk2Size);
// Copy PCM data after header
Buffer.BlockCopy(pcmData, 0, wav, headerSize, pcmData.Length);
return wav;
}
internal static IEnumerator UploadFileCoroutine(
string url,
byte[] fileData,
string fileName,
string fieldName,
float timeoutInSeconds,
Action<UnityWebRequest> callbackOnSuccess)
{
WWWForm form = new WWWForm();
form.AddBinaryData(fieldName, fileData, fileName);
using (UnityWebRequest request =
UnityWebRequest.Post(url, form))
{
var op = request.SendWebRequest();
yield return WaitForTimeout(op, timeoutInSeconds, () =>
{
Debug.LogError("Request timed out.");
});
if (request.result == UnityWebRequest.Result.Success)
{
callbackOnSuccess?.Invoke(request);
}
else
{
Debug.LogError(
$"Error uploading file: {request.error}");
}
}
}
internal static IEnumerator DownloadAudioCoroutine( internal static IEnumerator DownloadAudioCoroutine(
string url, string url,
float timeoutInSeconds, float timeoutInSeconds,

View File

@ -1,5 +1,4 @@
using System; using System;
using System.IO;
using System.Collections; using System.Collections;
using System.Linq; using System.Linq;
@ -8,6 +7,7 @@ using UnityEngine;
namespace PPGIA.X540.Project3.API namespace PPGIA.X540.Project3.API
{ {
[RequireComponent(typeof(AudioSource))]
public class ApiClientManager : MonoBehaviour public class ApiClientManager : MonoBehaviour
{ {
#region -- Inspector Fields ------------------------------------------- #region -- Inspector Fields -------------------------------------------
@ -29,7 +29,7 @@ namespace PPGIA.X540.Project3.API
private string _sessionCloseEndpoint = "/session/close"; private string _sessionCloseEndpoint = "/session/close";
[SerializeField] [SerializeField]
private string _chatEndpoint = "/chat"; private string _chatEndpoint = "/chat/";
[SerializeField] [SerializeField]
private string _llmAgentEndpoint = "/agent/ask"; private string _llmAgentEndpoint = "/agent/ask";
@ -38,13 +38,7 @@ namespace PPGIA.X540.Project3.API
private string _ttsEndpoint = "/tts/synthesize"; private string _ttsEndpoint = "/tts/synthesize";
[SerializeField] [SerializeField]
private string _sttUploadEndpoint = "/transcript/get-upload-url"; private string _sttEndpoint = "/stt/upload";
[SerializeField]
private string _sttStartEndpoint = "/transcript/start";
[SerializeField]
private string _sttDownloadEndpoint = "/transcript/download";
[Header("API Settings & Workload")] [Header("API Settings & Workload")]
[SerializeField] [SerializeField]
@ -79,10 +73,7 @@ namespace PPGIA.X540.Project3.API
void Awake() void Awake()
{ {
if (_audioSource == null)
_audioSource = GetComponent<AudioSource>(); _audioSource = GetComponent<AudioSource>();
if (_audioSource == null)
Debug.LogWarning("AudioSource component is missing.");
} }
#region -- API Calls -------------------------------------------------- #region -- API Calls --------------------------------------------------
@ -140,135 +131,6 @@ namespace PPGIA.X540.Project3.API
})); }));
} }
public void UploadAudioClip(
string localFilePath, Action<string> uploadCompletedCallback = null)
{
if (_session == null)
{
Debug.LogWarning("No active session. Please initiate a session first.");
return;
}
StopAllCoroutines();
var url = EndpointUrl(_sttUploadEndpoint, _session.SessionId);
var payload = new
{
filename = Path.GetFileName(localFilePath),
content_type = "audio/wav"
};
StartCoroutine(ApiClient.CallEndpointWithPostCoroutine(
url, _timeoutInSeconds, payload, (request) =>
{
var body = request.downloadHandler?.text ?? string.Empty;
var uploadUrl = JsonUtility.FromJson<STTUploadResponse>(body)?.UploadUrl;
var s3Key = JsonUtility.FromJson<STTUploadResponse>(body)?.S3Key;
if (uploadUrl == null)
{
Debug.LogWarning("Failed to get upload URL.");
return;
}
StartCoroutine(ApiClient.UploadAudioDataCoroutine(
uploadUrl, localFilePath, _timeoutInSeconds, (uploadRequest) =>
{
Debug.Log($"Audio upload complete: {uploadRequest.responseCode}");
uploadCompletedCallback?.Invoke(s3Key);
}));
}));
}
[ContextMenu("STT/Upload Audio Clip")]
public void StartTranscript(string s3Key,
Action<string> transcriptStartedCallback = null)
{
// Ensure there is an active session
if (_session == null)
{
Debug.LogWarning("No active session. Please initiate a session first.");
return;
}
if (string.IsNullOrEmpty(s3Key))
{
Debug.LogWarning("No file path provided for upload.");
return;
}
StopAllCoroutines();
// Build the endpoint URL
var url = EndpointUrl(_sttStartEndpoint);
var payload = new STTUploadResponse {
s3_key = s3Key
};
// Make the API call to upload the audio clip
StartCoroutine(ApiClient.CallEndpointWithPostCoroutine(
url, _timeoutInSeconds, payload, (request) =>
{
var body = request.downloadHandler?.text ?? string.Empty;
var response = ApiModel.FromJson<STTJobResponse>(body);
var jobName = response?.JobName;
Debug.Log($"Transcription job started: {jobName}");
transcriptStartedCallback?.Invoke(jobName);
}));
}
[ContextMenu("STT/Download Transcription")]
public void DownloadTranscription(string jobName,
Action<string> transcriptionReceivedCallback = null)
{
// Ensure there is an active session
if (_session == null)
{
Debug.LogWarning("No active session. Please initiate a session first.");
return;
}
StopAllCoroutines();
StartCoroutine(KeepCallingCoroutine(
EndpointUrl(_sttDownloadEndpoint, jobName), .5f,
transcriptionReceivedCallback
));
}
private IEnumerator KeepCallingCoroutine(string url,
float delayInSeconds, Action<string> callback)
{
// Make the API call to download the transcription
var wait = new WaitForSeconds(delayInSeconds);
bool keepCalling = true;
while (keepCalling)
{
yield return wait;
yield return ApiClient.CallEndpointWithGetCoroutine(
url, _timeoutInSeconds, (request) =>
{
var body = request.downloadHandler?.text ?? string.Empty;
var response = ApiModel.FromJson<STTJobResponse>(body);
if (response.Status == "FAILED")
{
keepCalling = false;
Debug.LogError("Transcription job failed.");
callback?.Invoke(null);
}
else if (response.Status == "COMPLETED")
{
keepCalling = false;
callback?.Invoke(response?.Transcript);
}
});
}
}
[ContextMenu("Chat/Send Message")] [ContextMenu("Chat/Send Message")]
public void SendChatMessage(string message = null, public void SendChatMessage(string message = null,
Action<string> responseReceivedCallback = null, Action<string> responseReceivedCallback = null,

View File

@ -48,30 +48,6 @@ namespace PPGIA.X540.Project3.API
public int ExpiresIn => expires_in; public int ExpiresIn => expires_in;
} }
[Serializable]
public class STTUploadResponse : ApiModel
{
public string upload_url;
public string s3_key;
public string UploadUrl => upload_url;
public string S3Key => s3_key;
}
[Serializable]
public class STTJobResponse : ApiModel
{
public string job_name;
public string s3_uri;
public string status;
public string transcript;
public string JobName => job_name;
public string S3Uri => s3_uri;
public string Status => status;
public string Transcript => transcript;
}
internal enum Environment internal enum Environment
{ {
Development, Development,

View File

@ -18,7 +18,6 @@ namespace PPGIA.X540.Project3
Hz96000 = 96000 Hz96000 = 96000
} }
#region -- Fields & Properties ----------------------------------------
[Header("Audio Capture Settings")] [Header("Audio Capture Settings")]
[SerializeField] [SerializeField]
private SampleRate _sampleRateInHz = SampleRate.Hz44100; private SampleRate _sampleRateInHz = SampleRate.Hz44100;
@ -55,14 +54,9 @@ namespace PPGIA.X540.Project3
private List<short> _capturedSamples = private List<short> _capturedSamples =
new List<short>(1024 * 32); // filled only on Stop new List<short>(1024 * 32); // filled only on Stop
private int _channels = 1; // microphone channel count (Unity usually mono) private int _channels = 1; // microphone channel count (Unity usually mono)
private AudioClip _recordingClip; private AudioClip _recordingClip;
public AudioClip GetRecordedClip() => _recordingClip;
private string _currentDevice; private string _currentDevice;
#endregion ------------------------------------------------------------
#region -- MonoBehaviour Methods --------------------------------------
private void Awake() private void Awake()
{ {
_audioSource = GetComponent<AudioSource>(); _audioSource = GetComponent<AudioSource>();
@ -73,7 +67,6 @@ namespace PPGIA.X540.Project3
{ {
StopRecording(); StopRecording();
} }
#endregion ------------------------------------------------------------
[ContextMenu("Start recording audio")] [ContextMenu("Start recording audio")]
public void StartRecording() public void StartRecording()
@ -222,6 +215,7 @@ namespace PPGIA.X540.Project3
writer.Write(dataBytes); writer.Write(dataBytes);
} }
LastSavedFilePath = filePath; LastSavedFilePath = filePath;
Debug.Log($"Audio saved to: {filePath}");
OnRecordingSaved?.Invoke(filePath); OnRecordingSaved?.Invoke(filePath);
} }
catch (Exception ex) catch (Exception ex)

View File

@ -7,10 +7,6 @@ namespace PPGIA.X540.Project3
{ {
public class AppManager : MonoBehaviour public class AppManager : MonoBehaviour
{ {
// Singleton instance
public static AppManager Instance { get; private set; }
#region -- Fields & Properties ----------------------------------------
[Header("References")] [Header("References")]
[SerializeField] [SerializeField]
private UIController _uiController; private UIController _uiController;
@ -18,129 +14,59 @@ namespace PPGIA.X540.Project3
[SerializeField] [SerializeField]
private ApiClientManager _apiManager; private ApiClientManager _apiManager;
[SerializeField]
private AudioCapture _audioCapture;
private AudioClip _recordedClip;
#endregion ------------------------------------------------------------
#region -- MonoBehaviour Methods --------------------------------------
private void Awake() private void Awake()
{ {
// Singleton pattern implementation
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
return;
}
if (_uiController == null) if (_uiController == null)
{ _uiController = GetComponent<UIController>();
Debug.LogError("UIController reference is missing in AppManager.");
}
if (_apiManager == null) if (_apiManager == null)
{ _apiManager = GetComponent<ApiClientManager>();
Debug.LogError("ApiClientManager reference is missing in AppManager.");
}
if (_audioCapture == null)
{
Debug.LogError("AudioCapture reference is missing in AppManager.");
} }
_uiController.OnTalkButtonClicked += HandleTalkButtonClicked; void Start()
_audioCapture.OnRecordingSaved += HandleClipSaved; {
_apiManager.CloseSession(
() => _uiController.SessionActive = _apiManager.IsSessionActive);
} }
private void OnEnable() private void OnEnable()
{ {
_apiManager.InitiateSession(() => _uiController.OnSessionButtonClicked += HandleSessionButtonClicked;
{ _uiController.OnSendChatButtonClicked += HandleSendChatButtonClicked;
Debug.Log("API session initiated successfully.");
});
} }
void OnDisable() private void OnDisable()
{ {
if (_apiManager != null && _apiManager.IsSessionActive) _uiController.OnSessionButtonClicked -= HandleSessionButtonClicked;
{ _uiController.OnSendChatButtonClicked -= HandleSendChatButtonClicked;
_apiManager.CloseSession(() =>
{
Debug.Log("API session closed successfully.");
});
}
} }
private void OnDestroy() private void HandleSessionButtonClicked()
{
_uiController.OnTalkButtonClicked -= HandleTalkButtonClicked;
_audioCapture.OnRecordingSaved -= HandleClipSaved;
}
#endregion ------------------------------------------------------------
private void HandleClipSaved(string filePath)
{
Debug.Log($"Audio clip saved at: {filePath}");
_apiManager.UploadAudioClip(
filePath,
(s3Key) =>
{
Debug.Log($"Clip uploaded to: {s3Key}");
_apiManager.StartTranscript(
s3Key,
(jobName) =>
{
Debug.Log($"Transcription job started: {jobName}");
_apiManager.DownloadTranscription(jobName, (transcript) =>
{
Debug.Log($"Transcription completed: {transcript}");
_uiController.AppendChatOutput($"\nUser: {transcript}\n");
_apiManager.SendChatMessage(transcript,
(response) =>
{
_uiController.AppendChatOutput($"Bot: {response}\n");
}, () =>
{
// Speech synthesis finished.
});
});
});
});
_uiController.CurrentState = UIController.UIState.Idle;
}
private void HandleTalkButtonClicked()
{ {
if (!_apiManager.IsSessionActive) if (!_apiManager.IsSessionActive)
{ {
Debug.LogWarning("Session is not active. Cannot send message."); _apiManager.InitiateSession(
return; () => _uiController.SessionActive = _apiManager.IsSessionActive);
} }
else
switch (_uiController.CurrentState)
{ {
case UIController.UIState.Idle: _apiManager.CloseSession(
_audioCapture.StartRecording(); () => _uiController.SessionActive = _apiManager.IsSessionActive
_uiController.CurrentState = UIController.UIState.Recording; );
break;
case UIController.UIState.Recording:
_audioCapture.StopRecording();
_uiController.CurrentState = UIController.UIState.Idle;
break;
case UIController.UIState.Processing:
Debug.Log("Currently processing. Please wait.");
break;
} }
} }
private void HandleSendChatButtonClicked(string message)
{
_apiManager.SendChatMessage(message,
(responseMessage) =>
{
_uiController.ChatOutput += $"User: {message}\n";
_uiController.ChatOutput += $"Bot: {responseMessage}\n";
},
() =>
{
// Speech finished callback (optional)
});
}
} }
} }

View File

@ -6,113 +6,86 @@ using UnityEngine.UIElements;
namespace PPGIA.X540.Project3 namespace PPGIA.X540.Project3
{ {
[RequireComponent(typeof(UIDocument))] [RequireComponent(typeof(UIController))]
public class UIController : MonoBehaviour public class UIController : MonoBehaviour
{ {
public enum UIState
{
Idle = 0,
Recording = 1,
Processing = 2
}
private UIDocument _uiDocument; private UIDocument _uiDocument;
private VisualElement _root; private VisualElement _root;
#region -- Fields & Properties ---------------------------------------- private readonly string[] _sessionButtonLabels = {
private readonly string[] _sendChatButtonLabels = { "Iniciar Sessão",
"Falar...", "Encerrar Sessão"
"Enviar...",
"Processando... Aguarde..."
}; };
private Button _sessionButton;
private Button _sendChatButton;
private int _currentSessionState = 0;
// UI controls -------------------------------------------------------- private TextField _chatInputField;
private Button _talkButton;
private TextField _chatOutputField; private TextField _chatOutputField;
public string ChatOutput public string ChatOutput
{ {
get => _chatOutputField.value; get => _chatOutputField.value;
set => _chatOutputField.value = value; set => _chatOutputField.value = value;
} }
private ProgressBar _progressBar; public bool SessionActive {
public float Progress get => _currentSessionState == 1;
{
get => _progressBar.value;
set => _progressBar.value = value;
}
// State management ---------------------------------------------------
private UIState _currentState = UIState.Idle;
public UIState CurrentState
{
get => _currentState;
set set
{ {
_currentState = value; _currentSessionState = value ? 1 : 0;
_talkButton.text = _sendChatButtonLabels[(int)value]; UpdateStateForSession();
if (value == UIState.Processing)
{
_talkButton.SetEnabled(false);
_progressBar.value = 0.5f;
}
else
{
_talkButton.SetEnabled(true);
_progressBar.value = 0f;
}
} }
} }
// Event Handlers ----------------------------------------------------- public Action OnSessionButtonClicked { get; set; }
public event Action OnTalkButtonClicked; public Action<string> OnSendChatButtonClicked { get; set; }
public float Progress { get; set; }
#endregion ------------------------------------------------------------
#region -- MonoBehaviour Methods --------------------------------------
private void Awake() private void Awake()
{ {
_uiDocument = GetComponent<UIDocument>(); _uiDocument = GetComponent<UIDocument>();
_root = _uiDocument.rootVisualElement; _root = _uiDocument.rootVisualElement;
_talkButton = _root.Q<Button>("B_Talk"); _sessionButton = _root.Q<Button>("B_Session");
if (_talkButton == null) _sendChatButton = _root.Q<Button>("B_SendChat");
{ _chatInputField = _root.Q<TextField>("TF_ChatInput");
Debug.LogError("Talk Button not found in UI."); _chatOutputField = _root.Q<TextField>("TF_ChatOutput");
SessionActive = false;
} }
_progressBar = _root.Q<ProgressBar>("PB_Progress"); void OnEnable()
if (_progressBar == null)
{ {
Debug.LogError("Progress Bar not found in UI."); _sessionButton.clicked += OnSessionButtonClickedInternal;
_sendChatButton.clicked += OnSendChatButtonClickedInternal;
} }
_chatOutputField = _root.Q<TextField>("TF_Dialogue"); void OnDisable()
if (_chatOutputField == null)
{ {
Debug.LogError("Chat Output Field not found in UI."); _sessionButton.clicked -= OnSessionButtonClickedInternal;
_sendChatButton.clicked -= OnSendChatButtonClickedInternal;
} }
CurrentState = UIState.Idle; private void UpdateStateForSession()
{
_sessionButton.text = _sessionButtonLabels[_currentSessionState];
var enable = _currentSessionState == 1;
_chatInputField.SetEnabled(enable);
_sendChatButton.SetEnabled(enable);
} }
private void OnEnable() private void OnSessionButtonClickedInternal()
{ {
_talkButton.clicked += OnTalkButtonClickedInternal; OnSessionButtonClicked?.Invoke();
// SessionActive state will be updated externally
} }
private void OnDisable() private void OnSendChatButtonClickedInternal()
{ {
_talkButton.clicked -= OnTalkButtonClickedInternal; OnSendChatButtonClicked?.Invoke(_chatInputField.value);
} _chatInputField.value = string.Empty;
#endregion ------------------------------------------------------------
private void OnTalkButtonClickedInternal() => OnTalkButtonClicked?.Invoke();
public void AppendChatOutput(string newText)
{
ChatOutput += newText;
} }
} }
} }

View File

@ -29,7 +29,7 @@ MonoBehaviour:
m_Match: 0 m_Match: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_TargetDisplay: 0 m_TargetDisplay: 0
m_BindingLogLevel: 2 m_BindingLogLevel: 0
m_ClearDepthStencil: 1 m_ClearDepthStencil: 1
m_ClearColor: 0 m_ClearColor: 0
m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0} m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}