# 112年3月 - Unity遊戲程式設計實作班
###### tags: `Unity` `遊戲程式設計` `產業人才投資方案` `授課資料`
> 此項筆記供112年3月產業人才投資方案-Unity遊戲程式設計實作班課程使用,講師會將上課補充重點、參考資料與程式碼留在此頁面 :books:
---
>課程日期:112-03-04(六)、112-03-11(六)、112-03-18(六)
>課程時間:09:00 ~ 12:00、13:30 ~ 16:30
>上課地點:崑山科技大學 民生應用學院二館 H2605教室 (電競教室)
>授課教師:[鄭郁翰](https://web.ksu.edu.tw/DTCECGD/teacher/BPm5DRXmVhiAEs76y8PalQ--) 講師 [[前往教師簡介]](https://web.ksu.edu.tw/DTCECGD/teacher/BPm5DRXmVhiAEs76y8PalQ--)
>課程大綱:https://cee.ksu.edu.tw/2414
>本頁面短網址:https://reurl.cc/7Rpdz1
>
>本課程使用之輔助教材:[Unity 遊戲設計育成攻略 (旗標出版、ISBN:9789863125822)](https://www.flag.com.tw/books/product_s/F9589)
>書籍範例檔案與素材下載:http://www.flag.com.tw/DL.asp?F9589
## :memo: 課前準備
### Step 1: 上課前應準備的
- [x] 完成 Unity 帳號申請
- [x] 安裝 Microsoft 微軟帳號申請
:::info
:pushpin: 本課程會使用到Unity及Visual Studio兩個開發工具,這兩個工具皆提供個人學習的免費授權,所以申請上面兩個帳號可供學員在家啟用免費授權來自我練習之用。
:::
### Step 2: 課前能力檢核
- [x] 電腦或手機遊戲接觸經驗 (至少也要有玩過吧!!)
- [x] 具備基礎程式語言能力
- [x] 有C#程式語言開發經驗者尤佳
### Step 3: 開發工具下載與安裝
1. Unity : https://unity.com/
2. Visual Studio 2022 Community : https://visualstudio.microsoft.com/zh-hant/downloads/
3. Unity Remote 5 - Google Play 應用程式 : https://play.google.com/store/apps/details?id=com.unity3d.mobileremote&hl=zh_TW&gl=US
4. Unity Remote 5 on the App Store : https://apps.apple.com/us/app/unity-remote-5/id871767552
5. Unity Asset Store : https://assetstore.unity.com/
## 何謂遊戲開發引擎
遊戲開發引擎是一種專門用於開發遊戲的軟體,它提供了一套完整的工具和框架,使開發人員可以更快速地開發出高質量的遊戲,而不必從頭開始自己編寫程式碼。這些引擎通常包括圖形渲染、物理模擬、音訊處理、人工智慧、腳本語言、資源管理和編輯器等工具,以方便開發人員進行遊戲的創作和設計。
相較於一般的程式開發框架,遊戲設計引擎更加專注於遊戲相關的功能和特性,並且通常已經內建了大量的函式庫和相關工具,使開發人員可以更快速地開始開發。此外,許多遊戲設計引擎還支援跨平台開發,可以輕鬆地在多個平台上發佈遊戲。
市面上常見的遊戲開發引擎包含Unity、Unreal Engine(虛幻引擎)...等。
Unity官方網站上目前描述可部署的平台:
![](https://hackmd.io/_uploads/rJ6E3Yk1n.png)
### Unity 的常見中/英文操作對照
![](https://hackmd.io/_uploads/BJyC0t112.png)
---
![](https://hackmd.io/_uploads/BkggJ9JJ3.png)
---
![](https://hackmd.io/_uploads/B1Bp15J12.png)
---
![](https://hackmd.io/_uploads/rk1sk9Jk3.png)
---
### 整體視窗比較
![](https://hackmd.io/_uploads/BJkee9JJn.png)
![](https://hackmd.io/_uploads/HkXMxcJJ2.png)
---
### 常見名詞中英對照
* Hierarchy / 階層
* Project / 專案
* Inspector / 檢查器
* Console / 控制台
* Scene / 場景
* Game / 遊戲
* Assets / 資源
* Window / 視窗
* Component / 元件
* Tag / 標籤
* Materiel / 材質
* Collider / 碰撞器
* Trigger / 觸發器
* Cube / 立方體
* Sphere / 球體
* Capsule / 膠囊
* Sylinder / 圓柱
* Plane / 平面
* Terrain / 地形
* Camera / 攝影機
* Effect / 效果
* Physics / 物理
* 3D Object / 3D物件
* Empty / 空物件
* Empty Chlid / 空子物件
* Empty Parent / 空父物件
* Prefab:有些網路文件翻譯為「預製體」、「預製物件」,但目前Unity的中文介面無對照中文翻譯,直接以Prefab稱之。
* Splash Screen / 啟動畫面
* Children / 子系
## 第一支程式碼:Hello World
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyCode : MonoBehaviour
{
void Start()
{
Debug.Log("Hello World");
}
void Update()
{
}
}
```
以上程式碼的重點在於 Debug.Log("Hello World"); ,其他內容都是自動產生的。
### Unity Scripting API : Transform
https://docs.unity3d.com/ScriptReference/Transform.
#### 常用方法(Methods)舉例
* Rotate
* Translate
#### 常用屬性(Properties)舉例
* rotation
* position
### Unity Scripting API : Input
https://docs.unity3d.com/ScriptReference/Input.html
#### 檢測滑鼠按鍵
* GetMouseButton
* GetMouseButtonDown
* GetMouseButtonUp
*
#### 檢測按鈕(從Input Manager定義)
* GetButton
* GetButtonDown
* GetButtonUp
* GetAxis
* GetAxisRaw
#### 檢測實體按鍵
* GetKey
* GetKeyDown
* GetKeyUp
常見的 KeyCode 可以參考[官方網站文件的說明](https://docs.unity3d.com/ScriptReference/KeyCode.html): ,例如有:
* UpArrow : 上方向鍵
* DownArrow : 下方向鍵
* LeftArrow : 左方向鍵
* RightArrow : 右方向鍵
* Space : 空白鍵
* 其他請參考 : https://docs.unity3d.com/ScriptReference/KeyCode.html
#### 體感操作(例如用於手機)
* 加速度計 : Input.acceleration
https://docs.unity3d.com/ScriptReference/Input-acceleration.html
```csharp=
void Update()
{
Vector3 v3 = Input.acceleration;
if (v3.y != 0)
{
transform.Translate(Input.acceleration.y * Time.deltaTime * 10, 0, 0);
}
}
```
* 陀螺儀 : Input.gyro
https://docs.unity3d.com/cn/2020.3/ScriptReference/Input-gyro.html
```csharp=
Gyroscope m_Gyro;
void Start() {
m_Gyro = Input.gyro;
m_Gyro.enabled = true;
}
void Update()
{
Debug.Log(m_Gyro.gravity);
Vector3 v3 = m_Gyro.gravity;
if (v3.x != 0)
{
transform.Translate(Input.acceleration.x * Time.deltaTime * 10, 0, 0);
}
}
```
#### 課本第三章實作程式碼
```csharp=
public class demo : MonoBehaviour
{
float rotSpeed = 0;
void Start()
{
}
void Update()
{
if (Input.GetMouseButton(0))
{
rotSpeed = 30;
}
rotSpeed *= 0.98f;
transform.Rotate(0, 0, rotSpeed);
}
}
```
## 課本第四章實作程式碼
UI Text配置
![](https://hackmd.io/_uploads/BylvaDgk3.png)
### CarController.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarController : MonoBehaviour
{
float speed = 0;
Vector2 start, end;
void Start()
{
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
start = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(0))
{
end = Input.mousePosition;
float swipeLength = end.x - start.x;
speed = swipeLength / 500f;
GetComponent<AudioSource>().Play();
}
speed *= 0.98f;
transform.Translate(speed, 0, 0);
}
}
```
### GameDirector.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class GameDirector : MonoBehaviour
{
GameObject car, flag, distance;
void Start()
{
car = GameObject.Find("car");
flag = GameObject.Find("flag");
distance = GameObject.Find("距離");
}
void Update()
{
float length = flag.transform.position.x - car.transform.position.x;
distance.GetComponent<Text>().text = "距離旗子還有" + length;
}
}
```
https://docs.unity3d.com/ScriptReference/AudioSource.html
### 設定其他字型
Google Font : https://fonts.google.com/?subset=chinese-traditional¬o.script=Hant
### 從遊戲場景中找出物件的方法
* Find() : 找出場景中指定名稱的物件
* FindGameObjectWithTag() : 找出場景中Tag名稱相同的所有物件(可能回傳多筆)
### 從遊戲物件中找出所屬元件
* GetComponent() 取出物件中指定的元件,以下為找出Rigibody的範例寫法
```csharp=
GameObject obj = GameObject.Find("myObj");
Rigibody rb = obj.GetComponent<Rigibody>();
```
### 碰撞器(Collider)與觸發器(Trigger)
### Untiy物理相關元件
| 物理元件 | 2D | 3D |
| -------- | -------- | -------- |
| 剛體 | Rigibody 2D | Rigibody |
|球體/圓形碰撞器|Circle Collider 2D|Sphere Collider |
|盒狀碰撞器|Box Collider 2D|Box Collider |
|膠囊體碰撞器|Capsule Collider 2D|Capsule Collider |
|網格/邊緣碰撞器|Edge Collider 2D|Mesh Collider |
### 觸發的監聽方法
|事件(Event)| 2D| 3D |
|----------|---|----|
|碰撞事件剛發生時|OnCollisionEnter2D|OnCollisionEnter|
|碰撞事件發生後的持續狀態|OnCollisionStay2D|OnCollisionStay|
|碰撞事件結束時|OnCollisionExit2D|OnCollisionExit|
|----|
|觸發事件剛發生時|OnTriggerEnter2D|OnTriggerEnter|
|碰觸發件發生後的持續狀態|OnTriggerStay2D|OnTriggerStay|
|觸發事件結束時|OnTriggerExit2D|OnTriggerExit|
### 其他參考常用方法
* Instantiate() : 針對物件進行複製,可以用於將Prefab實例化為遊戲物件物件 https://docs.unity3d.com/ScriptReference/Object.Instantiate.html
* Destroy() : 將物件銷毀。第二個參數可以指定多久時間後再銷毀。(延遲執行) https://docs.unity3d.com/ScriptReference/Object.Destroy.html
* Invoke() : 可設定多少秒數後執行指定方法。https://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html
* InvokeRepeating() : 與Invoke()類似,但是還可以不斷重複執行。如果要停止執行可以用CancelInvoke()。 https://docs.unity3d.com/ScriptReference/MonoBehaviour.InvokeRepeating.html
* Random.Range() : 用於取隨機值。 https://docs.unity3d.com/ScriptReference/Random.Range.html
* SceneManager.LoadScene() : 切換場景
* SceneManager.LoadScene(SceneManager.GetActiveScene().name) : 可用於重新載入場景
## 課本第五章實作程式碼 (2023-03-11課程修改後的版本)
### PlayerController.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void Start()
{
}
public void GoLeft()
{
if (transform.position.x >= -7)
{
transform.Translate(-3, 0, 0);
}
}
public void GoRight()
{
if (transform.position.x < 7)
{
transform.Translate(3, 0, 0);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
GoLeft();
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
GoRight();
}
}
}
```
### ArrowController.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ArrowController : MonoBehaviour
{
public float speed = 1f;
void Start()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
if ( collision.CompareTag("Player") )
{
GameObject.Find("GameHP").GetComponent<HpManager>().AddHp(-10);
Destroy(gameObject);
}
}
void Update()
{
// 當箭頭超出遊戲畫面時就捨棄物件
if (transform.position.y < -5.0f)
{
Destroy(gameObject);
}
}
}
```
### ArrowGenerator.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowGenerator : MonoBehaviour
{
public GameObject obj;
void Start()
{
InvokeRepeating("Generator", 1, 1);
}
public void Generator()
{
float newX = Random.Range(-8,8);
GameObject arrow = Instantiate(obj);
arrow.transform.position = new Vector3(newX, 5.5f, 0);
}
void Update()
{
}
}
```
### HpManager.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class HpManager : MonoBehaviour
{
public float totalHp = 100;
GameObject hpImage;
GameObject hpText;
void Start()
{
hpImage = GameObject.Find("hp");
hpText = GameObject.Find("TextHp");
}
public void AddHp(int hp)
{
totalHp += hp;
hpImage.GetComponent<Image>().fillAmount = totalHp / 100;
hpText.GetComponent<Text>().text = totalHp.ToString();
if (totalHp <= 0)
{
SceneManager.LoadScene("MenuScene");
}
}
void Update()
{
}
}
```
### Menu.cs
```csharp=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Menu : MonoBehaviour
{
public void StartGame()
{
SceneManager.LoadScene("SampleScene");
}
}
```
### 2023-03-11 程式碼檔案
2023-03-11課程實作檔案請點選以下連結下載
https://drive.google.com/file/d/1QyQwzim2jnyrgr_JH5WbfqQhRd5ElUyl/view?usp=share_link
### 補充:3D遊戲的球體主角控制
```csharp=
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Rigidbody rb = GetComponent<Rigidbody>();
Vector3 v3 = new Vector3(h, 0, v);
rb.AddForce(v3);
```
### 補充:Unity 事件生命週期
[Unity Docs 原始來源](https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg)
![](https://hackmd.io/_uploads/SkdiY-hJh.png)
Time Setting : Edit->Project Settings->Time
https://docs.unity3d.com/ScriptReference/Time-deltaTime.html
![](https://hackmd.io/_uploads/B1Vn8GMx3.png)
## Unity - UI
* Canvas - 遊戲中的UI物件都必須放在Canvas中,也就是UI物件都是Canvas的子物件
* EventSystem - 用於處理事件,遊戲UI中會使用到事件系統,例如點選按鈕、文字輸入等。
![](https://hackmd.io/_uploads/HyBF9mxg2.png)
### RectTransform
* 之前課程提到每個物件一定都有「Transform」元件,UI元件中只有「RectTransform」,但RectTransform是Transform元件的子類別,所以並不違法這項說法喔!
參考資料:https://docs.unity3d.com/ScriptReference/RectTransform.html
### Image 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Image.html
可用於顯示圖片,重要屬性包含:
* Source Image : 設定顯示的圖片來源
* Color : 圖片疊加的顏色
* ImageType : 圖片的類型,包含 Simple , Sliced , Tiled , Filled
### Text 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Text.html
![](https://hackmd.io/_uploads/B1h91Nex2.png)
極為常用,用於顯示文字,重要屬性包含:
* Text : 顯示的文字
* Font : 文字的字型 (預設為Arial)
* Font Style : 字體風格,例如粗體、斜體等
* Alignment : 文字對齊方式
* Horizontal Overflow : 水平內容超出時要處理的方法,可選擇 Wrap 或 Overflow
* Vertical Overflow : 垂直內容超出時要處理的方法,可選擇 Truncate 或 Overflow
* Best Fit : 自動調整最適合的大小
* Color : 文字顏色
* 可結合 Shadow 或 Outline 元件來產生其他文字效果
### Button 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Button.html
用於設計UI上的按鈕,重要屬性包含:
* Interactable : 設定按鈕是否可以進行操作
* Transition : 一個按鈕有多個狀態,包含 一般、突顯、按下、停用等狀態,可以利用惡個屬性來切換4個狀態的各種表現方式。
* OnClick : 按鈕被點擊後所觸發的事件,可以在此設定觸發後要執行的方法
* Button 是一個複合物件,預設底下還有一個子物件,若要改變文字請編輯子物件中Text元件的text屬性。
### Toggle 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Toggle.html
![](https://hackmd.io/_uploads/S1tteNxxh.png)
![](https://hackmd.io/_uploads/r1-9xNge3.png)
* Is On : 表示是否被勾選
* Transition : 如同前面Button所提到的,用於表示各種狀態的呈現方式
* Toggle Transition : 表示勾選時的效果,可設定None(無效果)或Fade(淡入淡出
* Group : 用於設計「單選方塊」的場景,只要多個 Toggle 物件設定了相同的 Group,就會形成一個單選方塊群組。
* 此外,Toggle 也是一個複合物件,若要變更文字,也請變更子物件的Text屬性
* OnValueChanged : 選取狀態被切換時觸發的事件,可以在此設定觸發後要執行的方法
### Slider 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Slider.html
![](https://hackmd.io/_uploads/BkAyXEglh.png)
用於顯示與設定一定範圍的數值
* Interactable : 設定是否可以進行操作
* Transition : 狀態間的效果
* Fill Rect : 表示已選擇的區域
* Handle Rect : 表示滑動鈕的區域
* Direction : 滑動的方向
* Min Value : 最小值
* Max Value : 最大值
* Whole Numbers : 設定是否只取整數
* Value : 目前的設定值
### Input Field 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-InputField.html
![](https://hackmd.io/_uploads/SyJLEEee3.png)
涉及文字輸入的場景會使用到
* Interactable : 設定是否可以進行操作
* Text : 物件上所輸入的文字
* Text Component : 關聯的文字內容子物件,可用於定義輸入文字的各項屬性,例如顏色、字體等
* Character Limit : 最大可輸入之字元
* Content Type : 設定內容類型,預設是Standard,也可設定成密碼型態、數值型態...等
* Line Type : 設定文字單行或多行
* Placeholder : 可用於設定尚未輸入文字時所呈現的內容
* Selection Color : 被選取時的背景顏色
* 有2個常用的事件,包含OnValueChanged(當內容改變時)及OnEndEdit(當結束編輯時)。
### Scroll Rect 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-ScrollRect.html
當內容大於顯示區域時,往往會需要捲動畫面來顯示畫面外的資訊,這時候就需要卷軸(Scroll)來幫助
* Content : 用來指定放置內容的子物件,會根據這項設定來呈現捲動的功能
* Horizontal : 設定是否可以水平捲動
* Vertical : 設定是否可以垂直捲動
* Movement Type : 設定畫面捲動到邊緣時的效果
* Elasticity : 設定反彈的力度。必須在Movement Type設定為Elastic時才有效
* Scroll Sensitivity : 捲動的靈敏度
* Viewport : 用於指定子物件的Viewport,表示要顯示的區域;通常外層是Viewport,內層是Content,Viewport通常會附加Mask元件。
## Mask 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-Mask.html
* 用於遮蓋超出Mask範圍外的內容
* 父物件設置 Mask 元件後,將會影響子物件顯示的範圍
## Grid Layout Group 元件
https://docs.unity3d.com/cn/2021.1/Manual/script-GridLayoutGroup.html
有關於畫面佈局(Layout),Unity有根據不同需求的自動佈局的元件,包含水平佈局(Horizontal Layout Group)、垂直佈局(Vertical Layout Group)、網格佈局(Grid Layout Group)等。這邊以Grid Layout Group為例子。
* Padding : 佈局元件的外距
* Spacing : 佈局間的內距(內部元素之間的距離)
* Cell Size : 每一個元素的大小
* Child Alignment : 子物件的對齊方式
* Start Axis : 設定沿著哪一個軸線進行自動佈局。分為Horizontal及Vertical。
## Content Size Fitter 元件
https://docs.unity3d.com/cn/2021.3/Manual/script-ContentSizeFitter.html
可根據內容來調整大小
## 好用的UI製作素材
Simple UI & icons
https://assetstore.unity.com/packages/2d/gui/icons/simple-ui-icons-147101
![](https://hackmd.io/_uploads/BJnAhNlen.png)
1. 請先依上述網址完成素材下載
2. 下載完成後,請確認素材已經在專案資料夾內
![](https://hackmd.io/_uploads/r1BJmSeeh.png)
3. 因為要用在UI上,將所需素材的Texture Type設定為Sprite(2D and UI)
![](https://hackmd.io/_uploads/HJYw4Bee2.png)
4. 使用 Sprite Editor 調整素材以符合使用需求。如果要使用 Sprite Editor,必須先安裝2D Sprite套件,請至Package Manager中進行安裝,如下圖所示。
![](https://hackmd.io/_uploads/SJHkNSlxh.png)
5. 以九宮格模式切割素材(使用綠色的線條),以避免拉伸時失真
![](https://hackmd.io/_uploads/ByYCNreg3.png)
## 幾種簡單遊戲資料儲存的方式
* PlayerPerfs
* 適合簡單的資料儲存,例如單一數值、單一字串等
* 主要用於儲存遊戲設定,例如使用者的操作習慣
* 可以接受 整數 int 、 浮點數 float 、 字串 string 等類型
* JSON (搭配使用JsonUtility)
* 可保存較複雜的資料結構
* 可接受數值、字串,也可以是陣列(Array)
* 搭配JsonUtility及StreamWrite來實現儲存
* 其他:SQLite、遠端伺服器(雲端)…
### 使用 PlayerPerfs 儲存資料
#### 儲存資料
* PlayerPrefs.SetString("key","data")
* PlayerPrefs.SetInt("key","data")
* PlayerPrefs.SetFloat("key","data")
* PlayerPrefs.Save();
#### 讀取資料
* PlayerPrefs.GetString("key")
* PlayerPrefs.GetInt("key")
* PlayerPrefs.GetFloat("key")
#### 刪除資料
* PlayerPrefs.DeleteAll();
* PlayerPrefs.DeleteKey("Key");
#### PlayerPrefs 實際資料儲存位置
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
|系統|路徑|
|---|---|
|macOS| ~/Library/Preferences/com.ExampleCompanyName.ExampleProductName.plist|
|Windows| HKCU\Software\ExampleCompanyName\ExampleProductName|
|Windows Store App| %userprofile%\AppData\Local\Packages[ProductPackageId]\LocalState\playerprefs.dat|
|Linux| ~/.config/unity3d/ExampleCompanyName/ExampleProductName|
|Android| /data/data/pkg-name/shared_prefs/pkg-name.v2.playerprefs.xml|
|iOS| /Apps/ your app's folder /Library/Preferences/ your app's .plist|
|WebGL| 使用瀏覽器的 IndexedDB API|
### 使用 JSON 儲存資料
https://docs.unity3d.com/cn/2021.1/Manual/JSONSerialization.html
![](https://hackmd.io/_uploads/HkoCk0We2.png)
#### 宣告儲存資料的資料結構
```csharp=
public class playerData
{
public string name;
public int level;
}
```
可以使用 JsonUtility 來處理 JSON 資料結構
* FromJson : 利用JSON來產生物件結構
* ToJson : 將物件轉換成JSON格式的字串
https://docs.unity3d.com/cn/2021.1/ScriptReference/JsonUtility.html
#### 儲存資料
```csharp=
public void save()
{
playerData myPlayer = new playerData();
myPlayer.name = "Jason";
myPlayer.level = 87;
//轉換成json格式字串
string saveString = JsonUtility.ToJson(myPlayer);
//存到硬碟中
StreamWriter file = new StreamWriter(System.IO.Path.Combine(Application.streamingAssetsPath, "myData"));
file.Write(saveString);
file.Close();
}
```
#### 讀取資料
```csharp=
public void load()
{
//讀取JSON檔案
StreamReader file = new StreamReader(System.IO.Path.Combine(Application.streamingAssetsPath, "myData"));
string loadJson = file.ReadToEnd();
file.Close();
playerData loadData = new playerData();
//使用JsonUtillty的FromJson方法將存文字轉成Json
loadData = JsonUtility.FromJson<playerData>(loadJson);
//輸出測試
Debug.Log(loadData.name);
}
```
### Xbox遊戲控制器對應
![](https://hackmd.io/_uploads/Sk78IM1g3.png)
其他參考資料:
* https://answers.unity.com/questions/1350081/xbox-one-controller-mapping-solved.html
* https://learn.unity.com/tutorial/configuring-an-xbox-controller-for-user-input-2019-3#
設置範例
![](https://hackmd.io/_uploads/ryMKwSeg2.png)
---
## 課後補充
### 2023-03-18 上課結果匯出
https://drive.google.com/file/d/1V4SryGiYuYFvJKnY6frajRGDXQnMsZy8/view?usp=share_link
### 課後補充
1. 依據前面 「2023-03-18 結果匯出」的產出APK結果:
https://drive.google.com/file/d/1vCzTD4tonPRfQFmOi26Wlc3CiM6BfCb7/view?usp=share_link
2. 前面產出結果的操作流程錄影檔:
{%youtube 5xPpvjVyx3w %}
## 課後更新:2023-03-23版本
依學員課後提問,修改程式碼提供參考:
1. 調整版面更適合手機大小操作
2. 新增排行榜依分數排序的程式碼
3. 有學員反應電腦上可登錄排行榜,但在Android實機上卻失敗,此版本已修正,原因後續說明
APK檔案 : https://drive.google.com/file/d/1FXZ6qnr5JJY_CMs5NqMq-96PPwTNffL3/view?usp=share_link
輸出資源 : https://drive.google.com/file/d/1T4ro2WW6EGGIHu45FO-wWybDWg8_XPPk/view?usp=share_link
提醒:若學員要使用上面的資源匯入您的專案,請建立2D專案,建立後Build Setting也要把2個場景都加入。
#### 補充:Android無法寫入排行榜原因
1. Application.streamingAssetsPath 的資料夾的內容會被封裝,在Android中是唯讀的,但PC是可寫可讀的。
2. 在Android或iOS若需要保存檔案,可使用「Application.persistantDataPath」,相關說明資料:https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html
#### 當日上課無法成功建置APK的原因說明
因上課當天的教室已安裝了「Android Studio」(Android App的開發環境),設定可能與Unity衝突,後續經移除「Android Studio」後Unity即可正常建置APK封裝檔案。
#### 讓行動裝置螢幕不要休眠的方法
2023-04-01補充:有學員詢問在手機上會進入休眠,如何解決?請參考以下資料來源:
https://gn02214231.pixnet.net/blog/post/207037819-unity-%E4%BF%AE%E6%94%B9%E8%A1%8C%E5%8B%95%E8%A3%9D%E7%BD%AE%E9%80%B2%E5%85%A5%E4%BC%91%E7%9C%A0%E7%9A%84%E6%99%82%E9%96%93