Pārlūkot izejas kodu

0216更新。

添加Login token和快速开始功能。
优化Playground动画。
添加Playground页面跳转功能。
Jees 3 mēneši atpakaļ
vecāks
revīzija
41668fb898
41 mainītis faili ar 1272 papildinājumiem un 264 dzēšanām
  1. 0 22
      Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer 1.terrainlayer
  2. 0 8
      Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer 1.terrainlayer.meta
  3. 0 22
      Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer.terrainlayer
  4. 0 8
      Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer.terrainlayer.meta
  5. 2 2
      Assets/Resources/Data/languages.json
  6. 19 5
      Assets/Resources/VoiceAndManu/MenuController.cs
  7. 51 2
      Assets/Resources/VoiceAndManu/VoiceAndMenu.prefab
  8. 1 1
      Assets/Resources/VoiceAndManu/VoiceAndMenu.uxml
  9. 115 5
      Assets/Resources/VoiceAndManu/VoiceController.cs
  10. 98 0
      Assets/Scenes/Home.unity
  11. 233 11
      Assets/Scenes/Login.unity
  12. 412 69
      Assets/Scenes/Playground.unity
  13. 12 1
      Assets/Scripts/Develop Script/TestSetup.cs
  14. 0 0
      Assets/Scripts/Develop Script/TestSetup.cs.meta
  15. 1 0
      Assets/Scripts/EnviromentController.cs
  16. 11 2
      Assets/Scripts/EnviromentSetting.cs
  17. 8 0
      Assets/Scripts/Functions.meta
  18. 0 0
      Assets/Scripts/Functions/SceneSwitcher.cs
  19. 0 0
      Assets/Scripts/Functions/SceneSwitcher.cs.meta
  20. 76 0
      Assets/Scripts/Functions/WebController.cs
  21. 2 0
      Assets/Scripts/Functions/WebController.cs.meta
  22. 30 0
      Assets/Scripts/Functions/ZipFileController.cs
  23. 2 0
      Assets/Scripts/Functions/ZipFileController.cs.meta
  24. 8 0
      Assets/Scripts/GameControllers.meta
  25. 7 2
      Assets/Scripts/GameControllers/DogInitialize.cs
  26. 0 0
      Assets/Scripts/GameControllers/DogInitialize.cs.meta
  27. 0 0
      Assets/Scripts/GameControllers/DogProperty.cs
  28. 0 0
      Assets/Scripts/GameControllers/DogProperty.cs.meta
  29. 3 2
      Assets/Scripts/GameControllers/UserProperty.cs
  30. 0 0
      Assets/Scripts/GameControllers/UserProperty.cs.meta
  31. 100 0
      Assets/Scripts/Login/LoginController.cs
  32. 0 0
      Assets/Scripts/Login/LoginController.cs.meta
  33. 5 3
      Assets/Scripts/Login/LoginLangController.cs
  34. 0 78
      Assets/Scripts/Login/LoginTokenController.cs
  35. 4 0
      Assets/Scripts/Login/SunMovement.cs
  36. 4 0
      Assets/Scripts/Playground/AirWallDetection.cs
  37. 10 2
      Assets/Scripts/Playground/DogCatchDetection.cs
  38. 43 15
      Assets/Scripts/Playground/PlayToyController.cs
  39. BIN
      Assets/Terrain/LoginTerrain.asset
  40. 4 4
      ProjectSettings/ProjectSettings.asset
  41. 11 0
      app.config

+ 0 - 22
Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer 1.terrainlayer

@@ -1,22 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!1953259897 &8574412962073106934
-TerrainLayer:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_Name: NewLayer 1
-  m_DiffuseTexture: {fileID: 2800000, guid: 4bddad9237c3757428b2c84c57a7117b, type: 3}
-  m_NormalMapTexture: {fileID: 0}
-  m_MaskMapTexture: {fileID: 0}
-  m_TileSize: {x: 2, y: 2}
-  m_TileOffset: {x: 0, y: 0}
-  m_Specular: {r: 0, g: 0, b: 0, a: 0}
-  m_Metallic: 0
-  m_Smoothness: 0
-  m_NormalScale: 1
-  m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0}
-  m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1}
-  m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0}
-  m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1}

+ 0 - 8
Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer 1.terrainlayer.meta

@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: a365029c554b61142a4c1886cd6d8bbc
-NativeFormatImporter:
-  externalObjects: {}
-  mainObjectFileID: 8574412962073106934
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 0 - 22
Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer.terrainlayer

@@ -1,22 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!1953259897 &8574412962073106934
-TerrainLayer:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_Name: NewLayer
-  m_DiffuseTexture: {fileID: 2800000, guid: 7678d9521dbf20a41a27ba6dbe48a619, type: 3}
-  m_NormalMapTexture: {fileID: 0}
-  m_MaskMapTexture: {fileID: 0}
-  m_TileSize: {x: 2, y: 2}
-  m_TileOffset: {x: 0, y: 0}
-  m_Specular: {r: 0, g: 0, b: 0, a: 0}
-  m_Metallic: 0
-  m_Smoothness: 0
-  m_NormalScale: 1
-  m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0}
-  m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1}
-  m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0}
-  m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1}

+ 0 - 8
Assets/Packages/Palmov Island/Low Poly Houses Free Pack/Prefabs/Houses with environment/NewLayer.terrainlayer.meta

@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 1d63538fa7d72f44cb3de74647564e50
-NativeFormatImporter:
-  externalObjects: {}
-  mainObjectFileID: 8574412962073106934
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 2 - 2
Assets/Resources/Data/languages.json

@@ -397,8 +397,8 @@
     "playgroundUI":{
         "button":{
             "confirm":{
-                "en": "Confrim",
-                "zh-cn": "确认"
+                "en": "Go Home",
+                "zh-cn": "回家"
             },
             "play_again":{
                 "en": "Play Again",

+ 19 - 5
Assets/Resources/VoiceAndManu/MenuController.cs

@@ -1,16 +1,20 @@
-using System.Collections;
+ using System.Collections;
 using System.Collections.Generic;
 using Unity.VisualScripting;
 using UnityEngine;
-using UnityEngine.UI;
+using UnityEngine.SceneManagement;
 using UnityEngine.UIElements;
 
+/* 本文件控制游戏右侧的菜单按键逻辑
+ */
+
 public class MenuController : MonoBehaviour
 {
     // Start is called once before the first execution of Update after the MonoBehaviour is created
     private VisualElement mainMenu;
     private List<VisualElement> subMenus = new();
     bool isSubMenuShow = false;
+ 
     void Start()
     {
         var root = GetComponent<UIDocument>().rootVisualElement;
@@ -32,13 +36,16 @@ public class MenuController : MonoBehaviour
         mainMenu.RegisterCallback<ClickEvent>(e => MainMenuClick(e));
         // root加载完成后,所有element算出位置后再进行计算
         root.RegisterCallback<GeometryChangedEvent>(e => OnMainMenuClickGeometryChanged(e));
+
+        // 绑定按键点击事件
+        playground.RegisterCallback<ClickEvent>(e => PlayGroundClick(e));
     }
 
     // Update is called once per frame
-    void Update()
-    {
+    //void Update()
+    //{
         
-    }
+    //}
 
     Vector2 CalcPosition (Vector2 curPosition, float angle, float distance)
     {
@@ -98,4 +105,11 @@ public class MenuController : MonoBehaviour
         mainMenu.transform.scale = new Vector2(1.0f, 1.0f);
         InitialSubMenu();
     }
+
+    void PlayGroundClick(ClickEvent evt)
+    {
+        SceneManager.LoadScene("Playground", LoadSceneMode.Single);
+    }
+
+    
 }

+ 51 - 2
Assets/Resources/VoiceAndManu/VoiceAndMenu.prefab

@@ -10,6 +10,9 @@ GameObject:
   m_Component:
   - component: {fileID: 509118905340469216}
   - component: {fileID: 1349988398253066161}
+  - component: {fileID: 3964713078886633438}
+  - component: {fileID: 2824888340937387283}
+  - component: {fileID: 3982022933525629195}
   m_Layer: 5
   m_Name: UIDocument
   m_TagString: Untagged
@@ -46,11 +49,57 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   m_PanelSettings: {fileID: 11400000, guid: 7ca44f0cc21b574428c09a7b6ce95659, type: 2}
   m_ParentUI: {fileID: 0}
-  sourceAsset: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: 1093b48dd2b012948b6976d49baef305, type: 3}
   m_SortingOrder: 0
   m_WorldSpaceSizeMode: 1
   m_WorldSpaceWidth: 1920
   m_WorldSpaceHeight: 1080
+--- !u!114 &3964713078886633438
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 648218781261652396}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 23aeed6a06c30204b9e1f45d68adbf75, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!114 &2824888340937387283
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 648218781261652396}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0f7f8759cd8317649a1c345f218977fb, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!95 &3982022933525629195
+Animator:
+  serializedVersion: 7
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 648218781261652396}
+  m_Enabled: 1
+  m_Avatar: {fileID: 0}
+  m_Controller: {fileID: 0}
+  m_CullingMode: 0
+  m_UpdateMode: 0
+  m_ApplyRootMotion: 0
+  m_LinearVelocityBlending: 0
+  m_StabilizeFeet: 0
+  m_AnimatePhysics: 0
+  m_WarningMessage: 
+  m_HasTransformHierarchy: 1
+  m_AllowConstantClipSamplingOptimization: 1
+  m_KeepAnimatorStateOnDisable: 0
+  m_WriteDefaultValuesOnDisable: 0
 --- !u!1 &7983087457938491336
 GameObject:
   m_ObjectHideFlags: 0
@@ -152,4 +201,4 @@ MonoBehaviour:
   m_BlockingObjects: 0
   m_BlockingMask:
     serializedVersion: 2
-    m_Bits: 4294967295
+    m_Bits: 23

+ 1 - 1
Assets/Resources/VoiceAndManu/VoiceAndMenu.uxml

@@ -11,7 +11,7 @@
             <ui:VisualElement name="mainMenu" class="subMenu" style="background-image: url(&quot;project://database/Assets/Packages/2D%20Casual%20UI/Sprite/GUI.png?fileID=21300072&amp;guid=1eaee135ce037439d925cee5e41ce026&amp;type=3#GUI_36&quot;); width: 26%; height: 26%; position: absolute; top: 52px; left: 85px; bottom: auto;" />
         </ui:VisualElement>
         <ui:VisualElement name="voiceArea" style="flex-grow: 1; position: absolute; bottom: 2%; flex-direction: column; justify-content: space-around; align-items: center; align-content: flex-start; width: 100%;">
-            <ui:VisualElement name="waveForm" style="flex-grow: initial; background-image: url(&quot;project://database/Assets/Pictures/waveform.png?fileID=711615006&amp;guid=743c12517ce3fef47a5c8b2f1a26f4ac&amp;type=3#waveform_0&quot;); width: 95%; height: 30px; flex-shrink: initial; -unity-background-image-tint-color: rgba(255, 255, 255, 0.74);" />
+            <ui:VisualElement name="waveForm" style="flex-grow: initial; background-image: url(&quot;project://database/Assets/Pictures/waveform.png?fileID=711615006&amp;guid=743c12517ce3fef47a5c8b2f1a26f4ac&amp;type=3#waveform_0&quot;); width: 95%; height: 30px; flex-shrink: initial; -unity-background-image-tint-color: rgba(255, 255, 255, 0.74); visibility: hidden;" />
             <ui:Button name="voice" style="background-image: url(&quot;project://database/Assets/Pictures/speaker.png?fileID=-1526337199&amp;guid=e472be41a1391b94482678153c3e5f4b&amp;type=3#speaker_6&quot;); width: 100px; height: 50px; background-color: rgba(188, 188, 188, 0); background-size: 75% 75%; border-top-width: 0; border-bottom-width: 0; border-left-width: 0; border-right-width: 0;" />
         </ui:VisualElement>
     </ui:VisualElement>

+ 115 - 5
Assets/Resources/VoiceAndManu/VoiceController.cs

@@ -1,14 +1,23 @@
 using System;
 using System.Collections;
+using System.IO;
 using UnityEngine;
 using UnityEngine.UIElements;
 
+using System.Runtime.InteropServices;
+
+
 public class VoiceController : MonoBehaviour
 {
     // Start is called once before the first execution of Update after the MonoBehaviour is created
     private VisualElement waveForm;
     private Button voiceBtn;
     private Coroutine waveCoroutine;
+    private AudioClip audioClip;    // 保存的音频
+    private bool isRecording = false;
+    private string filePathWav, filePathZip; 
+
+
     void Start()
     {
         var root = GetComponent<UIDocument>().rootVisualElement;
@@ -18,15 +27,17 @@ public class VoiceController : MonoBehaviour
 
         // root加载完成后,所有element算出位置后再进行计算
         root.RegisterCallback<GeometryChangedEvent>(e => OnMainMenuClickGeometryChanged(e));
+        voiceBtn.RegisterCallback<PointerDownEvent>(e => VoiceBtnPointerDown(e), TrickleDown.TrickleDown); // TrickleDown.TrickleDown参数,确保事件在捕获阶段优先处理。
+        voiceBtn.RegisterCallback<PointerUpEvent>(e => VoiceBtnPointerUp(e));
     }
 
     // Update is called once per frame
-    void Update()
-    {
+    //void Update()
+    //{
         
-    }
+    //}
 
-    IEnumerator waveFormAnimation()
+    IEnumerator WaveFormAnimation()
     {
         while (true)
         {
@@ -41,7 +52,106 @@ public class VoiceController : MonoBehaviour
     {
         if (waveCoroutine == null)
         {
-            waveCoroutine = StartCoroutine(waveFormAnimation());
+            waveCoroutine = StartCoroutine(WaveFormAnimation());
         }
     }
+
+    // 语言控制按键按下的触发事件
+    void VoiceBtnPointerDown(PointerDownEvent evt)
+    {
+
+        Debug.Log("voice button pointer down.");
+        StartRecording();
+        waveForm.visible = true;
+    }
+
+    // 语音控制按键松开事件
+    void VoiceBtnPointerUp(PointerUpEvent evt)
+    {
+        Debug.Log("voice button pointer up.");
+        StopRecording();
+        waveForm.visible = false;
+    }
+
+    // 开始录音
+    void StartRecording()
+    {
+        if (isRecording) return; // 如果已经在录音,则不再重复开始
+
+        // 设置录音文件名和路径
+        filePathWav = Path.Combine(Application.persistentDataPath, "voiceCommand.wav");
+        filePathZip = Path.Combine(Application.persistentDataPath, "voiceCommand.mp3");
+
+        // 检测目录是否存在不存在就创建
+        string directoryPath = Path.GetDirectoryName(filePathWav);
+        if (!Directory.Exists(directoryPath))
+        {
+            Directory.CreateDirectory(directoryPath);
+        }
+        //删除旧文件
+        if (File.Exists(filePathWav))
+        {
+            File.Delete(filePathWav);
+        }
+        if (File.Exists(filePathZip))
+        {
+            File.Delete(filePathZip);
+        }
+
+        // 开始录音,最长4秒
+        audioClip = Microphone.Start(null, false, 4, 44100);
+        isRecording = true;
+        Debug.Log("开始录音...");
+    }
+
+    // 停止录音
+    void StopRecording()
+    {
+        if (!isRecording) return; // 如果没有在录音,则直接返回
+
+        // 停止录音
+        Microphone.End(null);
+        isRecording = false;
+        Debug.Log("停止录音...");
+
+        // 保存录音为WAV文件
+        SaveWavFile(filePathWav, audioClip);
+        Debug.Log("录音已保存到: " + filePathWav);
+        ZipFileController.ZipFile(filePathWav, filePathZip);
+    }
+
+    // 保存音频文件wav
+    void SaveWavFile(string path, AudioClip audio) {
+        // 创建文件流
+        using (FileStream fileStream = new(path, FileMode.Create))
+        {
+            using (BinaryWriter writer = new BinaryWriter(fileStream))
+            {
+                // 写入WAV文件头
+                writer.Write(new char[4] { 'R', 'I', 'F', 'F' }); // RIFF标志
+                writer.Write(36 + audio.samples * 2); // 文件大小
+                writer.Write(new char[4] { 'W', 'A', 'V', 'E' }); // WAVE标志
+                writer.Write(new char[4] { 'f', 'm', 't', ' ' }); // fmt标志
+                writer.Write(16); // fmt块大小
+                writer.Write((ushort)1); // 音频格式(PCM)
+                writer.Write((ushort)audio.channels); // 声道数
+                writer.Write(audio.frequency); // 采样率
+                writer.Write(audio.frequency * audio.channels * 2); // 字节率
+                writer.Write((ushort)(audio.channels * 2)); // 块对齐
+                writer.Write((ushort)16); // 位深度
+                writer.Write(new char[4] { 'd', 'a', 't', 'a' }); // data标志
+                writer.Write(audio.samples * 2); // 数据大小
+
+                // 写入音频数据
+                float[] samples = new float[audio.samples * audio.channels];
+                audio.GetData(samples, 0);
+
+                for (int i = 0; i < samples.Length; i++)
+                {
+                    writer.Write((short)(samples[i] * short.MaxValue)); // 将浮点数转换为16位整数
+                }
+            }
+        }
+    }
+
 }

+ 98 - 0
Assets/Scenes/Home.unity

@@ -3014,6 +3014,103 @@ Transform:
   m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 497eeb713045b2c4b84c9c4ec3b01784, type: 3}
   m_PrefabInstance: {fileID: 2092871523}
   m_PrefabAsset: {fileID: 0}
+--- !u!1001 &2099867578
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_Pivot.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_Pivot.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchorMax.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchorMax.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchorMin.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchorMin.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_SizeDelta.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_SizeDelta.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchoredPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_AnchoredPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 3819734098196001969, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7983087457938491336, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_Name
+      value: VoiceAndMenu
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
 --- !u!1 &2130545348
 GameObject:
   m_ObjectHideFlags: 0
@@ -3132,3 +3229,4 @@ SceneRoots:
   - {fileID: 921216528}
   - {fileID: 1360961875}
   - {fileID: 240199426}
+  - {fileID: 2099867578}

+ 233 - 11
Assets/Scenes/Login.unity

@@ -397,10 +397,10 @@ MonoBehaviour:
   m_OnClick:
     m_PersistentCalls:
       m_Calls:
-      - m_Target: {fileID: 1863178294}
-        m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine
-        m_MethodName: SetActive
-        m_Mode: 6
+      - m_Target: {fileID: 963194232}
+        m_TargetAssemblyTypeName: LoginController, Assembly-CSharp
+        m_MethodName: QuickStart
+        m_Mode: 1
         m_Arguments:
           m_ObjectArgument: {fileID: 0}
           m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@@ -532,7 +532,7 @@ MonoBehaviour:
   - m_Script
   m_LockStageInInspector: 
   m_StreamingVersion: 20170927
-  m_Priority: 10
+  m_Priority: 0
   m_StandbyUpdate: 2
   m_LookAt: {fileID: 0}
   m_Follow: {fileID: 0}
@@ -862,7 +862,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &540259604
 RectTransform:
   m_ObjectHideFlags: 0
@@ -1601,7 +1601,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 782739693}
-  m_Enabled: 0
+  m_Enabled: 1
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3}
   m_Name: 
@@ -2052,8 +2052,8 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 963194225}
   serializedVersion: 2
-  m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
-  m_LocalPosition: {x: 15, y: 1.5, z: 15}
+  m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
+  m_LocalPosition: {x: 0, y: 1.5, z: 14}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_ConstrainProportionsScale: 0
   m_Children: []
@@ -2091,7 +2091,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 963194225}
-  m_Enabled: 0
+  m_Enabled: 1
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: c52c89405d9917140bca2187d7a1e93a, type: 3}
   m_Name: 
@@ -2813,7 +2813,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 0
+  m_IsActive: 1
 --- !u!114 &1349309765
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -3394,6 +3394,67 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   m_Padding: {x: -8, y: -5, z: -8, w: -5}
   m_Softness: {x: 0, y: 0}
+--- !u!1001 &1720136357
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 4935552578167154759, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: 'm_Materials.Array.data[0]'
+      value: 
+      objectReference: {fileID: 2100000, guid: ece002c46bd7a6a46a49d487b041ec9e, type: 2}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 36
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 12
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 90
+      objectReference: {fileID: 0}
+    - target: {fileID: 6067956420894348072, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6881050099682970002, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
+      propertyPath: m_Name
+      value: fence white left
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: 3768e9958615ec448aa0316549ed68cc, type: 3}
 --- !u!1 &1748407892
 GameObject:
   m_ObjectHideFlags: 0
@@ -3719,6 +3780,67 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 0, y: 0}
   m_Pivot: {x: 0, y: 0}
+--- !u!1001 &1975442722
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 558941391177588771, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: 'm_Materials.Array.data[0]'
+      value: 
+      objectReference: {fileID: 2100000, guid: ece002c46bd7a6a46a49d487b041ec9e, type: 2}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 36
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 18
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 90
+      objectReference: {fileID: 0}
+    - target: {fileID: 1696430887500569420, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 2072005799332839926, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
+      propertyPath: m_Name
+      value: fence white right
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: 5dd8209dc48ef624498af0bc0c965410, type: 3}
 --- !u!1 &1982422434
 GameObject:
   m_ObjectHideFlags: 0
@@ -4009,6 +4131,103 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1994667331}
   m_CullTransparentMesh: 1
+--- !u!1 &2083184152
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2083184154}
+  - component: {fileID: 2083184153}
+  m_Layer: 0
+  m_Name: Dog Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &2083184153
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2083184152}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 0
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 0
+  m_Range: 50
+  m_SpotAngle: 75
+  m_InnerSpotAngle: 1
+  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: 1.02e-43, y: 6.4e-44, z: 7.856e-42, w: 2.4371993e-37}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &2083184154
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2083184152}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.5, y: 0.5, z: 0.5, w: 0.5}
+  m_LocalPosition: {x: 12, y: 4, z: 15}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 90, z: 90}
 --- !u!1 &2137333350
 GameObject:
   m_ObjectHideFlags: 0
@@ -4080,6 +4299,7 @@ SceneRoots:
   m_Roots:
   - {fileID: 963194228}
   - {fileID: 705507995}
+  - {fileID: 2083184154}
   - {fileID: 972508929}
   - {fileID: 1589749813}
   - {fileID: 1389830019}
@@ -4089,3 +4309,5 @@ SceneRoots:
   - {fileID: 782739695}
   - {fileID: 317191830}
   - {fileID: 1751824541}
+  - {fileID: 1975442722}
+  - {fileID: 1720136357}

+ 412 - 69
Assets/Scenes/Playground.unity

@@ -26,7 +26,7 @@ RenderSettings:
   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_SkyboxMaterial: {fileID: 2100000, guid: 12ccb828343c3405fb94289774b51aad, type: 2}
   m_HaloStrength: 0.5
   m_FlareStrength: 1
   m_FlareFadeSpeed: 3
@@ -251,7 +251,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 33934a78cc510314da574108110ad661, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  forceAdjust: 400
+  forceAdjust: 100
 --- !u!114 &72980117
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -455,6 +455,78 @@ RectTransform:
   m_CorrespondingSourceObject: {fileID: 3102913922244801059, guid: a1af5d77c38f0864b935d6770025ff3d, type: 3}
   m_PrefabInstance: {fileID: 82528520}
   m_PrefabAsset: {fileID: 0}
+--- !u!1 &142544961
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 142544962}
+  - component: {fileID: 142544963}
+  m_Layer: 0
+  m_Name: Dog CAM
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &142544962
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 142544961}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -36.87, y: -8.75, z: -26.650002}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 571992664}
+  m_Father: {fileID: 1981288963}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &142544963
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 142544961}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_ExcludedPropertiesInInspector:
+  - m_Script
+  m_LockStageInInspector: 
+  m_StreamingVersion: 20170927
+  m_Priority: 0
+  m_StandbyUpdate: 2
+  m_LookAt: {fileID: 0}
+  m_Follow: {fileID: 0}
+  m_Lens:
+    FieldOfView: 60.000004
+    OrthographicSize: 5
+    NearClipPlane: 0.3
+    FarClipPlane: 1000
+    Dutch: 0
+    ModeOverride: 0
+    LensShift: {x: 0, y: 0}
+    GateFit: 2
+    FocusDistance: 10
+    m_SensorSize: {x: 1, y: 1}
+  m_Transitions:
+    m_BlendHint: 0
+    m_InheritPosition: 0
+    m_OnCameraLive:
+      m_PersistentCalls:
+        m_Calls: []
+  m_LegacyBlendHint: 0
+  m_ComponentOwner: {fileID: 571992664}
 --- !u!1001 &168027944
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -539,57 +611,6 @@ PrefabInstance:
       insertIndex: -1
       addedObject: {fileID: 450893382}
   m_SourcePrefab: {fileID: 100100000, guid: b23aa0f47b77fbc4c8e0a2a9adc0fb29, type: 3}
---- !u!1 &249530890 stripped
-GameObject:
-  m_CorrespondingSourceObject: {fileID: 648218781261652396, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
-  m_PrefabInstance: {fileID: 6316843775113258627}
-  m_PrefabAsset: {fileID: 0}
---- !u!114 &249530892
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 249530890}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 23aeed6a06c30204b9e1f45d68adbf75, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
---- !u!114 &249530895
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 249530890}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 0f7f8759cd8317649a1c345f218977fb, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
---- !u!95 &249530896
-Animator:
-  serializedVersion: 7
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 249530890}
-  m_Enabled: 1
-  m_Avatar: {fileID: 0}
-  m_Controller: {fileID: 0}
-  m_CullingMode: 0
-  m_UpdateMode: 0
-  m_ApplyRootMotion: 0
-  m_LinearVelocityBlending: 0
-  m_StabilizeFeet: 0
-  m_AnimatePhysics: 0
-  m_WarningMessage: 
-  m_HasTransformHierarchy: 1
-  m_AllowConstantClipSamplingOptimization: 1
-  m_KeepAnimatorStateOnDisable: 0
-  m_WriteDefaultValuesOnDisable: 0
 --- !u!1 &253874363
 GameObject:
   m_ObjectHideFlags: 0
@@ -1150,6 +1171,89 @@ Transform:
   - {fileID: 253874370}
   m_Father: {fileID: 0}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &571992663
+GameObject:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 571992664}
+  - component: {fileID: 571992667}
+  - component: {fileID: 571992666}
+  - component: {fileID: 571992665}
+  m_Layer: 0
+  m_Name: cm
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &571992664
+Transform:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 571992663}
+  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: 142544962}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &571992665
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 571992663}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: bd6043bde05a7fc4cba197d06915c1e3, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Damping: {x: 0.1, y: 0.5, z: 0.3}
+  ShoulderOffset: {x: 0.2, y: 0.45, z: 0}
+  VerticalArmLength: 0.4
+  CameraSide: 0
+  CameraDistance: 1.8
+  CameraCollisionFilter:
+    serializedVersion: 2
+    m_Bits: 0
+  IgnoreTag: 
+  CameraRadius: 0.2
+  DampingIntoCollision: 0
+  DampingFromCollision: 2
+--- !u!114 &571992666
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 571992663}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a4c41ac9245b87c4192012080077d830, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Damping: 0
+--- !u!114 &571992667
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 571992663}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: ac0b09e7857660247b1477e93731de29, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &641109531 stripped
 GameObject:
   m_CorrespondingSourceObject: {fileID: 3802863874315455982, guid: a1af5d77c38f0864b935d6770025ff3d, type: 3}
@@ -1848,6 +1952,78 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: e2be7075929be2643b0e1b5bbc818674, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+--- !u!1 &1313049589
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1313049590}
+  - component: {fileID: 1313049591}
+  m_Layer: 0
+  m_Name: Player CAM
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1313049590
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1313049589}
+  serializedVersion: 2
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 1.3, z: -13}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 2029850347}
+  m_Father: {fileID: 1981288963}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1313049591
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1313049589}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_ExcludedPropertiesInInspector:
+  - m_Script
+  m_LockStageInInspector: 
+  m_StreamingVersion: 20170927
+  m_Priority: 10
+  m_StandbyUpdate: 2
+  m_LookAt: {fileID: 0}
+  m_Follow: {fileID: 0}
+  m_Lens:
+    FieldOfView: 60.000004
+    OrthographicSize: 5
+    NearClipPlane: 0.3
+    FarClipPlane: 1000
+    Dutch: 0
+    ModeOverride: 0
+    LensShift: {x: 0, y: 0}
+    GateFit: 2
+    FocusDistance: 10
+    m_SensorSize: {x: 1, y: 1}
+  m_Transitions:
+    m_BlendHint: 0
+    m_InheritPosition: 0
+    m_OnCameraLive:
+      m_PersistentCalls:
+        m_Calls: []
+  m_LegacyBlendHint: 0
+  m_ComponentOwner: {fileID: 2029850347}
 --- !u!1 &1405097793
 GameObject:
   m_ObjectHideFlags: 0
@@ -1860,6 +2036,7 @@ GameObject:
   - component: {fileID: 1405097795}
   - component: {fileID: 1405097794}
   - component: {fileID: 1405097797}
+  - component: {fileID: 1405097798}
   m_Layer: 0
   m_Name: Main Camera
   m_TagString: MainCamera
@@ -1908,7 +2085,7 @@ Camera:
     height: 1
   near clip plane: 0.3
   far clip plane: 1000
-  field of view: 75
+  field of view: 60.000004
   orthographic: 0
   orthographic size: 5
   m_Depth: -1
@@ -1935,7 +2112,7 @@ Transform:
   m_GameObject: {fileID: 1405097793}
   serializedVersion: 2
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: 0, y: 1.3, z: -12.305}
+  m_LocalPosition: {x: 0, y: 1.3, z: -13}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_ConstrainProportionsScale: 0
   m_Children: []
@@ -1953,6 +2130,40 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 0cf1c61d68f2a7842bebe048adbcbdfd, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+--- !u!114 &1405097798
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1405097793}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 72ece51f2901e7445ab60da3685d6b5f, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_ShowDebugText: 0
+  m_ShowCameraFrustum: 1
+  m_IgnoreTimeScale: 0
+  m_WorldUpOverride: {fileID: 0}
+  m_UpdateMethod: 2
+  m_BlendUpdateMethod: 1
+  m_DefaultBlend:
+    m_Style: 1
+    m_Time: 0.3
+    m_CustomCurve:
+      serializedVersion: 2
+      m_Curve: []
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+  m_CustomBlends: {fileID: 0}
+  m_CameraCutEvent:
+    m_PersistentCalls:
+      m_Calls: []
+  m_CameraActivatedEvent:
+    m_PersistentCalls:
+      m_Calls: []
 --- !u!1001 &1418362843
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -1963,7 +2174,7 @@ PrefabInstance:
     m_Modifications:
     - target: {fileID: 2417705292335416526, guid: 7b8797bfcbfe3f549ba74d2a9250e660, type: 3}
       propertyPath: m_Name
-      value: dog example (no use)
+      value: dog (not use)
       objectReference: {fileID: 0}
     - target: {fileID: 2417705292335416526, guid: 7b8797bfcbfe3f549ba74d2a9250e660, type: 3}
       propertyPath: m_IsActive
@@ -2220,7 +2431,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   m_IgnoreReversedGraphics: 1
-  m_BlockingObjects: 0
+  m_BlockingObjects: 3
   m_BlockingMask:
     serializedVersion: 2
     m_Bits: 4294967295
@@ -2290,6 +2501,134 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 0, y: 0}
   m_Pivot: {x: 0, y: 0}
+--- !u!1 &1981288962
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1981288963}
+  m_Layer: 0
+  m_Name: V Cameras
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1981288963
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1981288962}
+  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: 1313049590}
+  - {fileID: 142544962}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &2029850346
+GameObject:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2029850347}
+  - component: {fileID: 2029850350}
+  - component: {fileID: 2029850349}
+  - component: {fileID: 2029850348}
+  m_Layer: 0
+  m_Name: cm
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &2029850347
+Transform:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2029850346}
+  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: 1313049590}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2029850348
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2029850346}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fa7155796051b734daa718462081dc5f, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_BindingMode: 1
+  m_FollowOffset: {x: 0, y: 0, z: -10}
+  m_XDamping: 1
+  m_YDamping: 1
+  m_ZDamping: 1
+  m_AngularDampingMode: 0
+  m_PitchDamping: 0
+  m_YawDamping: 0
+  m_RollDamping: 0
+  m_AngularDamping: 0
+--- !u!114 &2029850349
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2029850346}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f4044717213e31446939f7bd49c896ea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_TrackedObjectOffset: {x: 0, y: 0, z: 0}
+  m_LookaheadTime: 0
+  m_LookaheadSmoothing: 0
+  m_LookaheadIgnoreY: 0
+  m_HorizontalDamping: 0.5
+  m_VerticalDamping: 0.5
+  m_ScreenX: 0.5
+  m_ScreenY: 0.5
+  m_DeadZoneWidth: 0
+  m_DeadZoneHeight: 0
+  m_SoftZoneWidth: 0.8
+  m_SoftZoneHeight: 0.8
+  m_BiasX: 0
+  m_BiasY: 0
+  m_CenterOnActivate: 1
+--- !u!114 &2029850350
+MonoBehaviour:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2029850346}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: ac0b09e7857660247b1477e93731de29, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &2129734284
 GameObject:
   m_ObjectHideFlags: 0
@@ -2391,6 +2730,10 @@ PrefabInstance:
     serializedVersion: 3
     m_TransformParent: {fileID: 0}
     m_Modifications:
+    - target: {fileID: 2559338786808445806, guid: 00b97733408f83840b44ba387e9ae31b, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
     - target: {fileID: 5997909836355842307, guid: 00b97733408f83840b44ba387e9ae31b, type: 3}
       propertyPath: m_Name
       value: StatusUI
@@ -2580,23 +2923,22 @@ PrefabInstance:
       propertyPath: m_Name
       value: VoiceAndManu
       objectReference: {fileID: 0}
-    - target: {fileID: 7983087457938491336, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
-      propertyPath: m_IsActive
+    - target: {fileID: 8362141720302802052, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_Enabled
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 8362141720302802052, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_BlockingMask.m_Bits
+      value: 4294967295
+      objectReference: {fileID: 0}
+    - target: {fileID: 8362141720302802052, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
+      propertyPath: m_IgnoreReversedGraphics
+      value: 1
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
-    m_AddedComponents:
-    - targetCorrespondingSourceObject: {fileID: 648218781261652396, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
-      insertIndex: -1
-      addedObject: {fileID: 249530892}
-    - targetCorrespondingSourceObject: {fileID: 648218781261652396, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
-      insertIndex: -1
-      addedObject: {fileID: 249530895}
-    - targetCorrespondingSourceObject: {fileID: 648218781261652396, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
-      insertIndex: -1
-      addedObject: {fileID: 249530896}
+    m_AddedComponents: []
   m_SourcePrefab: {fileID: 100100000, guid: ce6d2f68a67743945825670e3de02e19, type: 3}
 --- !u!1660057539 &9223372036854775807
 SceneRoots:
@@ -2618,3 +2960,4 @@ SceneRoots:
   - {fileID: 1418362843}
   - {fileID: 552932584}
   - {fileID: 17225207}
+  - {fileID: 1981288963}

+ 12 - 1
Assets/Scripts/TestSetup.cs → Assets/Scripts/Develop Script/TestSetup.cs

@@ -1,4 +1,5 @@
-using UnityEngine;
+using System;
+using UnityEngine;
 
 public class TestSetup : MonoBehaviour
 {
@@ -7,6 +8,8 @@ public class TestSetup : MonoBehaviour
     {
         // 初始化狗数据用于测试
         DogProperty puppy = new DogProperty();
+        puppy.runSpeed = 1000;
+        puppy.skin = "yellow";
         UserProperty.dogs.Add(puppy);
 
         if (EnviromentSetting.languageData == null)
@@ -21,6 +24,14 @@ public class TestSetup : MonoBehaviour
         
     }
 
+    // todo 删除。测试假数据注入
+    void TestDataInjection()
+    {
+        PlayerPrefs.SetString("LoginToken", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiSlRZTlpQOU8iLCJleHAiOjE3NDAxOTQ2Nzl9.081FF2AwxDTsN1gDWGZuzOxIDbM4M8Dw-mdwLfkxk4A");
+        DateTime now = DateTime.Now;
+        DateTime oneHourAgo = now.AddHours(-1);
+        PlayerPrefs.SetString("LoginTokenTime", oneHourAgo.ToString());
+    }
     // Update is called once per frame
     //    void Update()
     //    {

+ 0 - 0
Assets/Scripts/TestSetup.cs.meta → Assets/Scripts/Develop Script/TestSetup.cs.meta


+ 1 - 0
Assets/Scripts/EnviromentController.cs

@@ -45,6 +45,7 @@ public class EnviromentController : MonoBehaviour
 
         // 读取Dogbreeds 数据
         DogBreedController.LoadDogBreed();
+
     }
 
     // Update is called once per frame

+ 11 - 2
Assets/Scripts/EnviromentSetting.cs

@@ -4,13 +4,14 @@ using System.Collections.Generic;
 using UnityEngine;
 using System.Text.RegularExpressions;
 using Newtonsoft.Json;
+using static System.Net.WebRequestMethods;
 
 /* 本文件包含EnviromentSetting 主要功能上游戏运行环境设定
  */
 public static class EnviromentSetting
 {
-    // 服务器ip
-    public const string serverIp = "101.34.23.118";
+    // 服务器ip 正式发布需要替换掉ip
+    public static string serverIp = "http://101.34.23.118";
 
     //language.json读取和存放
     public static string langFilePath = "Assets/Resources/Data/languages.json";
@@ -18,6 +19,13 @@ public static class EnviromentSetting
 
     // access Token
     public static string accessToken;
+    public static DateTime accessTokenReceivedTime;
+    // 不需要access Token的请求
+    public static string[] accessTokenWhiteList = {
+        "/api/login/token/",
+        "/api/game/quick_start/",
+        "/api/login/"
+    };
 
     //系统语言 default=en
     public static string languageCode = "en";
@@ -31,6 +39,7 @@ public static class EnviromentSetting
     // 狗的数据库
     public static string dogDBFilePath = "Assets/Resources/Data/dogDB.json";
     public static DogBreed[] dogBreeds;
+    
 
     //用于获取多层级Dictionary中的value
     public static string GetValueAtPath(Dictionary<string, object> root, string[] path)

+ 8 - 0
Assets/Scripts/Functions.meta

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

+ 0 - 0
Assets/Scripts/SceneSwitcher.cs → Assets/Scripts/Functions/SceneSwitcher.cs


+ 0 - 0
Assets/Scripts/SceneSwitcher.cs.meta → Assets/Scripts/Functions/SceneSwitcher.cs.meta


+ 76 - 0
Assets/Scripts/Functions/WebController.cs

@@ -0,0 +1,76 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine;
+using UnityEngine.Networking;
+
+
+/* 本文件二次封装Web request
+ */
+
+public class WebController : MonoBehaviour {
+
+    // Start is called before the first frame update
+    //void Start()
+    //{
+
+    //}
+
+    // Update is called once per frame
+    //void Update()
+    //{
+
+    //}
+
+    public static IEnumerator PostRequest(string url,  Dictionary<string, string> postData=null, string filePath = null, System.Action<string> callback=null)
+    {
+     
+        // 创建 WWWForm 对象
+        WWWForm form = new WWWForm();
+        // 添加access token
+        bool accessTokenReq = true;
+        foreach (string whiteUrl in EnviromentSetting.accessTokenWhiteList)
+        {
+            if (url == whiteUrl && accessTokenReq == true)
+            {
+                accessTokenReq = false;
+            }
+        }
+        if (accessTokenReq) { form.AddField("access_token", EnviromentSetting.accessToken); }
+        
+
+        // 添加表单字段
+        foreach (var item in postData)
+        {
+            form.AddField(item.Key, item.Value);
+        }
+
+        // 添加文件
+        if (filePath != null)
+        {
+            byte[] fileData = System.IO.File.ReadAllBytes(filePath);
+            form.AddBinaryData(Path.GetFileName(filePath), fileData);
+        }
+        // 创建 UnityWebRequest 对象
+        url = EnviromentSetting.serverIp + url;
+        using (UnityWebRequest request = UnityWebRequest.Post(url, form))
+        {
+            // 发送请求并等待响应
+            yield return request.SendWebRequest();
+
+            // 检查是否有错误
+            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
+            {
+                Debug.LogError("上传失败: " + request.error);
+            }
+            else
+            {
+                // 上传成功,获取服务器响应
+                string responseText = request.downloadHandler.text;
+                callback?.Invoke(responseText);
+                Debug.Log("上传成功!服务器响应: " + responseText);
+            }
+        }
+    }
+
+}

+ 2 - 0
Assets/Scripts/Functions/WebController.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: f16b206cded010b4ea2ebb2b5ba5d2c4

+ 30 - 0
Assets/Scripts/Functions/ZipFileController.cs

@@ -0,0 +1,30 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.IO.Compression;
+using System.IO;
+using System;
+
+public class ZipFileController
+{
+    // Start is called before the first frame update
+    public static void ZipFile(string inputFile, string outputFile)
+    {
+        // 要压缩的文件路径
+        string fileToZip = inputFile;
+        // 压缩后的 ZIP 文件路径
+        string zipFilePath = outputFile;
+        // 创建一个新的 ZIP 文件并将文件添加到其中
+        using (FileStream zipToOpen = new FileStream(zipFilePath, FileMode.Create))
+        {
+            using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
+            {
+                // 获取文件名
+                string fileName = Path.GetFileName(fileToZip);
+                // 将文件添加到 ZIP 文件中
+                archive.CreateEntryFromFile(fileToZip, fileName);
+            }
+        }
+        Console.WriteLine("文件已成功压缩到: " + zipFilePath);
+    }
+}

+ 2 - 0
Assets/Scripts/Functions/ZipFileController.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: bf0373db64519f74eb22ab4ca64e40c4

+ 8 - 0
Assets/Scripts/GameControllers.meta

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

+ 7 - 2
Assets/Scripts/DogInitialize.cs → Assets/Scripts/GameControllers/DogInitialize.cs

@@ -11,9 +11,14 @@ public class DogInitialize : MonoBehaviour
     public Vector3 location, rotation, scale = new Vector3(1,1,1) ;       // 狗初始化位置
     public string dogId, dogDisplayName;        // 狗的id指的是调用用户拥有的狗的id dogName是狗在场景中的显示名
     public DogProperty dogProperty;
+
+    private void Awake()
+    {
+        
+    }
     // Start is called once before the first execution of Update after the MonoBehaviour is created
     void Start()
-    {   
+    {
         // 如果输入dog id 就优先使用dog id的数据读取
         if (!string.IsNullOrWhiteSpace(dogId))
         {
@@ -25,7 +30,7 @@ public class DogInitialize : MonoBehaviour
     // Update is called once per frame
     //void Update()
     //{
-        
+       
     //}
 
     // 初始化狗,并显示在屏幕上

+ 0 - 0
Assets/Scripts/DogInitialize.cs.meta → Assets/Scripts/GameControllers/DogInitialize.cs.meta


+ 0 - 0
Assets/Scripts/DogProperty.cs → Assets/Scripts/GameControllers/DogProperty.cs


+ 0 - 0
Assets/Scripts/DogProperty.cs.meta → Assets/Scripts/GameControllers/DogProperty.cs.meta


+ 3 - 2
Assets/Scripts/UserProperty.cs → Assets/Scripts/GameControllers/UserProperty.cs

@@ -10,10 +10,11 @@ using UnityEngine;
 public static class UserProperty
 {
     // Start is called before the first frame update
-    public static int userId = 1;
+    public static string userId;
     public static string name = "任天堂";
     public static int coin = 1005;
-    public static DateTime tokenExpireTime;
+    public static string email, mobile, level;
+    public static bool isRegUser = false;
     //public static Dictionary<string, int> foods = new();
     //public static Dictionary<string, int> toys = new();
     //public static Dictionary<string, int> others = new();

+ 0 - 0
Assets/Scripts/UserProperty.cs.meta → Assets/Scripts/GameControllers/UserProperty.cs.meta


+ 100 - 0
Assets/Scripts/Login/LoginController.cs

@@ -0,0 +1,100 @@
+using System;
+using UnityEngine;
+using UnityEngine.Networking;
+using System.Collections;
+using System.Collections.Generic;
+using Unity.VisualScripting;
+using Newtonsoft.Json;
+using UnityEngine.SceneManagement;
+using UnityEditor;
+
+/* 使用login token进行登录和数据读取保存
+ * TestDataInjection 是测试用的假数据注入
+ * LoginTokenCheck 验证login token是否有效,和服务器比对
+ */
+public class LoginController : MonoBehaviour
+{
+    // Start is called once before the first execution of Update after the MonoBehaviour is created
+    void Start()
+    {
+        //启动自动采用Login Token 登录。其他登录方式为手动登录。
+        //StartCoroutine(LoginTokenRequest());
+    }
+
+    // Update is called once per frame
+    //void Update()
+    //{
+        
+    //}
+
+
+
+    // LoginToken登录方法
+    IEnumerator LoginTokenEvent()
+    {
+        //yield return null;      // 跳过第一帧(可以考虑去掉,数据加载已经移到awake()了。
+        string UUID = SystemInfo.deviceUniqueIdentifier; // 这里需要考虑这段代码执行在Enviroment Controller之前
+        string LoginToken = PlayerPrefs.GetString("LoginToken", null);
+        string LoginTokenTime = PlayerPrefs.GetString("LoginTokenTime", null);
+
+        // todo 比较LoginTokenTime 如果超时直接放弃后面代码。比较UUID是否是null如果是直接放弃后面代码
+        if (LoginToken == null) { yield break; };
+        if (LoginTokenTime == null) { yield break; };
+        DateTime tokenTime;
+        DateTime now = DateTime.Now;
+        if (DateTime.TryParse(LoginTokenTime, out tokenTime))
+        {
+            TimeSpan span = now - tokenTime;
+            if (span.TotalHours > 7 * 24)
+            {
+                yield break;
+            }
+        }
+        else { yield break; }
+
+        // 提交POST
+        string url = "/api/login/token/";
+        Dictionary<string, string> formData = new();
+        formData.Add("login_token", LoginToken);
+        formData.Add("UUID", UUID);
+
+        StartCoroutine(WebController.PostRequest(url, formData, callback:LoginTokenCallback));
+    }
+
+    // Post之后callback的函数
+    void LoginTokenCallback(string json)
+    {
+        var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
+        if (data != null && data["status"] == "success") {
+            PlayerPrefs.SetString("LoginToken", data["login_token"]);
+            PlayerPrefs.SetString("LoginTokenTime", DateTime.Now.ToString());
+            EnviromentSetting.accessToken = data["access_token"];
+            EnviromentSetting.accessTokenReceivedTime = DateTime.Now;
+            UserProperty.userId = data["user_id"];
+        }
+        if (UserProperty.userId != null && EnviromentSetting.accessToken != null)
+        {
+            SceneManager.LoadScene("Home");
+        }
+    }
+
+    // Quick Start 登录方式,用UUID换取Login Token
+    public void QuickStart()
+    {
+        string url = "/api/game/quick_start/";
+        Dictionary<string, string> formData = new();
+        formData.Add("UUID", EnviromentSetting.UUID);
+        StartCoroutine(WebController.PostRequest(url, formData, callback: QuickStartCallback));
+    }
+
+    void QuickStartCallback(string json)
+    {
+        var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
+        if (data != null && data["status"] == "success")
+        {
+            PlayerPrefs.SetString("LoginToken", data["login_token"]);
+            UserProperty.userId = data["user_id"];
+            StartCoroutine(LoginTokenEvent());
+        }
+    }
+}

+ 0 - 0
Assets/Scripts/Login/LoginTokenController.cs.meta → Assets/Scripts/Login/LoginController.cs.meta


+ 5 - 3
Assets/Scripts/Login/LoginLangController.cs

@@ -4,6 +4,8 @@ using TMPro;
 using UnityEngine;
 using UnityEngine.UI;
 
+/* 本段代码控制登录页面语言设置
+ */
 public class LoginLangController : MonoBehaviour
 {
     // Start is called before the first frame update
@@ -14,10 +16,10 @@ public class LoginLangController : MonoBehaviour
     }
 
     // Update is called once per frame
-    void Update()
-    {
+    //void Update()
+    //{
         
-    }
+    //}
     void LoginCanvasLangSetting()
     {
         //读取Login Canvas语言设定

+ 0 - 78
Assets/Scripts/Login/LoginTokenController.cs

@@ -1,78 +0,0 @@
-using System;
-using UnityEngine;
-using UnityEngine.Networking;
-using System.Collections;
-using System.Collections.Generic;
-using Unity.VisualScripting;
-
-/* 使用login token进行登录和数据读取保存
- * TestDataInjection 是测试用的假数据注入
- * LoginTokenCheck 验证login token是否有效,和服务器比对
- */
-public class LoginTokenController : MonoBehaviour
-{
-    // Start is called once before the first execution of Update after the MonoBehaviour is created
-    void Start()
-    {
-        TestDataInjection();
-        StartCoroutine(LoginTokenCheck());
-    }
-
-    // Update is called once per frame
-    //void Update()
-    //{
-        
-    //}
-
-    // todo 删除。测试假数据注入
-    void TestDataInjection()
-    {
-        PlayerPrefs.SetString("LoginToken", "TestLoginToken");
-        DateTime now = DateTime.Now;
-        DateTime oneHourAgo = now.AddHours(-1);
-        PlayerPrefs.SetString("LoginTokenTime", oneHourAgo.ToString());
-    }
-
-    // LoginToken登录方法
-    IEnumerator LoginTokenCheck()
-    {
-        //yield return null;      // 跳过第一帧(可以考虑去掉,数据加载已经移到awake()了。
-        string UUID = SystemInfo.deviceUniqueIdentifier; // 这里需要考虑这段代码执行在Enviroment Controller之前
-        string LoginToken = PlayerPrefs.GetString("LoginToken", null);
-        string LoginTokenTime = PlayerPrefs.GetString("LoginTokenTime", null);
-
-        // todo 比较LoginTokenTime 如果超时直接放弃后面代码。比较UUID是否是null如果是直接放弃后面代码
-        if (LoginToken == null) { yield break; };
-        if (LoginTokenTime == null) { yield break; };
-        DateTime tokenTime;
-        DateTime now = DateTime.Now;
-        if (DateTime.TryParse(LoginTokenTime, out tokenTime))
-        {
-            TimeSpan span = now - tokenTime;
-            if (span.TotalHours > 7 * 24)
-            {
-                yield break;
-            }
-        }
-        else { yield break; }
-
-        // 提交POST
-        string url = "https://" + EnviromentSetting.serverIp + "/api/login/token/";
-        WWWForm form = new();
-        form.AddField("login_token", LoginToken);
-        form.AddField("UUID", UUID);
-        //List<KeyValuePair<string, string>> fields = form.fields;
-        using UnityWebRequest request = UnityWebRequest.Post(url, form);
-        {
-            yield return request.SendWebRequest();
-            if (request.result == UnityWebRequest.Result.Success)
-            {
-                Debug.Log("POST Success: " + request.downloadHandler.text);
-            }
-            else
-            {
-                Debug.Log("POST Error: " + request.error);
-            }
-        }
-    }
-}

+ 4 - 0
Assets/Scripts/Login/SunMovement.cs

@@ -30,6 +30,10 @@ public class SunMovement : MonoBehaviour
             UnityEngine.RenderSettings.skybox = nightSkybox;
             UnityEngine.RenderSettings.ambientIntensity = 0.3f;
             UnityEngine.RenderSettings.reflectionIntensity = 0.2f;
+
+            // ¹·¹·´´½¨µÆ¹â
+            var dogLight = GameObject.Find("Dog Light").GetComponent<Light>();
+            dogLight.intensity = 1.2f;
         }
         else
         {

+ 4 - 0
Assets/Scripts/Playground/AirWallDetection.cs

@@ -1,4 +1,5 @@
 using UnityEngine;
+using UnityEngine.Rendering.PostProcessing;
 
 public class AirWallDetection : MonoBehaviour
 {
@@ -22,6 +23,9 @@ public class AirWallDetection : MonoBehaviour
             Debug.Log("·ÉÅ̳ö½çÁË¡£ " + other.gameObject.tag);
             PlayData.throwHitWall = true;
             PlayData.gameStatus = PlayData.GameStatus.finishOutOfBound;
+            var dog = GameObject.Find("dog");
+            Animator animator = dog.GetComponent<Animator>();
+            animator.SetBool("runState", false);
         }
     }
 }

+ 10 - 2
Assets/Scripts/Playground/DogCatchDetection.cs

@@ -1,4 +1,5 @@
-using UnityEngine;
+using Cinemachine;
+using UnityEngine;
 
 /* 主要管理狗和飞盘触控管理发生后的管理行为 */
 
@@ -40,6 +41,12 @@ public class DogCatchDetection : MonoBehaviour
 
         if (other.gameObject.tag == "Throw Material" && other.transform.position.z > -9)    // >-9表示丢出一段距离后再检测
         {
+            // 调整camera
+            var CamPlayer = GameObject.Find("Player CAM").GetComponent<CinemachineVirtualCamera>();
+            var CamDog = GameObject.Find("Dog CAM").GetComponent<CinemachineVirtualCamera>();
+            CamPlayer.Priority = 10;
+            CamDog.Priority = 0;
+
             Debug.Log("狗狗接到飞盘了" + other.gameObject.tag);
             PlayData.throwCatched = true;
             PlayData.throwEndPosition = other.transform.position;    // 提交飞盘停止位置
@@ -67,7 +74,8 @@ public class DogCatchDetection : MonoBehaviour
         DogProperty dogProperty = UserProperty.dogs[0]; // 读取狗的数据
         var basePosition = new Vector3(0, 0.4f, -10.85f);
         float dogSpeed = dogProperty.runSpeed / 10;   // 狗的移动速度
-        dog.transform.rotation = Quaternion.RotateTowards(dog.transform.rotation, Quaternion.LookRotation(basePosition), 10800 * Time.deltaTime);
+        dog.transform.LookAt(basePosition);
+        //dog.transform.rotation = Quaternion.RotateTowards(dog.transform.rotation, Quaternion.LookRotation(basePosition), 10800 * Time.deltaTime);
         dog.transform.position = Vector3.MoveTowards(dog.transform.position, basePosition, dogSpeed * Time.deltaTime);
 
         if (dog.transform.position == basePosition)

+ 43 - 15
Assets/Scripts/Playground/PlayToyController.cs

@@ -1,4 +1,5 @@
-using System;
+using Cinemachine;
+using System;
 using UnityEngine;
 using UnityEngine.InputSystem;
 using UnityEngine.SceneManagement;
@@ -21,12 +22,21 @@ public class PlayToyController : MonoBehaviour
     Vector2 mouseEndPosition = new(0f, 0f);
     // forceAdjust 用于调节力量参数,数字越大减力效果越高
     public int forceAdjust = 100;
-    
+    private CinemachineVirtualCamera CamPlayer, CamDog;
+    private GameObject dog;
+
     // Start is called once before the first execution of Update after the MonoBehaviour is created
-    //void Start()
-    //{
-    //    Physics.gravity = new Vector3(0, -9.81f, 0);
-    //}
+    void Start()
+    {
+
+        PlayData.Reset();
+
+        CamPlayer = GameObject.Find("Player CAM").GetComponent<CinemachineVirtualCamera>();
+        CamDog = GameObject.Find("Dog CAM").GetComponent<CinemachineVirtualCamera>();
+        
+        
+        
+    }
 
     // FixedUpdate is called once per frame
     void FixedUpdate()
@@ -51,7 +61,10 @@ public class PlayToyController : MonoBehaviour
         // 按下鼠标
         if (context.phase == InputActionPhase.Started)
         {
-
+            // 动态配置Dog V Cam。不能放在Start()里面,因为狗是动态加载的。Start时候狗还没有加载。
+            dog = GameObject.Find("dog");
+            CamDog.m_Follow = dog.transform;
+            CamDog.m_LookAt = dog.transform;
             Ray ray = Camera.main.ScreenPointToRay(Pointer.current.position.ReadValue());
             if (Physics.Raycast(ray, out RaycastHit hit))
             {
@@ -75,7 +88,7 @@ public class PlayToyController : MonoBehaviour
             yForce = (mouseEndPosition.y - mouseStartPosition.y)/throwTime/forceAdjust;
             Debug.Log("xForce is: " + xForce);
             Debug.Log("yForce is: " + yForce);
-            if (yForce > 1 && yForce > xForce) // 确保是向前飞出飞盘
+            if (yForce > 1 && yForce > xForce*0.5f) // 确保是向前飞出飞盘
             {
                 AddThrowForce();
             }
@@ -110,15 +123,21 @@ public class PlayToyController : MonoBehaviour
     // 飞碟飞出后,狗追逐飞碟
     public void DogCatchToy()
     {
+        // 调整摄像机
+        CamPlayer.Priority = 0;
+        CamDog.Priority = 10;
+
         var dog = GameObject.Find("dog");
         var toy = GameObject.Find("toy");
         DogProperty dogProperty = UserProperty.dogs[0]; // 读取狗的数据
-        float turnSpeed = 90.0f; // 每秒最多旋转角度
+        //float turnSpeed = 90.0f; // 每秒最多旋转角度
     //dog.transform.LookAt(fisbee.transform.position);
 
         if (toy.transform.position.y < 0.43 && PlayData.gameStatus == PlayData.GameStatus.inProgress)
         {
             PlayData.gameStatus = PlayData.GameStatus.finishFail;   // 游戏状态设置为失败。狗依然在追逐飞盘,但是飞盘已经落地
+            Animator animator = dog.GetComponent<Animator>();
+            animator.SetBool("runState", false);
             Debug.Log("飞盘落地了");
         }
         else if (dog != null && toy != null)
@@ -136,8 +155,10 @@ public class PlayToyController : MonoBehaviour
                 targetRotation = Quaternion.LookRotation(direction);
             }
 
+            // 直接转向
+            dog.transform.LookAt(targetPosition);
             // 平滑旋转到目标方向
-            dog.transform.rotation = Quaternion.RotateTowards(dog.transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
+            //dog.transform.rotation = Quaternion.RotateTowards(dog.transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
 
             float dogSpeed = dogProperty.runSpeed/10;   // 狗向飞盘移动
             dog.transform.position = Vector3.MoveTowards(dog.transform.position, targetPosition, dogSpeed * Time.deltaTime);
@@ -152,8 +173,8 @@ public class PlayToyController : MonoBehaviour
         }
     }
 
-    // 初始化 playground UI 的按键语言
-    public void UILanguageInit()
+    // 初始化 playground UI 的按键语言和功能
+    public void UI_Initial()
     {
         var root = GameObject.Find("PlaygroundUIDocument").GetComponent<UIDocument>().rootVisualElement;
         var btnArea = root.Q<VisualElement>("btnArea");
@@ -166,16 +187,17 @@ public class PlayToyController : MonoBehaviour
         playagainBtn.text = textValue;
 
         playagainBtn.clicked += ()=> GameReset();
+        confirmBtn.clicked += ConfirmBtnClick;
     }
 
-    // 游戏结束显示结果
+    // 游戏结束调用显示显示结果UI
     public void ShowGameResult()
     {
         if (PlayData.isResultShowed == false)
         {
             var playgroundUI = GameObject.Find("PlaygroundUIPlaceholder").transform.Find("PlaygroundUI").gameObject;
             playgroundUI.SetActive(true);
-            UILanguageInit();
+            UI_Initial();
             var root = GameObject.Find("PlaygroundUIDocument").GetComponent<UIDocument>().rootVisualElement;
             var gameResult = root.Q<Label>("gameResult");
             string textValue;
@@ -200,7 +222,7 @@ public class PlayToyController : MonoBehaviour
     }
 
     // 游戏重置
-    public void GameReset()
+    void GameReset()
     {
         PlayData.Reset();
         // 获取当前场景的名称
@@ -208,6 +230,12 @@ public class PlayToyController : MonoBehaviour
         // 重新加载当前场景
         SceneManager.LoadScene(currentSceneName);
     }
+
+    // UI 点击确认后,返回到Home界面
+    void ConfirmBtnClick()
+    {
+        SceneManager.LoadScene("Home");
+    }
 }
 
 

BIN
Assets/Terrain/LoginTerrain.asset


+ 4 - 4
ProjectSettings/ProjectSettings.asset

@@ -12,8 +12,8 @@ PlayerSettings:
   targetDevice: 2
   useOnDemandResources: 0
   accelerometerFrequency: 60
-  companyName: DefaultCompany
-  productName: PuppyLocal
+  companyName: Echo3991
+  productName: PuppyAR
   defaultCursor: {fileID: 0}
   cursorHotspot: {x: 0, y: 0}
   m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
@@ -164,7 +164,7 @@ PlayerSettings:
   androidMinAspectRatio: 1
   applicationIdentifier:
     Android: com.DefaultCompany.PuppyLocal
-    Standalone: com.DefaultCompany.PuppyLocal
+    Standalone: com.Echo3991.PuppyAR
   buildNumber:
     Standalone: 0
     VisionOS: 0
@@ -981,6 +981,6 @@ PlayerSettings:
   hmiLoadingImage: {fileID: 0}
   platformRequiresReadableAssets: 0
   virtualTexturingSupportEnabled: 0
-  insecureHttpOption: 0
+  insecureHttpOption: 1
   androidVulkanDenyFilterList: []
   androidVulkanAllowFilterList: []

+ 11 - 0
app.config

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="NAudio.Core" publicKeyToken="e279aa5131008a41" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>