見出し画像

ClusterScriptは力を入れずして天地を動かし…

1 現代の言霊

ClusterScriptは力を入れずして天地を動かし
目に見えぬ鬼神をもあはれと思わす。

平安時代からタイムスリップしてきた
古今和歌集の選者『紀貫之』に
ClusterScriptの教科書を編纂してもらったら
序文は、きっと
こんな書き出しになるだろう(笑)

前回は
イナバさんの『折りたたみ式階段』のscriptと
その設計思想を『MorseCode』として紹介した。

今回は
その『MorseCode』をベースに
むさしが制作した『ふうとんよーよー』の構造と
その仕組みを解説する。

時折
ClusterScriptと『やまとうた』の
奇妙な共通点を紹介するコーナーを挟み込むが
作者のニッチな趣味的嗜好なので
許してくれ(笑)

2 ヨーヨーの動き

『ふうとんよーよーVR』の動きを
動画で確認してみよう!

ヨーヨーがくるくると回りながら
糸を伸ばして前方に飛び出していく。

そして、少しの間、任意の場所にとどまり
その後、糸を縮ませて手元に戻ってくる。

『MoseCode』は
こうした反復運動を得意とするscriptなのだ!

【補足】
script上は、上下の動きだが
VR版は手首を返せるので前後の動きになる。

3 ヨーヨーの構造

次に
Unity画面のスクショで構造を確認してみよう!

ヒエラルキー

『YOYO』は
様々な機能を持たせる実体のない器
『Laska』は
高さ調整やのちの魔改造のための実体のない器

そして
実体のあるものの構造は大きく2つに分かれる。
『kinkan』=金環(指輪)と
『yoyo』=ヨーヨーだ!

『kinkan』を親とする子『catch』も
実体はないがスマホ版のつかむ位置を司る
重要な役割を持つ。

つかむ位置

『kinkan』を親とする子の『ito』は
長さ10cmの糸を7本重ね合わせ
『yoyo』の中に隠している。

まるで『シュレディンガーの猫』のよう… 
量子的だ(笑)

重なり合う7本の糸
スッポリ収まる

言霊のレトリック 『掛詞』

1つの言の葉に複数の意味を
重ね合わせることができる
『やまとうた』の修辞法『掛詞』… 
ClusterScriptは、
複数のオブジェクトを重ね合わせたり
引き離したりできるのだ!

4 ClusterScript

では、ClusterScriptを書いていこう!

始めに
動くものに定義づけをしていくぞ!

『yoyo』は、移動と回転の両方を定義すること
『ito』は、1~7まですべて定義することが
ポイントだ!

効果音はオプションなので説明を割愛する。

//移動定義
const step0 = $.subNode("yoyo");
const step1 = $.subNode("ito1");
const step2 = $.subNode("ito2");
const step3 = $.subNode("ito3");
const step4 = $.subNode("ito4");
const step5 = $.subNode("ito5");
const step6 = $.subNode("ito6");
const step7 = $.subNode("ito7");

//回転定義
const speed = 1000.0;
const axis = new Vector3(1.0, 0.0, 0.0);
const subNode = $.subNode("yoyo");

//効果音定義
const se1 = $.audio("Audio1");
const se2 = $.audio("Audio2");

次に『持つトリガー(onGrab)』だが
ここでは、『onGrab』と対になる
『isGrab』の関連性を覚えておこう!

『isGrab』のくだりは
効果音を鳴らすには不要だが
のちの魔改造のためにつけている(笑)

//持つトリガー
$.onGrab(isGrab => {
  let isGrab = $.state.isGrab;
  isGrab = !isGrab;
  $.state.isGrab = isGrab;

//効果音指令
se1.play();
});

次に『使うトリガー(onUse)』だが
ここでは、『onUse』と対になる
『isDown』の関連性を覚えておこう!

画像は
使うボタンを押したときに
糸を下に向かって1本1本
10cm間隔で並べ
ヨーヨーをその先端まで運ぶscriptだ!
使うボタンを離すと元に戻る。

//使うトリガー
$.onUse(isDown => {
    let isDown = $.state.isDown;
    isDown = !isDown;
    $.state.isDown = isDown;

 //移動指令
    const pos0 = Vector3(0, isDown ? -0.7:0,0);  
    step0.setPosition(pos0);
    const pos1 = Vector3(0, isDown ? -0.0:0,0);  
    step1.setPosition(pos1);
    const pos2 = Vector3(0, isDown ? -0.1:0,0);  
    step2.setPosition(pos2);
    const pos3 = Vector3(0, isDown ? -0.2:0,0);  
    step3.setPosition(pos3);
    const pos4 = Vector3(0, isDown ? -0.3:0,0);  
    step4.setPosition(pos4);
    const pos5 = Vector3(0, isDown ? -0.4:0,0);  
    step5.setPosition(pos5);
    const pos6 = Vector3(0, isDown ? -0.5:0,0);  
    step6.setPosition(pos6);
    const pos7 = Vector3(0, isDown ? -0.6:0,0);  
    step7.setPosition(pos7);

//効果音指令
se2.play();  
})

最期の画像は
使うボタンを押したときに
ヨーヨーを(※前方に)回転させ
離すと止まるscriptだ!

※方向は前段定義文に記述している。

Code文の中に
『onUse』と関連性のある
『isDown』が登場していることに注目だ!

//回転処理
$.onUpdate(deltaTime => {
  if (!$.state.initialized) {
    $.state.initialized = true;
    $.state.pivot = $.getRotation();
    $.state.time = 0.0;
    $.state.isDown = false;
  }

  if (!$.state.isDown) return;

  $.state.time += deltaTime;

  subNode.setRotation(subNode.getRotation().multiply(new Quaternion().setFromAxisAngle(axis, speed * deltaTime)));
});

言霊のレトリック 『縁語』

『使うトリガー(onUse)』下において
回転処理を実行する鍵は『isDown』なのだ!

『やまとうた』には
『縁語』という関連性の深い言葉を
歌の中に散りばめる連想ゲームのような
修辞法がある。

『onGrab』と『isGrab』
『onUse』と『isDown』のような
『縁語』はほかにもあるので
探してみるといい。

この『縁語』を意識すれば
ClusterScriptの難しい課題を
クリアできる可能性が高まるぞ!

6 言霊のレトリック 『本歌取り』

『やまとうた』には
『本歌取り』という修辞法がある。

本歌を背景に新しい歌を創作することで
歌に奥行きを持たせる技法だそうだ。

そう! だから
先人たちのClusterScriptを活用するときは
本歌とその詠み人をリスペクトしつつ
アイテムに
新しい息吹を吹き込む努力を
忘れないようにしたい。

さて、次回は
シリーズ最終回…
できれば、学研の『科学』と『学習』のような
付録を用意したいと考えている。

では、また
その日にお会いしよう!