Processingでモーショングラフィックスを作るまで その2
モーショングラフィックスっぽい表現を作っていきます!
2回目です。
今回つくったもの
クリックした位置にそれっぽい図形が出現して消えるモーショングラフィックス
課題点
扱う図形が増えるごとにパラメータが多くなるので、そこをうまくまとめる仕組みを考える必要があります。
よく使いそうな表現をクラス可して、どのタイミングでどの動作を行うかといった制御周りとの区別を明確にするような設計を作るとよさそうです。
次回はそのあたりを意識して作ります。
Processingでモーショングラフィックスを作るまで その1
モーショングラフィックスとは
図形やテキストやイラストなどに音や動きを加えたものです。
カッコイイものはネットにいっぱい転がっているので、Google先生かYahoo先生に聞いてみてください。
やること
Processingはグラフィック表現がしやすい言語です。
関数一つで簡単に四角や丸などを書くことができます。
しかも、Javaベースでオブジェクト指向プログラミングもできる・・・
つまり
モーショングラフィックスが作りやすい!気がする!
なので
モーショングラフィックスでよく用いられているような表現を一つづつ分解していってProcessingで作っていきます!
今回やること
四角が移動してきて四角の下からテキストがにゅっと出てくるようなものを作ります。
できたもの
Processingで波を書く方法
波のような滑らかな動きを使うと一気にリッチな表現ができるようになります。
作り方
「Vertex」という、点を打つ関数を使います!
sin()を使って点を打てば、波のようになります。
ポイント
beginShape(); vertex(-100, height/2); for (int i=0; i<width*resolution; i++) { vertex(i/resolution, sin(i/interval+x)*_height+height/2); } vertex(width+100,height/2); vertex(width+100, height); vertex(-100, height); endShape(CLOSE);
vertexは始点から終点まで線でつなぎ、線で囲まれた部分を塗ります。
確実に波だけが描画されるように、始点と終点を画面外に置きます。
for文の中が実際に波を描画している部分です。
エディタ拡張で偽ブラクラを作る【Unity】
無限にウィンドウが開いたり、ホラー画像がでかでかと出たり、明らかにいたずらで作ったwebページ。
うっかりリンクを踏んだら最後。
このwebページをブラクラ(ブラウザクラッシャー)といい、1990年代から、2000年代あたりに多くありました。(今もどこかにあるはず)
つくるもの
ウィンドウが消すほど増えるような仕組みをUnityのエディタ拡張で再現してみたいと思います!
ブラクラとして有名な「You are an idiot!」みたいなものを作ります。
本当に無限にウィンドウが作成されるとUnityクラッシャーになる大変なので、何回か増えたら消せるように制限をかけます。
制作フロー
(1)EditorWindowを作る
上記の通りです。
tofgame.hatenablog.com
(2)EditorWindowを閉じたら新しくEditorWindowを開くようにする
ウィンドウを閉じるとOnDisable ()が呼ばれるので、その中でウィンドウの生成処理を書きます。
(3)画像がチカチカでるようにする
白調の画像と黒調の画像を用意して、交互に表示することで見た目を表現します。
作ったものがこちら
終わりに
ウィンドウ出現数を制限しないと本当に大変なことになります(経験済み)。十分に注意してください・・・
それでは、楽しいブラクラライフを(?)
【古代の】Fortran導入してみた【プログラミング言語】
環境を整える
現在使っているPCがWindows10なので、Macでは事情が違うかもしれません。
Cygwinをインストールしました。
CygwinでFortranのコンパイラもインストールできます。
以下のページを参考にしました。
www2.kuma.u-tokai.ac.jp
いつもの(Hello,world!)
コードを書きます(拡張子は.f08)
tst.f08
program tst print *,'Hello World!' end program tst
実行する
実行できました!
ですが、直接exeファイルを開こうとするとエラーがでたので、ターミナル上で実行したほうが無難そうです。
FizzBuzzを作る
数字が3で割れたらfizz、5で割れたらbuzz、15で割れたらfizzBuzzを出力するやつです。
program fizzBuzz implicit none !暗黙の型宣言を禁止する integer::num !整数型変数宣言 print*,'数字を入力してください' read*, num if(num>=1) then if(mod(num,15)==0) then print*,'fizzBuzz' else if(mod(num,3)==0) then print*,'fizz' else if(mod(num,5)==0) then print*,'buzz' end if else print*,'1以上の整数を入力してください' endif end program fizzBuzz
実行結果
おわりに
計算に強い言語とのことなので、負荷が高い計算をやりたいときにFortranはいいかもしれません。
今後使えるタイミングがあれば積極的に使っていきます。
【Unity】エディタ拡張で音楽をながす方法
EditorWindowを作成してその中で音を出したい!
コンポーネントを作るんじゃなく、直接呼び出したい!
調べました!
AudioUtility
既につよいスクリプトを作っている人がいたので、これを利用して実装します。
このAudioUtility内のメソッドを使ってAulidclipを呼び出します。
https://forum.unity.com/threads/reflected-audioutil-class-for-making-audio-based-editor-extensions.308133/
このAudioUtilityの中でも、PlayClipというメソッドをピックアップして何をしているのかを見てみます。
PlayClip()
using System; using System.Reflection; using UnityEngine; namespace UnityEditor { public static class AudioUtility { public static void PlayClip(AudioClip clip , int startSample , bool loop) { Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); MethodInfo method = audioUtilClass.GetMethod( "PlayClip", BindingFlags.Static | BindingFlags.Public, null, new System.Type[] { typeof(AudioClip), typeof(Int32), typeof(Boolean) }, null ); method.Invoke( null, new object[] { clip, startSample, loop } ); } } }
ここでは、AudioUtilクラスをリフレクションしています。
PlayClipメソッドを呼び出して音を鳴らします。
リフレクションについては、以下のページも是非みてください!
tofgame.hatenablog.com
実際に音楽をかける
新しいウィンドウを開いた時にメソッドを呼び出すようにエディタ拡張をします。
using UnityEditor; using UnityEngine; public class EditorWindow : EditorWindow { private static AudioClip audioClip; [MenuItem("music/tst")] public static void Open () { var window = CreateInstance<EditorWindow>(); window.Show(); audioClip = Resources.Load<AudioClip>("bgm1"); AudioUtility.PlayClip(audioClip,0,true); //ここで呼び出し!! } private void OnDisable () { AudioUtility.StopClip(audioClip); } }
複数ウィンドウを作るとその分だけ音楽がながれます。
おわりに
作業中に音楽をならすミュージックプレイヤーウィンドウとかも作れそうですね!
3秒でわかる「リフレクション」【UnityC#】
リフレクションとは
メタデータを使ってクラスやメソッドの情報にアクセスすることです!
メタデータは、クラス名やメソッド名、変数などの、プログラムデータに関する情報のことです。
リフレクションを使うことで、メタデータの取得はもちろん、メタデータからクラスや関数を呼び出すこともできます。
アセンブリからデータを呼び出すこともできます!すごい!
リフレクションプローブ(Reflection Prove)とは無関係です。
今回は、他クラスのメタデータの取得とメソッドの呼び出しを試してみます。
メタデータを見てみる
まずはメタデータを取得する対象のクラスを定義します。
public class TestClass { public int num; private int numPrivate; public void Method () { } private void MethodPrivate () { } }
実際にメタデータを取得するスクリプトを書きます!
using UnityEngine; using System.Reflection; using System; public class TestReflection : MonoBehaviour { private BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; private void Start () { Test(); } private void Test () { Type type = Type.GetType("TestClass"); //メンバーのデータ Debug.Log("-----Member-----"); foreach(var i in type.GetMembers(bindingFlags)) { Debug.Log(i); } //変数のデータ Debug.Log("-----field-----"); foreach(var i in type.GetFields(bindingFlags)) { Debug.Log(i); } //メソッドのデータ Debug.Log("-----Method-----"); foreach(var i in type.GetMethods(bindingFlags)) { Debug.Log(i); } } }
ここでのポイント
リフレクションをするために含めます。
using System.Reflection; using System;
「TestClass」クラスを取得します。
Type type = Type.GetType("TestClass");
これらのメソッドでメタデータを取得します。
type.GetMembers(); type.GetFields(); type.GetMethods();
type.Get~系のメソッドの引数に入れることで、アクセスする対象を決めます。
private BindingFlags bindingFlags =
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.DeclaredOnly;
「Instance」「Static」はどちらかがなければいけなく、また、「Public」「NonPublic」もどちらかがなければいけません。
「Instance」「Static」「Public」「NonPublic」は名前から意味が分かると思います。
「DeclaredOnly」は対象にするクラスのみをアクセスする、という意味です。
BindingFlagsについて詳しく知りたい方は以下のページを見てください!
docs.microsoft.com
実行する
うまく取れていそうですね!
メンバーの.ctor()はコンストラクタです!
次はメソッドを実際に呼び出してみます。
メソッドを呼び出してみる
他クラスからSumメソッドを呼び出して足し算をしてみます!
TestClassを書き換える
Sumメソッドを定義します。
public class TestClass { public int Sum (int a,int b) { return a + b; } }
TestReflectionを書き換える
TestClassのSum()メソッドをSum()メソッドでラップします!
using UnityEngine; using System.Reflection; using System; public class TestReflection : MonoBehaviour { private Type[] argType = new Type[] { typeof(Int32),typeof(Int32) }; private BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; private void Start () { Debug.Log(Sum(1,3)); } private int Sum (int a,int b) { object[] args = { a,b }; Type type = Type.GetType("TestClass"); object tmp = Activator.CreateInstance(type); return (int)type.GetMethod("Sum",bindingFlags,null,argType,null).Invoke(tmp,args); } }
ここでのポイント
「TestClass」のインスタンス生成
object tmp = Activator.CreateInstance(type);
メソッドの引数を定義
private Type[] argType = new Type[] { typeof(Int32),typeof(Int32) };
メソッドを取得してリターン
private int Sum (int a,int b) { object[] args = { a,b }; Type type = Type.GetType("TestClass"); object tmp = Activator.CreateInstance(type); return (int)type.GetMethod("Sum",bindingFlags,null,argType,null).Invoke(tmp,args); }
GetMethod()を使用してTestClassのSum()メソッドを取得しています。
ここでは1、2、4個目の引数を扱っています。3、5個目はnullでOKです。
内容としては、
[1]メソッドの名前
[2]BindingFlags
[3](Binderクラス)
[4]引数の型
[5](ParameterModifier構造体)
になっています。
実行する
これで関数呼び出し完了です!
参考にしました
3秒でわかる「フラグメントシェーダー」【Unity】
フラグメントシェーダーとは
画面に投影される予定のピクセルの色データを加工するシェーダーです!
頂点シェーダーで加工したデータが別の工程を経た後、画面に投影される分のピクセルデータに変換されます。
そのピクセルデータを受け取り、再計算することでいろんな見えかたに変化させることができます。
シェーダーのコード
Shader "Unlit/NewUnlitShader"{ Properties{ _MainTex("Texture", 2D) = "white" {} } SubShader{ Tags { "RenderType" = "Opaque" } LOD 100 Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag //入力用の構造体 struct appdata { float4 vertex : POSITION; //頂点の座標 float2 uv : TEXCOORD0; //頂点に設定されたuv座標 }; //出力の構造体 struct v2f { float4 vertex : SV_POSITION; //頂点の座標 float2 uv : TEXCOORD0; //頂点に設定されたuv座標 }; //頂点シェーダー v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //頂点の座標をクリップ空間での座標に変換 o.uv = v.uv; //uv座標はそのまま return o; } sampler2D _MainTex; //プロパティで設定したテクスチャデータ //フラグメントシェーダー fixed4 frag(v2f i) : SV_Target{ fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
フラグメントシェーダーに関わる部分
#pragma fragment frag
フラグメントシェーダーメソッドを設定しています。
sampler2D _MainTex; //プロパティで設定したテクスチャデータ
Propertiesで設定した_MainTexを使用するために変数を宣言します。
fixed4 frag(v2f i) : SV_Target{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ここの部分がフラグメントシェーダーのメソッドです。
出力データとして「SV_Target」セマンティクスを設定しています。(シェーダーの入出力にはセマンティクスを設定しなければいけません)
「SV_Target」は出力のカラー値を表しています。
「tex2D」メソッドで「_MainTex(テクスチャのデータ)」と「i.uv(ピクセルデータに補完されたuv座標)」を引数にとり、色のデータに変換しています。
その後そのデータをそのまま返します。
いろいろな処理を経て出力
フラグメントシェーダーでは色データをいじることができます。色々試せそうです。
3秒でわかる「テイラー展開」
式
付近で近似するとして、
をテイラー展開
まずはx=0で1次近似します。
とだとあまりにも違うので、次はx=0で2次近似をします。
なので、1次近似と同じ値になりました。次は3次近似をします。
少し近づきました!
計算していくとわかりますが、下記の式のようになります。