HeliScriptの基礎知識

:::note info
本記事は、[HeliScriptでリッチなアスレチックワールドを作ろう！【コピペで使えるサンプルコード付き】](https://qiita.com/IwahanaFuku/private/63e6bbca2bc1f13ed57e)の記事の一部です

VR法人HIKKYのorganization下のQiita/Zenn両方に投稿しております。
:::

## はじめに
Vket Cloudでは、ギミックを作るとき、HeliScript以外にも、ノーコードでギミックを作ることが出来る、アクションという仕組みが備わっています。
では、なぜ、HeliScriptを使うのか、HeliScriptを使うと何ができるようになるのか、また、HeliScriptを使う上でどういったことを知っておくとよいのかについて説明します。

アクションの概要や使い方については、[アクションの概要](https://vrhikky.github.io/VketCloudSDK_Documents/latest/Actions/ActionsOverview.html)をご参照ください。

## HeliScriptを使うと何ができるのか
Vket Cloudのアクションの仕組みは、スクリプトをかけない人にとってはとても良い仕組みですが、大規模な開発や複雑なギミックを作ろうとすると、困ることが出てきます。
アクションではなく、HeliScriptを使うことで、こんなことが実現できるようになります

### 一つのスクリプトで柔軟な動作を実現できるようになる
HeliScriptを使用しない場合、Vket Cloudでモノを動かそうとすると、
* [MoveTo](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/Actions/Item/MoveTo.html)アクションを使用して、まっすぐ動かす
* [物理エンジン](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/WorldMakingGuide/PhysicsEngine.html)を使用して、物理法則に従って動かす
* [アニメーション](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/WorldMakingGuide/PropAnimation.html)を使用して、オブジェクトを動かす

で動かすことが出来るようになります。
しかし、プレイヤーの位置に追従して動かしたり、滑らかな動作を行なったり、プレイヤーの状況に応じて動きを変えたりすることは、実装出来なかったり、出来てもものすごく時間がかかったりしてしまいます。

しかし、HeliScriptを使用することで、コードさえ書いてしまえば、様々な状況に対して柔軟に対応できるギミックを作ることが出来るようになります。

### 複雑な計算や条件分岐ができるようになる
アクションで使える計算は、[SetVar](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/Actions/Programmatic/SetVar.html)により事前に決めた値に対して、[AddVar](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/Actions/Programmatic/AddVar.html)で、足すしか行えず、条件分岐は事前に設定した定数に対して、AddVarした値が大きいか、小さいか、等しいかなどを比べるしか行えず、数回クリックしたらこのアクションが実行されるといったごく簡易的な条件分岐しか作ることが出来ませんでした。

しかし、HeliScriptを使えば、変数の宣言や、if文といった基本的なプログラミングに必要な処理を行うことができ、複数の条件分岐があったり、ボードゲームといった複雑な判断が必要なギミックも作れるようになります。

### 同期ギミックを作れるようになる
アクションで作られた動作は、プレイヤーのローカルの動作しか作ることが出来ず、他のプレイヤーとの同期を行うことは出来ませんでした。
しかし、HeliScriptでは、[組み込み関数 - ネットワーク](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_system_function_net.html)が用意されており、新しく入室したプレイヤーにも値が同期されるカスタムステートや、一度きりの送信が行えるカスタムデータといった仕組みが用意されています。

これによって、対戦ゲームや協力ゲームなど、Vket Cloudの長所であるWeb上で簡単に複数人で遊ぶことが出来るというメリットを生かしたギミック作成ができるようになります。

### そのほかにも…。
様々な[コールバック関数](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_component.html)が使えたり、三角関数などの[数学](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_system_function_math.html)が使えたり、[カメラ](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_system_function_camera.html)が操作できるようになったりと、使い方によってさまざまな可能性を広げることの出来る機能が用意されています。公式ドキュメントのHeliScriptの欄もそこまで分量があるわけではない(12.3時点)ので、興味のある方は一通り目を通すと新しい発見や、アイデアが湧くかもしれません。

## HeliScriptを使うための知識
HeliScriptは、C言語やC#言語と同じような文法を使える言語です。しかし、HeliScript特有の概念や、Vket Cloudの機能を知っておくことで、より柔軟に開発を進めることが出来るようになります。
HeliScript特有の概念から、HeliScriptの設定方法を説明します。

### Hello World!
公式のチュートリアルで[HeliScript概要](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_overview.html)として、Hello World!を行うチュートリアルが存在しているため、初めのチュートリアルとしてこちらをご確認ください。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/8dc9f448-be1a-7f85-47b4-9ab7d6bd864b.png)](https://vrhikky.github.io/VketCloudSDK_Documents/12.3/hs/hs_overview.html)


### classとcomponentについて
HeliScriptでは、classと同様の概念として[component](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_component.html)があります。
componentは、scene上に設置されたItemに対して複数個設定することが出来ます。
componentの特徴として、
* ひとつひとつのItemに対して設定できる
* システム側が必要な時に自動で生成する
* コールバックとしてイベントを受け取れる

といった特徴があります。また、VketCloudSDKでは、componentとして設定したものでないと、HEO Scriptに設定できません。

逆に
* 任意のタイミングで `new クラス名()` などで生成や廃棄したい
* クラスによる型の作成に使用したい

といったときは、classを使用します。

:::note warn
Unity上のコンポーネントと、HeliScriptのcomponentあって紛らわしいですが、本記事中では、Unity上のコンポーネントはカタカナでコンポーネント、HeliScriptのcomponentは英単語でcomponentと表記します。
:::

### VketCloudSDKでHeliScriptを使用するには
Vket Cloud上で、HeliScriptを使用するには、VketCloudSettingsのBasicSettings内で、HeliScriptファイルを登録する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/bea8fb2a-0a30-4e2e-07c2-2f8375375b78.png)
ここに登録されることで、ワールドロード時、Vket Cloudを動かすエンジンが、HeliScriptを読みこむようになります。

しかし、componentを、ひとつひとつのItemに対して設定したり、コールバックでイベントを受け取れるようにするにはHEO Scriptを使って、どのItemに対してコンポーネントを設定するか指定する必要があります。

### HEO Scriptについて
componentは、**ひとつひとつのItemに対して設定できて、コールバックでイベントを受け取れる**といった特徴を持つクラスオブジェクトでした。componentを活用するには、どのItemにcomponentを設定するか指定する必要があります。

HEO Scriptは、
* HEO Scriptを設定したItemに、指定されたcomponentを設定する
* BasicSettingsに、指定されたcomponentが記載されているHeliScriptファイルを追加する

という二つの動作を一緒に行ってくれるコンポーネントです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/a3781bb2-db10-a690-f6c9-ddfe9176b95b.png)

この設定を行うことにより、componentがどのItemに付与されているかを指定することが出来るようになります。

### Propertyについて
VketCloudSDKには、[HEO Property](https://vrhikky.github.io/VketCloudSDK_Documents/latest/HEOComponents/HEOProperty.html?h=%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3)というコンポーネントがあります。このコンポーネントは、Itemに対して、独自の性質を、string型のKeyとValueという辞書形式で設定することが出来ます。
この性質は、HeliScript側で取得、設定することが可能なので、Propertyを使用すると、HeliScriptを書き換えなくても、Unity側で細かい設定を行うことが出来るようになります。

これによって、

* ギミックの調整を素早く行うことが出来る
* componentを再利用しやすくなる
* 複数人開発をしていている場合、ゲームの難易度調整をする人と、スクリプトを作る人で分業することが出来るようになる

といったことが出来るようになります。

Propertyとして設定、使用するためには、
* Propertyを設定したいItemに、HEO PropertyでKeyとValueを設定すること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/be124045-29e1-5e44-e9cb-9b3c62817953.png)

* 同じItemにcomponentを設定して、`Item.GetProperty(string key)`で、設定したKeyを取得すること
```C#:PropertySample.hs
component PropertySample
{
    Item m_item;
    string m_property;
    public PropertySample()
    {
        m_item = hsItemGetSelf();
        m_property = item.GetProperty("property");
        hsSystemWriteLine(m_property);
    }
}
```
で使用することが出来ます。
上記のコードでは、Propertyに設定した項目がコンソール上に表示されます。

### Itemの種類（type）について
Vket Cloudのワールド上に配置されているオブジェクトは、すべてItemとして扱われています。3Dモデル以外にも、音声や、エフェクト、カメラに関してもItemとして扱われています。
それぞれのItemがどのようにふるまうかに関しては、[Itemの種類一覧 / HeliScript関数対応表 -Itemのtype-](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_item_types_functions.html#itemtype)に記載があります。

HeliScriptでItemを扱う上で意識する必要があるのは、Itemの種類によって、使用できるItemクラスの関数が変わるという事です。

たとえば、[Item.Play()](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_class_item.html#play)は、アニメーション、音声、パーティクルなど、**再生**を行うことが出来るItemのtypeに限って使用することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/ec62634e-6798-911b-3684-5a0a56bb4b5e.png)

また、Vket Cloudのバージョンが上がると、Itemのtypeに対して使用できる関数が追加されるとがあります。

そのため、Itemクラスの関数を使いたいときは、何のItemであればその関数が使えるのかをドキュメントの**このメソッドを呼び出し可能なオブジェクトタイプ**を確認して、対象のItemがどのtypeなのか、そのtypeにその関数が使用できるかを把握しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629942/4253ab22-c864-7907-dbab-7d8500d9cd0c.png)

:::note info
Itemについて解説した別記事として[基礎から始めるVket Cloudワールド作成](https://qiita.com/IwahanaFuku/items/d69a99dbab732b5822e7#items)があるので、より詳しく知りたい方はこちらの記事もご参照ください。
:::

 **前 :** [HeliScriptでリッチなアスレチックワールドを作ろう！【コピペで使えるサンプルコード付き】](https://qiita.com/IwahanaFuku/private/63e6bbca2bc1f13ed57e)
 **次 :** [Heliscriptを扱う上での事前設定＆Tips](https://qiita.com/IwahanaFuku/private/8cf9f74a7b2dff5d93d9)

Icons by [Icons8](https://icons8.com/)