# 表演資源規格標準化
## 開發版本
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>

檔案歸類大致上分為:
Addos(插件資源)、MiscAssets(美術資源)、Scenes(主要表演場景)、Scripts(自定義腳本)

## 各製作檔案項目歸檔方式
✦Addons 是放置 Unity 插件相關,從 AssetStore購置或Github 等添加的插件,需放置此處。
插件中的 -> 腳本、資源等,在匯入時可能是散落的,建議先創建一個以原本插件名稱相同的空資料夾,將散落的目錄集中至剛剛創建的空資料夾中,最後再將集中好的插件目錄放置 (拖曳) 至 Addons 中,以免使用過多插件時,過多的插件目錄重疊衝突。
<font color=red> (下圖為示意,請用英文) </font>

✦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)。(下圖為示意,請用英文)

✦Scripts 放置自己編寫非AssetStore、Github 整合過的腳本,其中有使用到UnityEditor必須放置到Editor(編輯器),避免Build執行檔遇到編譯錯誤。

已有插件清單
僅列出較常見表演項目插件

<font color=red>
若有新增插件需求,需要在Addons資料夾,以目錄分隔
匯入前先告知我方,並進行測試評估
</font>
# 表演、運鏡編輯製作規範
## 整體演出時間軸設定
當演出設定設好之後,填好演出設定表(表2.表演規劃表)之後,BEATDAY方會提供一個演出設定檔,設定演出順序與各景的基本設定,啟動機制會根據此設定檔進行表演的加載。 場景編排請參考下一章節。

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

## Beatday表演控制元件: TimeLineComp
TimeLineCom<font color=red>**必須**</font>進行以下設定:
1. Director Root:
導演模式鏡頭的根節點,關於導演模式的配置請看下一章節
2. Born Locst:
配置完架在此表演場景生成的初始位置,+Z為Forward方向,此為Array形式,須至少配置一個Transform,當配置多個生成點,會隨機在這些地點生成玩家。
以下為<font color=blue>選擇配置,如果沒有配置,會使用預設值</font>:
1. Qulity Data:

用以配置當不同圖像設定時,啟用不同的設定,可以如果element是物件,可以切換開關物件,如果是配置在主timeline的子timeline物件,如下圖,會進行timeline模組的切換。

QualityLevel 會連動使用者的BEATDAY系統設定。

2. Day Data:
如果要用相同表演,但是在不同場次的演出有些特殊的不同配置,可以使用Day Key會自動抓表演設定的序號,可以藉有比對序號,開啟設定的Obj。DayKey匹配不到時,會使用第一組資料。

一個基本的timeline會有這樣的配置,建議用群組區分功能,導演鏡頭的設定也會以子timeline的方式加載主timeline。

## 導演運鏡編輯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節點下



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

如果怕玩家跑到太遠的區域,需要觀眾回到主舞台,可以建立一個collider,isTrigger打開,另外多掛ObjectTriggerController元件,開啟"isCheckChar" 跟 "TriggerEnter”,設定當發生時,呼叫SetPositionRandomBorn,指定重生點,此重生點建議設定為TimeLineCom的BornLocs群組。

碰撞區塊建立一個 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 以下

掛載測試效能檢測(BEATDAY插件->效能資訊顯示插件),運行中檢查圖中資訊(Ctrl+F11 切換)
單首歌強烈建議運行fps: 60 以上,
Memory(allocated): 4G 以下
掛載物件第一人稱預覽(驗證玩家視角可觀看區域、確保碰撞體遮擋避免穿模

# 特殊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


<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>

# 鏡頭特效與燈光使用規範
1. Post processing部分禁用.
<font color=red>鏡頭景深與動態模糊禁用 包含類似的機制外掛</font>

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)