---
# System prepended metadata

title: BeatDay表演製作規格書v1.0.2

---

# 表演資源規格標準化

## 開發版本

Unity版本：2022.3.59.f1
Unity模式：URP

## 電腦測試環境 (最低要求)

CPU：Intel® Core™ i5
(4th generation or better) or equivalent
RAM：8GB
顯卡：NVIDIA GeForce GT 1030

## Project Folders

<font color=red>
[必須]     
    
* 插件根據項目放在Addons，以目錄分隔，匯入前先告知我方，進行測試評估
* 美術資源放在MiscAssets目錄下
* 主表演景(.unity)放在Scenes下
* 客製腳本放在Scripts目錄下
* 目錄，檔案只可用英文命名
</font>    
![image](https://hackmd.io/_uploads/BJ-IODXLgl.png)


檔案歸類大致上分為：
Addos(插件資源)、MiscAssets(美術資源)、Scenes(主要表演場景)、Scripts(自定義腳本)
![image](https://hackmd.io/_uploads/Bk6yFD78eg.png)




## 各製作檔案項目歸檔方式

✦Addons 是放置 Unity 插件相關，從 AssetStore購置或Github 等添加的插件，需放置此處。

插件中的 -> 腳本、資源等，在匯入時可能是散落的，建議先創建一個以原本插件名稱相同的空資料夾，將散落的目錄集中至剛剛創建的空資料夾中，最後再將集中好的插件目錄放置 (拖曳) 至 Addons 中，以免使用過多插件時，過多的插件目錄重疊衝突。
<font color=red> (下圖為示意，請用英文) </font>
![image](https://hackmd.io/_uploads/SkN-Yw7Lxg.png)



✦MiscAssets 是放置 美術相關資源，分別為Animations(動補相關)、Art(美術表演資源)、Media(音樂相關)，建議分類依照以下類別放置。




✦Concert->(表演編號)-Song 放置該一首歌曲表演相關的全部資源。
✦並建議根據資源類別分類ConcertTimeline(Timeline組件)少會有一組主表演運行Timelin與一組導演運鏡Timeline。



✦Show->(節目編號)-Show 放置該一場互動環節相關的全部資源。
✦並建議根據資源類別分類ConcertTimeline(Timeline組件)少會有一組主表演運行Timelin與一組導演運鏡Timeline。


✦VTCharacter放置VTuber人物模型檔案。(下圖為示意，請用英文)



✦UI放置UX、UI介面相關資源。(下圖為示意，請用英文)




✦Media 放置歌曲、音效等音源檔案。
背景音樂、音效聲音、表演歌曲等，建議依據項目在做歸檔的分類。




✦Scenes 分別為(表演順序)-ConcertScene(歌曲表演)、(表演順序)-ShowScene(互動環節)，是放置 [最終表演要使用的場景]，原則上是對應一首歌一個景，如果場景為連續使用，一個景也會含多首歌(但建議超過5首歌曲依然分另一組Scene)。(下圖為示意，請用英文)
![image](https://hackmd.io/_uploads/SJuaYw7Ulx.png)



✦Scripts 放置自己編寫非AssetStore、Github 整合過的腳本，其中有使用到UnityEditor必須放置到Editor(編輯器)，避免Build執行檔遇到編譯錯誤。
![image](https://hackmd.io/_uploads/HkGk5w7Uxe.png)




已有插件清單

僅列出較常見表演項目插件
![image](https://hackmd.io/_uploads/rJEg5PXLxl.png)

<font color=red>
若有新增插件需求，需要在Addons資料夾，以目錄分隔
匯入前先告知我方，並進行測試評估
</font>

# 表演、運鏡編輯製作規範

## 整體演出時間軸設定

　　當演出設定設好之後，填好演出設定表(表2.表演規劃表)之後，BEATDAY方會提供一個演出設定檔，設定演出順序與各景的基本設定，啟動機制會根據此設定檔進行表演的加載。 場景編排請參考下一章節。

![image](https://hackmd.io/_uploads/HJ27iwQUgx.png)



## 場景編排

　　每個場景、表演內容被載入時，會自動開啟Root階層的物件，如果有不希望被自動開啟的物件，請將他放在第二層物件階層，然後關閉此物件。
　　Root階層物件需配一個主要timeline控制演出，需要掛在一個TimeLineCom元件，每個演出都必須要配置一個TimeLineCom，這是BEATDAY設定演出的入口。
此主timelime的”Play On Awake”需要關閉，Update Method使用”Game Time”。另外建議Wrap Mode用在 Hold 避免表演完瞬跳回初始狀態，除非有特殊情況。Timeline更新率建議都用30fps，經驗值上影片或聲音的吻合度會比較好。
![image](https://hackmd.io/_uploads/BJCNsvXUxg.png)

## Beatday表演控制元件: TimeLineComp

TimeLineCom<font color=red>**必須**</font>進行以下設定：
1. Director Root：
導演模式鏡頭的根節點，關於導演模式的配置請看下一章節
2. Born Locst：
配置完架在此表演場景生成的初始位置，+Z為Forward方向，此為Array形式，須至少配置一個Transform，當配置多個生成點，會隨機在這些地點生成玩家。

以下為<font color=blue>選擇配置，如果沒有配置，會使用預設值</font>：
1. Qulity Data：
![image](https://hackmd.io/_uploads/Sy9-nDQ8le.png)
用以配置當不同圖像設定時，啟用不同的設定，可以如果element是物件，可以切換開關物件，如果是配置在主timeline的子timeline物件，如下圖，會進行timeline模組的切換。
![image](https://hackmd.io/_uploads/BJNS3P7Ixe.png)
QualityLevel 會連動使用者的BEATDAY系統設定。
![image](https://hackmd.io/_uploads/BkkQhwQIxl.png)


2. Day Data：
如果要用相同表演，但是在不同場次的演出有些特殊的不同配置，可以使用Day Key會自動抓表演設定的序號，可以藉有比對序號，開啟設定的Obj。DayKey匹配不到時，會使用第一組資料。
![image](https://hackmd.io/_uploads/BJNS3P7Ixe.png)

　　一個基本的timeline會有這樣的配置，建議用群組區分功能，導演鏡頭的設定也會以子timeline的方式加載主timeline。
![image](https://hackmd.io/_uploads/rkdF3wmLlx.png)


## 導演運鏡編輯Cinemachine

　　運鏡用Unity Cinemachine插件製作，並且場景中資源放在同一個物件底下，以便用開關物件方式切換 6dof & 導播鏡頭 該物件上也會掛載驅動導播鏡頭的Timeline，詳情請參考官方最新API：https://docs.unity3d.com/Packages/com.unity.cinemachine@3.1/manual/index.html
建議以以下方式進行編排，會有一個主要的Camera，用timeline　(ConcertDirectorTimeline)來控制Camera的進位，各段落的VCam放在All_Cut節點下
![image](https://hackmd.io/_uploads/SyxGTvQUgx.png)
![image](https://hackmd.io/_uploads/B1OzTv78gg.png)
![image](https://hackmd.io/_uploads/BJbQ6vQ8xe.png)

## 場景碰撞體與出界設置

　　用戶會用第一人稱操作虛擬角色觀看表演，需要匯入BEATDAY提供的簡易角色控制器，將其拖曳至場景上，用於檢測該場景碰撞是否正常(地板掉落、場景物件穿模、隔絕靠近演出人物範圍、飛行限制區域)，整個場景外圍需要用collider包起來，避免觀眾跑到場外，Collider的isTrigger 要關閉。

![image](https://hackmd.io/_uploads/Hy3VTv78eg.png)

　　如果怕玩家跑到太遠的區域，需要觀眾回到主舞台，可以建立一個collider，isTrigger打開，另外多掛ObjectTriggerController元件，開啟"isCheckChar" 跟 "TriggerEnter”，設定當發生時，呼叫SetPositionRandomBorn，指定重生點，此重生點建議設定為TimeLineCom的BornLocs群組。
![image](https://hackmd.io/_uploads/ByPTaw7Uel.png)


　　碰撞區塊建立一個 New GameObject (命名為 Colliders) 用於群組相關的碰撞物體，並且 Tag 須設定，並且使用 Box Collider、Sphere Collider建置，<font color=red>盡量不使用 Mesh Collider，主要是 Mesh Collider 比較耗運算。</font>

# 效能檢查工具與方法

　　表演基本效能檢查，可以在 Unity Editor 掛載 Graphy - Ultimate FPS Counter 插件物件，進行以下項目測試，並且達到指定的電腦規格，在 Unity Editor 是否順跑 60fps。


測試電腦規格
CPU：Intel Core i5 以上
RAM：8GB 以上
顯卡：NVIDIA GeForce GT1030 以上
硬碟空間: 20GB 以上
建議網速: 50 Mbps
Unity 內建Stats: Batch 在800 以下
![image](https://hackmd.io/_uploads/ryV10w7Ule.png)



　　掛載測試效能檢測(BEATDAY插件->效能資訊顯示插件)，運行中檢查圖中資訊(Ctrl+F11 切換)

單首歌強烈建議運行fps: 60 以上,
Memory(allocated): 4G 以下


掛載物件第一人稱預覽(驗證玩家視角可觀看區域、確保碰撞體遮擋避免穿模
![image](https://hackmd.io/_uploads/HJkGRvQLlg.png)


# 特殊Layer、Tag使用規範

場景碰撞、燈光、道具 Layer、Tag使用分類


| Layer | 名稱 | 用途 | 
| -------- | -------- |-------- |
| 0     | Default，Unity預設     | )|
| 1~4   | Unity預設，保留     ||
| 5     | UI，Unity預設     ||
| 6     | Actor (表演者)     |表演者 |
| 7     | Actor2(表演者預留)     |表演者預留|
| 8     | Character(人物角色，玩家操作角色)     | 物角色，玩家操作角色|
| 9     | Item(道具物件)     |道具物件|
| 10    | Interactive(場景互動物件)     |場景互動物件|
| 11    | Scene 01         | 表演場景分層用 |
| 12    | Scene 02         | 表演場景分層用 |
| 13    | Scene 03         | 表演場景分層用 |
| 14    | Scene 04         | 表演場景分層用 |
| 15    | Scene 05         | 表演場景分層用 |
| 16    | Scene 06         | 表演場景分層用 |
| 17    | Scene 07         | 表演場景分層用 |
| 18    | Scene 08         | 表演場景分層用 |
| 19    | Scene 09         | 表演場景分層用 |
| 20    | Reserved 01      | 保留備用 |
| 21    | Reserved 02      | 保留備用 |
| 22    | Reserved 03      | 保留備用 |
| 23    | Reserved 04      | 保留備用 |
| 24    | Reserved 05      | 保留備用 |
| 25    | Reserved 06      | 保留備用 |
| 26    | Stencil Layer 1  | Stencil功能備用 |
| 27    | Stencil Layer 2  | Stencil功能備用 |
| 28    | Mirror           | 鏡面反射 |
| 29    | CardStencil      | 卡牌效果 |
| 30    | FullScreenVideo  |  |
| 31    | CamDepth         |  |

# Audio Mixer

1. 聲音來源檔案
 * 聲音格式 (wav, 雙聲道 優先 )
 * 各別音樂音效需在AudioSource各別設定指定Mixer Channel
![image](https://hackmd.io/_uploads/B1AOxd7Uel.png)

![image](https://hackmd.io/_uploads/HJOAgOmLxx.png)



　　<font color=red>如果不確定表演要如何分類，至少要替AudioSource掛載Show作為Default值，不然使用者會無法對音量進行調控</font>


# 場景資源製作規範

1. 原始貼圖Size/格式、Unity貼圖Size、Unity壓縮格式
* 原始貼圖Size/格式只能使用PNG 與JPG 最大不要超過2048。
* Unity貼圖Size請以1024以內為主 重要主視覺或者大面積需求才用2048 ，請在貼圖的inspector設定好
* Unity壓縮格式使用預設即可
2. Batch數量
整個場景最大所有粒子與特效全開600上下為主，多人共同演出800上下。如果再更多請與我方討論。
3. Material與Shader使用限制
整個舞台的材質球合理使用，單一物件材質球數量5個以內，同樣與類似的材質盡量共用。
不要有大面積涵蓋整個舞台、視覺畫面超過50%~100%的半透明物件同時出現
半透明物件不要同時間多個重複遮蓋
4.場景檔案的 Root 層級 <font color=red>(下圖為示意，請用英文)</font>
![image](https://hackmd.io/_uploads/ryJUZuQUxx.png)


# 鏡頭特效與燈光使用規範

1. Post processing部分禁用.  
<font color=red>鏡頭景深與動態模糊禁用 包含類似的機制外掛</font>
![image](https://hackmd.io/_uploads/H1cDnuQIex.png)

2. Realtime實體燈光數限制 
* 作用在場景以1~2盞為主 只能有一盞Directional Light或者Spot Light可以有hard shadows
* 作用在Vtuber放在指定Layer能有1~3盞 

| Layer | 名稱 | 用途 | 
| -------- | -------- |-------- |
| 6     | Actor (表演者)     |表演者 |
| 7     | Actor2(表演者預留)     |表演者預留|

* 請用unity圖層把作用在場景跟作用在Vtuber的燈光，根據Layer設定切分開來(使用Layer: Scene01~ Scene09 )

3. Realtime shadow限制 
表演同一段落，只能有一盞Directional Light，或者Spot Light可以有hard shadows

4. Light probe 可使用，需警慎分配


# 表演特效與粒子製作規範

1. 粒子發射最大數量
    * 全場不論使用幾個粒子特效同時間場上粒子總數不要超過2000
    * 只支援URP特效
    * 不要有大面積、視覺畫面超過50%~100%的半透明特效物件同時出現



# 影片與廣告素材使用規範
建議壓縮格式、聲音格式、影片解析度、影片大小
* 影片格式 webm
* 編碼: vp8
* FPS： 24 (建議) / 30
* 位元率：VBR
    * HD： 8 mbps (最高)
   * 720P： 5mbps (最高)
* 音訊:
    * 雙聲道 128kbps, AAC
* 建議影片單一大小不要超過 100 MB
* 同一時間不可播放超過2個影片

# BackendApi 使用

## 排行榜
為比賽或小遊戲進行排行榜動作，也可以利用此機制確認有沒有完成某設定事件。leaderboardId需要跟BEATDAY方申請確認，確保不重複。
* 取得排行榜分數
int UserExtraAPI.GetAttr(myUserData.uid, myUserData.jwt, leaderboardId)
須帶入登入後的uid跟jwt(可以從系統內取得)，如果沒有設定過，會回傳預設值0。
* 設定排行榜分數
int UserExtraAPI.SetAttr(myUserData.uid, myUserData.jwt, leaderboardId, score, logArrayString);
須帶入登入後的uid跟jwt(可以從系統內取得)，會回傳設定後的分數。logArrayString可以傳入防偽或遊戲歷程，避免作弊，預設為空字串。
* 增加排行榜分數
int UserExtraAPI.AddAttr(myUserData.uid, myUserData.jwt, leaderboardId, plusScore);
須帶入登入後的uid跟jwt(可以從系統內取得)，會回傳增加後的分數。
* 取得排行榜前n名
List<(string, int) UserExtraAPI.GetAttrTops(myUserData.uid, myUserData.jwt, leaderboardId, topN);
取的指定排行榜前topN排行，回傳第一個值是uid, 第二個值是分數。

## 投票
一人一票，voteId需要跟BEATDAY方申請確認，確保不重複。回傳投票格式為
```

        public struct VoteTable
        {
            // Database 參數
            public string id;               //投票代碼
            public DateTime endTimeDateUtc; //結束時間UTC
            public string endtime;          //結束時間UTC字串, 傳遞用，請用endTimeDateUtc
            public string title;            //投票標題
            public string detail;           //投票內容
            public string[] options;        //投票選項
            public int[] rs;                //投票票數
            public int myopt;               //我的投票結果, 表示未投票 -1 
            public int no;                  //廢票人數
            public string status;            //投票狀態: end (結束) / ing (進行中) / del (刪除中)

            // 主角的投票狀態，不一定會使用，
            public string[] vnames;         //參加的Vtuvber
            public int[] vrs;               //參加的Vtuvber投票結果
        }

```
* 投票
VoteTable VoteAPI.VoteAsync(string voteId, string uid, int votOpt, string jwt)
須帶入登入後的uid跟jwt(可以從系統內取得)，voteOpt順序為0-based，如果-1表示還沒有投票
* 取得目前投票結果
如果非簡易模式(slimMode)，需要傳入uid, 得知自己的投票結果，如果是slim模式，只有rs(投票結果)有值，其他皆為空。
VoteTable VoteAPI.GetVoteAsync(string voteId, bool slimMode, string uid = null)

