# 使用Skript的變量
本篇教學會詳細解說變量以及教你如何使用Skript的變量
在上一篇已經說明如何安裝Skript,如果你還不會可以點這裡:point_right: [Skript 入門教學](/4kzPSPklQ4-UEszrHp7Clw)
## 關於變量
### 要在Skript裡使用變量你要先了解以下幾點 :
1. **什麼是變量?**
變量是一種可以儲存任何數據的一種形式數字、文字、布林值(boolean)、列表、玩家、材料、
變量有以下幾種形式 :
|變量 |類型 |
|:---|:---|
|`{Var}`|全局變量|
|`{Var::*}`| 全局列表變量|
|`{_Var}`| 局部變量|
|`{_Var::*}`| 局部列表變量|
以上4種就是Skript內最常用的變量
2. **變量可以用在哪裡?**
變量可以用在,例如command內,將使用指令的玩家ID存進變量
或是提取數據,有的時候Skript不能直接將將指定數據輸出
例如 :
:::danger
:x: **不可行** :point_down:
:::
```Skript=1
send mongo value "UUID" of collection {_docs}
```
:::success
:white_check_mark: **可行** :point_down:
:::
```Skript=1
set {_uuid} to mongo value "UUID" of collection {_docs}
send {_uuid}
```
上面的程式是將MongoDB內的數據提取出來,但直接使用send會出錯
像這種情況就需要先將MongoDB的數據放到一個變量內再輸出
## 變量類型
1. **全局變量**
全局變量的名稱前面是沒有_的,當你設置一個全局變量的時候,就不能在別的任何地方創建一個一樣名稱的全局變量,而且這個變量在同一 個伺服器內,不論是哪個Skript程式裡都是相同的東西,做個比方 :
我先在名稱為`Project-1.sk`的程式裡寫一段
```
set {number} to 1
```
在另一個名稱為`Project-2.sk`的程式裡寫一段
```
set {number} to 2
```
如果我先執行`Project-1.sk`,再執行`Project-2.sk`,最後`{number}`的值會是2
這同時是全局變量好處也是壞處,好處是你可以利用這個特性去寫一個跨程式的全局變量,能夠讓不同程式去交互數據,壞處是當程式越寫越龐大時,你就容易搞混而且你還要為每個不同變量都想一個新名稱
2. **局部變量**
局部變量相比全局變量就是名稱前面一定要有_,像是`{_data}`,局部變量的特性是用完就丟,當一段程式碼執行完後,裡面所有的局部變量所保存的數據就會丟棄,不利於長期儲存數據,局部變量在一個程式內可以有無限多個相同名稱但存著不同數據的變量
如下程式碼 :
```Skript=1
command /test:
trigger:
set {_number} to 1
set {_user} to player's name
send "%{_number}%"
send "%{_user}%"
wait 5 second
send "%{_number}%"
send "%{_user}%"
on join:
send {_user}
```
在這個段代碼裡,先看到command的部分,當玩家執行/test之後就會生成一個新的變量`{_number}`、`{_user}`,而且當command底下執行完後,生成的變量就消失了,所以下方`on join`的部分是不會顯示任何東西的,因為局部變量不會憑空出現,你可能會想問,如果有兩個玩家同時使用/test指令,那`{_user}`會是A玩家的名稱還是B玩家的名稱呢?
結果就是`{_user}`會像分身一樣同時存在A、B玩家的名稱,只是在執行的程式碼內就會是對應的值,互不干擾,A玩家執行了/test,那`{_user}`對於A玩家來說就是A玩家的名稱,對B玩家同理
3. **列表變量**
列表變量會像這樣`{_list::*}`,他的特點是一個變量就可以儲存多組數據,`*`的意思是"全部",他也分全局跟局部,但性質就跟上面相同,這裡主要講==列表==的部分
```Skript=1
add "A" to {_list::*}
add "B" to {_list::*}
add "C" to {_list::*}
add "D" to {_list::*}
send {_list::*}
```
上面的寫法會上輸出為 :
`A`
`B`
`C`
`D`
如果要指定哪組數據,可以
```Skript=1
add "A" to {_list::*}
add "B" to {_list::*}
add "C" to {_list::*}
send {_list::2}
```
輸出為 : `B`
如果你直接往`{_list::*}`內添加數據,而沒有指定數據名稱的情況下,默認會自動照順序
如上方`{_list::1}`就會是A,`{_list::3}`就會是C
當然你也可以指定名稱
```Skript=1
set {_list::aa} to "A"
set {_list::bb} to "B"
set {_list::cc} to "C"
send {_list::cc}
```
輸出為 : `C`
你也可以使用雙重以上的列表變量
```Skript=1
set {_list::a::player} to "Aoter"
add 1 to {_list::b::*}
add "Code" to {_list::b::*}
send {_list::*}
send {_list::b::*}
send {_list::b::1}
```
分別輸出 :
- `Aoter`
`1`
`Code`
- `1`
`Code`
- `1`
注意!
1. 你不能這樣用`{_list::*::a}`,你不能在`*`的後面再指定一組數據
2. add語法變數的最後一組一定要是`*`像是`{_list::b::*}`就可以使用add,如果你指定了名稱,例如: `{_list::b::a}`,請使用set語法而不是add
## 數據類型
儲存在變量內的數據也是有==類型==區分的,下方為數據類型列表
注意! 在"引號"內的數據通通都是文字類型
|數據|類型|
|:--|:--|
|"text"|文字|
|10|數字|
|true、false|布林值|
|null|空的|
|stone|物品|
|{NBT:1}|NBT|
|player|玩家|
|offlineplayer|離線玩家|
**對應用法**(部分需擴展)
- `set {_text} to "Text"`
- `set {_number} to 10`
- `set {_boolean} to true`
- `set {_null} to null`
- `set {_block} to type of event-block`
- `set {_nbt} to nbt of event-block`
- `set {_player} to player`
**將文字轉為其他類型**
- `set {_number} to "10" parsed as number`
- `set {_item} to "%event-block%" parsed as itemtype`
- `set {_uuid} to {_player}'s uuid parsed as offlineplayer`
## 使用變量
不過我個人習慣一律使用局部變量,你們只需要依照你們需要的變量去編寫就行
1. **玩家數據**
```Skript=1
#當玩家加入時
on join:
#設置該變數為玩家名稱
set {_playerdata::name} to player's name
#設置該變數為玩家UUID
set {_playerdata::uuid} to player's uuid
#設置該變數為玩家座標
set {_playerdata::location} to player's location
#設置該變數為現在時間
set {_playerdata::JoinTime} to now
#將以上所有變數發送到控制台
send {_playerdata::*} to console
```
該程式會將玩家的名稱、UUID、位置、加入時間都發送到後台
2. **提取MongoDB數據**
```Skript=1
#當玩家加入時
on join:
set {_p::uuid} to player's uuid
set {_p::name} to player's name
set {_doc} to first mongo document with mongosk filter where field "uuid" is {_p::uuid} of collection {collection}
if {_doc} is set:
set mongo value "name" of {_doc} to {_p::name}
update mongo document {_doc} of {collection}
```
以上是一個基本的將數據寫入MongoDB的程式
||當然這也需要使用MongoDB的Skript擴展才能使用,這裡只是示範||
有關Skript擴展的教學要之後才會有了
以上就是入門教學的一個成教程,如果有任何錯誤或問題都可以在底下提出,如果有錯誤我會盡快修正
## 我的聯絡資訊
- **Discord : aoter.dev** :speech_balloon:
- **Gmail : mail@aoter.net** :mailbox:
如果有關Skript的任何問題都可以聯絡我
Discord我是會比較快回覆,但請你表明你的目的