LoginSignup
9
5

More than 1 year has passed since last update.

Unity/C#のための「多分最速」のスクリプト言語作った。#1

Last updated at Posted at 2023-02-12

Unityのためのアロケーションの少ない静的型付け言語が欲しかったので、作っています。
まだまだ未完成ですが、とりあえず公開しました。
https://github.com/Akeit0/YukataScript
--追記 タイトルに追加したんですけど多分(C#で動くもので、C#の関数を呼び出すのが)最速です。

--追記 続きものにしました。->#2 https://qiita.com/aakei/items/5145d6e9922cff6c99fc

--追記(2/19) WebGLDemo 作りました -> https://akeit0.github.io/YukataScript/
--追記(2/20) 説明不足でしたが、C#上で動的IL生成などを使わず動くものなので、C#よりも遅いです。
-- Zennでの解説記事

目次

  1. 使い方

  2. どれだけ速いか

  3. いいところ

  4. ダメなところ

  5. まとめ

使い方

C# 側ではこんなコード書いて

using YS;
using YS.Fields;
using YS.VM;

[TextAreaAttribute(3,20)]
public string code;
public TextAsset TextFile;
public bool DoPerformanceCheck = false;
VirtualMachine _engine=new (32,32,32);

Compiler _compiler = new Compiler();

public List<NameVariablePair> Fields;
       
public void Compile() {
      Wrapper.Init();
     _compiler.SourceCode = TextFile != null ? TextFile.text : code;
      foreach (var field in Fields) {
            if (field is {IsValid: true}) _engine.AddVariable(field.Name, field.Variable);
      }
      _compiler.Compile(_engine, DoPerformanceCheck);       
}
public void Run() {
      if (DoPerformanceCheck) {
           using (ElapsedTimeLogger.StartNew("run")) {
                 _engine.Process();
           }
      }else {
           _engine.Process();
       }
}
async void RunAsync() {
     try {
         await   _engine.RunAsync();
         }
     catch (Exception) {
         Debug.Log("catch");
         throw;
     }    
      Debug.Log("End");
}

Codeをこんな風に書いてみると

using UnityEngine
print("Start")
for i in ..100{
    await 30.ms()
    transform.position+=new Vector3(f,0,0)
}

YSAsync.gif
こうなる。

どれだけ速いか

そもそもどれくらい速いですが、C#では

for (int i = 0; i < 100000; i++) {
    v3 += new Vector3(f,1,1);
}

これが4.4689 msで
YukataScriptでは

using UnityEngine
for i in ..100000{
    v3+=new Vector3(f,1,1)
}

これが28.7999 msです。だいぶC#に近づけたと思います。
まあint 型の足し算で比べたらだいぶ遅くなりますが、、、
-- 追記22.1546msになりました。
-- 追記(2/20) 18ms程度になりました。

いいところ

  • フィールドをなんでも選択できるのは便利
  • PlayModeじゃなくても動く(上のgifもエディタモード)
  • 事前コード生成でデリゲートでラッパーを作っているので、パフォーマンスも良いです。
  • コンパイル後はC# と同じアロケーションしかしません。
  • IL2CPP上でコンパイルして動きました。(速度変わらず)
  • await が使いやすい(ついでにUniTaskもAwaiterと一緒にコード生成すれば使える)。
  • オーバーロード解決できる
  • 拡張メソッド使える。

ダメなところ

  • Genericsほぼできない(解決したい)
  • 関数もクラスも定義できない(解決したい)
  • 上ができても再帰は絶対できない(解決しない)
  • バグだらけ

まとめ

まだまだですが、多分可能性は無限大です。
https://github.com/Akeit0/YukataScript
続き https://qiita.com/aakei/items/5145d6e9922cff6c99fc

9
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5