スクリプトでライトをコントロールする
こちらでも扱っていますが、たまに忘れるのでメモ代わりに。
prince9.hatenablog.com
注意点としては、スクリプトを直接ライトにつけると、プレイ時にエラーが出ます。
空のオブジェクトを作って、「public GameObject slight」などにしてライトをドラッグ&ドロップする必要があります。
準備
下記の3点を作ります。
・空のゲームオブジェクト(「GameObject」メニュー→「Create Empty」
・明るさをコントロールしたいライト
・スクリプト(「Assets」を右クリックして、C# Script)
スクリプト
1.スクリプトを空のゲームオブジェクトにドラッグ&ドロップする
2.空のゲームオブジェクトをクリックし、Inspectorの「slight」にコントロールしたいライトをドラッグ&ドロップする
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LightScript : MonoBehaviour { //以下2つ必須 public GameObject slight; float LIntensity; // Use this for initialization void Start () { LIntensity = slight.GetComponent<Light>().intensity; } // Update is called once per frame void Update () { //ライトの明るさ LIntensity = 100f; slight.GetComponent<Light>().intensity = LIntensity; } }
同じプロジェクト間、違うスクリプトでのデータの受け渡し
同じプロジェクトの別のスクリプトで変数とそのデータを使いまわしたいことがあります。
そのときのデータを受け渡し(正確には読み取り)のメモです。
準備
1.「GameObject」メニュー→「Create Empty」で空のオブジェクトを2つ作る
2.それぞれの名前を「Send」「Recieve」などにする。同じ名前にしないよう気をつける
3.「Assets」を右クリックしてスクリプトを2つ作り、「SendScript」「RecieveScript」などと名前をつける
4.「Send」オブジェクトには「SendScript」を、「Recieve」オブジェクトには「RecieveScript」をドラッグ&ドロップする
5.「SendScript」と「RecieveScript」をダブルクリックしてスクリプトを書く
スクリプト 「SendScript」データを送る方(参照先)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SendScript : MonoBehaviour { //この値を「RecieveScript」に送る(参照する) public int ScoreData = 100; void Start () { } // Update is called once per frame void Update () { } }
スクリプト 「RecieveScript」データを受け取る方(処理する先)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class recieveScript : MonoBehaviour { //この2つの変数が必要 GameObject scoreBox; SendScript script; // Use this for initialization void Start () { //Sendというオブジェクトを探す scoreBox = GameObject.Find ("Send"); script = scoreBox.GetComponent<SendScript>(); //新しく変数を作って、「SendScript」の変数「ScoreData」を入れる int score = script.ScoreData; Debug.Log ("スコアは" + score); } // Update is called once per frame void Update () { } }
VRMキャラクターの表情を一定時間ランダムに変える
こちら2つの応用編です。コルーチン使用部分はたぶん力技。
prince9.hatenablog.com
prince9.hatenablog.com
マイクの最大音量を計測し、そのときにランダムに表情を変えるというスクリプトを書いてる途中のメモです。
キーボードを押すごとにランダムに表情が変わり、2秒後に元に戻ります。
準備
こちらを参考にして、必要な表情を作成しておきます。
prince9.hatenablog.com
スクリプト
「BlendList = new List
using System.Collections; using System.Collections.Generic; using UnityEngine; using VRM; public class FaceKeep : MonoBehaviour { private VRMBlendShapeProxy proxy; public List<string> BlendList; private string rBlend; //「処理を止める処理」を停止するか否か bool isRunning = false; // Use this for initialization void Start () { //使いたい表情のリスト BlendList = new List<string>(){"Neutral","Smile","Setunai","SHINKEN"}; } // Update is called once per frame void Update () { if (proxy == null) { proxy = GetComponent<VRMBlendShapeProxy>(); } else { //上矢印キーをキーコードで判断 if(Input.GetKeyDown(KeyCode.UpArrow)) { //ランダムにリストから表情を選ぶ rBlend = BlendList[ Random.Range(0, BlendList.Count) ]; Debug.Log(rBlend); proxy.SetValue(rBlend, 1.0f); //時を止める処理 StartCoroutine(TimeStop()); } else { proxy.SetValue(BlendList[0], 1.0f); } } } IEnumerator TimeStop() { //「処理を止める処理」を開始する if( isRunning ) { yield break; } isRunning = true; //2秒時を止める yield return new WaitForSeconds(2.0f); //2秒後表情を通常に戻す proxy.SetValue(rBlend, 0f); proxy.SetValue(BlendList[0], 1.0f); //「処理を止める処理」を停止する(動き出す) isRunning = false; } }
一定以上のボリュームのときに大きさが変わる
音量が一定以上になったときにキャラクターの表情を変えたいと思い、そのテストとしてやってみました。
一定以上のボリュームになったら、オブジェクトのサイズと色が変わります。
ただ実際に実装したいのが「表情」なので、サイズと色が変わったらそれを2秒保持する(=2秒次の処理を止める)ことを行なっています。
瞬間的に表情が変わり続けるのはどうかと思うので・・・
数秒後に処理を行う、など時間を扱う処理である「コルーチン」を使いましたが、力技なような気がしてます。
大きさの変化に関して参考にさせて頂いたのがこちら。
tips.hecomi.com
前準備 再生したいサウンドファイルを設定する
スクリプトを書いて、オブジェクトにコードをドラッグ&ドロップします。
そうするとInspectorに「Audio Source」の項目ができるので、▶︎をクリックして「AudioClip」に再生したいサウンドファイルをドラッグ&ドロップします。
スクリプト
状態を保持する時間を作っているので、音との同期が確実に正確ではありませんが、実験ではまあまあでした。
using System.Collections; using System.Collections.Generic; using UnityEngine; /* ボリュームに合わせてオブジェクトの大きさを変えたい場合に必要 using System.Linq; */ [RequireComponent(typeof(AudioSource))] public class SoundMoveScript : MonoBehaviour { //256を1024にするともっと細かく検出できる float[] wData = new float[256]; //「処理を止める処理」を停止するか否か bool isRunning = false; private AudioSource audioS; // Use this for initialization void Start () { audioS = GetComponent<AudioSource>(); } // Update is called once per frame void Update () { /* ボリュームの変化に合わせてオブジェクトの大きさを変える場合はここだけ。他の変数との兼ね合いで変数名を変えてますが、例ほぼそのままです AudioListener.GetOutputData(wData, 1); var volume = wData.Select(x => x*x).Sum() / wData.Length; transform.localScale = Vector3.one * volume * 10; */ float vol = GetMaxVolume(); Debug.Log(vol); //ボリューム最大値が0.5以上のとき if(vol >= 0.5) { gameObject.GetComponent<Renderer>().material.color = Color.blue; transform.localScale = new Vector3(4, 4, 4); } else { //0.5以上になったときの処理を停止する=状態を保持して、次の状態へ移行する StartCoroutine(TimeStop()); } } float GetMaxVolume() { float a = 0; audioS.GetOutputData(wData,0); foreach(float vMax in wData) { //最大値を取り出す a += Mathf.Max(vMax); } return a/256.0f; } IEnumerator TimeStop() { //「処理を止める処理」を開始する if( isRunning ) { yield break; } isRunning = true; //2秒止める(状態を保持する) yield return new WaitForSeconds(2.0f); //次の処理へ移行 transform.localScale = new Vector3(1, 1, 1); gameObject.GetComponent<Renderer>().material.color = Color.red; //2秒止める(状態を保持する) yield return new WaitForSeconds(2.0f); //「処理を止める処理」を停止する(動き出す) isRunning = false; } }
VRMで数秒後に表情を変化させる
音楽のアタックに合わせて表情を変えようとしてる途中の産物です。
笑顔の表情の数秒後に元の表情に戻したい場合の処理をメモしました。
表情をつくる
VRoidや購入したりダウンロードしたVRMファイルはあらかじめいくつかの表情がプリセットとして登録されています。
そのプリセットを呼び出す場合は、
proxy.SetValue("Neutral", 1.0f);
となります。この場合、「Neutral」がプリセット名(BlendShapeName)になります。
プリセットを作成する場合は、
1.「Hierarchy」のキャラクターをクリックして、Playボタンを押す
2.「Inpector」→「VRM Blend Shape Proxy」の「Blend Shape Avatar」→「Blend Shape(Blend Shape Avatar)」をダブルクリックする
3.「Add BlendShapeClip」を押して、作りたい表情の名前を入力する。その後Saveを押して保存する。
このときの名前がプリセット名となります
4.「▶︎ Face」の▶︎を押して展開し、スライダを動かして表情をつくる
5.表情を作成したら、「Apply」を押して登録する
6.スクリプトの中で呼び出すときは、
proxy.SetValue("Smile", 1.0f);
とする。この場合は「Smile」が3.で登録したプリセット名
VRMで表情を変化させる
ご本家の通り、下記の2つが必要になります。
BlendShapeを操作する - dwango on GitHub
・proxy = GetComponent
・proxy.SetValue("Smile", 1.0f) 表情ON
・proxy.SetValue("Smile", 0f) 表情OFF
例として、キーボードで表情を変える例が下記です。
using System.Collections; using System.Collections.Generic; using UnityEngine; using VRM; public class FaceChange : MonoBehaviour { private VRMBlendShapeProxy proxy; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (proxy == null) { proxy = GetComponent<VRMBlendShapeProxy>(); } else { //キーボード入力 if(Input.GetKey(KeyCode.UpArrow)) { //表情呼び出し proxy.SetValue("Neutral", 1.0f); } else { proxy.SetValue("Neutral", 0f); } if(Input.GetKey(KeyCode.DownArrow)) { proxy.SetValue("Smile", 1.0f); } else { proxy.SetValue("Smile", 0f); } if(Input.GetKey(KeyCode.RightArrow)) { proxy.SetValue("Setunai", 1.0f); } else { proxy.SetValue("Setunai", 0f); } if(Input.GetKey(KeyCode.LeftArrow)) { proxy.SetValue("SHINKEN", 1.0f); } else { proxy.SetValue("SHINKEN", 0f); } } } }
一定時間後に表情を変える
笑顔から一定時間後に元の表情に戻したい場合の処理がこちらです。
TimeCount -= Time.deltaTime;を使っています。
using System.Collections; using System.Collections.Generic; using UnityEngine; using VRM; public class FaceKeep : MonoBehaviour { private VRMBlendShapeProxy proxy; //3秒後に表情を戻す(別の表情にする) float TimeCount = 3; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (proxy == null) { proxy = GetComponent<VRMBlendShapeProxy>(); } else { proxy.SetValue("Smile", 1.0f); //表情処理終章後にカウント開始 TimeCount -= Time.deltaTime; //カウントが0になったら=この場合は3秒経ったら if(TimeCount <= 0) { proxy.SetValue("Smile", 0f); //表情変化 proxy.SetValue("Neutral", 1.0f); } } } }
マウスドラッグでオブジェクトを動かす
ググってみて動かしてみたら、どれをやっても動かない。英語で検索してみたところ、解決は「Main Camera」のタグを「MainCamera」にするとのこと。どの日本語サイトもそれについては言及しておらず、動かない!とマウスを投げる方がいそうなので、メモしました。
カメラのタグを「MainCamera」にする
Hierarchyの「Main Camera」をクリックし、Inspectorの「Tag」を「MainCamera」にする
スクリプトを書く
下記のスクリプトを書きます。「Vector3 mousePos」のZの値は適当でOKです。マウスはXY軸にしか動かないからですが、ないとエラーになってしまいます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MouseDragScript : MonoBehaviour { private void OnMouseDrag() { //10の値は適当。マウスはXY方向にしか動かないので、Z軸は適当な値でOK。値なしだと動かない Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10); Vector3 objectPos = Camera.main.ScreenToWorldPoint(mousePos); transform.position = objectPos; } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
TidalCyclesでライブコーディング 準備編
プログラミングをしつつ音を生成したりVJしたりする「ライブコーディング」が急にしたくなったので、環境構築のメモです。
今回は「TidalCycles」という音生成の環境を使って演奏していきます。
www.youtube.com
TidalCyclesのインストール(Mac)
1.下記から「Download.zip」をクリックし、ダウンロードする
tidal-bootstrap
2.下記からAppleIDでログインし、自分のOSに合ったcommand line toolsをダウンロードする
Sign in with your Apple ID - Apple Developer
3.「ユーティリティ」→「ターミナル」アプリを立ち上げ、下記を入力してエンターキーを押す
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
4.1.でダウンロードした中にある「tidal-bootstrap.command」をダブルクリックする。TidalCyclesのインストールが始まる。
途中「y/n (or press Enter to accept)」とキーボード入力を求められたら、「Y」キーを押してからエンターキーを押す
5.「プロセスが完了しました」という表示が出たら、ターミナルを終了させる
6.「アプリケーション」の中にある「SuperCollider」アプリをダブルクリックして立ち上げる
7.エディタが立ち上がるので、左の画面に下記を入力する
include("SuperDirt")
8.「include("SuperDirt")」の部分をマウスドラッグして選択し、エンターキーを押す
9.インストールが始まるので、しばし待つ。「-> SuperDirt」が出てきたら終了
10.SuperColliderを終了させ、再度起動させる
11.「SuperDirt.start;」と入力し、この部分をマウスドラッグで選択して「command+enter」キーを押す
12.右下に「SuperDirt: listening to Tidal on port 57120」と出たらOK
13.「アプリケーション」から「Atom」をダブルクリックして開く
14.「Atom」メニュー→「Preference」を選択し、「+Install」をクリックする
15.「Tydalcycles」と入力して、「Package」を押す
16.Tydalcyclesの「Install」をクリックしてインストールする
Tydalcyclesを動かす
1.SuperColliderで右下に「SuperDirt: listening to Tidal on port 57120」と出ているか確認する
2.Atomを立ち上げ、「Packages」→「TidalCycles」→「Boot TidalCycles」を選択する
3.「d1 $ sound "bd sn"」と入力する
4.「File」→「Save」を選択し、「Test.tidal」など、拡張子が「.tidal」にして保存する
5.「d1 $ sound "bd sn"」をドラッグして選択し、「command+enter」キーを押す
上記の5.でエラーが出た場合
1.下記から「Download Core」をクリックしてダウンロード、インストールする
www.haskell.org
2.ターミナルを立ち上げ、「cabal install tidal」と入力してエンターキーを押す
3.SuperColliderを立ち上げ「SuperDirt.start;」と入力し、この部分をマウスドラッグで選択して「command+enter」キーを押す
4.Atomで「Tydalcyclesを動かす」の4.で保存したファイルを開く
5.「Packages」→「TidalCycles」→「Boot TidalCycles」を選択する
6.「d1 $ sound "bd sn"」と入力する
7.音が鳴る。止めたいときは「hush」と入力して、この部分をマウスドラッグで選択して「command+enter」キーを押す