トーフメモ

主にゲーム制作

Processingでモーショングラフィックスを作るまで その2

f:id:tofgame:20190518234006p:plain

モーショングラフィックスっぽい表現を作っていきます!
2回目です。

今回つくったもの

クリックした位置にそれっぽい図形が出現して消えるモーショングラフィックス
f:id:tofgame:20190518233555g:plain

課題点

扱う図形が増えるごとにパラメータが多くなるので、そこをうまくまとめる仕組みを考える必要があります。
よく使いそうな表現をクラス可して、どのタイミングでどの動作を行うかといった制御周りとの区別を明確にするような設計を作るとよさそうです。
次回はそのあたりを意識して作ります。

次回

tofgame.hatenablog.com


Processingでモーショングラフィックスを作るまで その1

f:id:tofgame:20190518234829p:plain

モーショングラフィックスとは

図形やテキストやイラストなどに音や動きを加えたものです。
カッコイイものはネットにいっぱい転がっているので、Google先生かYahoo先生に聞いてみてください。

やること

Processingはグラフィック表現がしやすい言語です。
関数一つで簡単に四角や丸などを書くことができます。
しかも、Javaベースでオブジェクト指向プログラミングもできる・・・
つまり
モーショングラフィックスが作りやすい!気がする!
なので
モーショングラフィックスでよく用いられているような表現を一つづつ分解していってProcessingで作っていきます!

今回やること

四角が移動してきて四角の下からテキストがにゅっと出てくるようなものを作ります。

できたもの

f:id:tofgame:20190517234512g:plain

次回のモーショングラフィックスtofgame.hatenablog.com


Processingで波を書く方法

f:id:tofgame:20190517010953g:plain
波のような滑らかな動きを使うと一気にリッチな表現ができるようになります。

作り方

「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文の中が実際に波を描画している部分です。

ソースコード

SourceTreeにGithubアカウントを追加する

f:id:tofgame:20190428235106j:plain

個人的に忘れそうだったので備忘録として残します。

環境

【OS】Windows10
【SourceTree】3.1.2.3027

SourceTreeにアカウントを追加する

ツール -> オプション でオプションを開き、認証タブをクリックすると以下のような表示になります。
f:id:tofgame:20190512021503p:plain

「追加」をクリックすると「ホスティングアカウントを設定」と出ます。
f:id:tofgame:20190512021751p:plain

ホスティングサービスの部分をGithubに変更。
ここで「OAuthトークンを再読み込み」をクリック(ここが一番重要)
そうするとブラウザが立ち上がり認証画面に飛ぶので、認証。
f:id:tofgame:20190512022214p:plain

これでGithubアカウントが追加されます。
f:id:tofgame:20190512022318p:plain

エディタ拡張で偽ブラクラを作る【Unity】

f:id:tofgame:20190512002547p:plain

無限にウィンドウが開いたり、ホラー画像がでかでかと出たり、明らかにいたずらで作ったwebページ。
うっかりリンクを踏んだら最後。
このwebページをブラクラ(ブラウザクラッシャー)といい、1990年代から、2000年代あたりに多くありました。(今もどこかにあるはず)

つくるもの

ウィンドウが消すほど増えるような仕組みをUnityのエディタ拡張で再現してみたいと思います!
ブラクラとして有名な「You are an idiot!」みたいなものを作ります。
本当に無限にウィンドウが作成されるとUnityクラッシャーになる大変なので、何回か増えたら消せるように制限をかけます。

制作フロー

(1)EditorWindowを作る

上記の通りです。
tofgame.hatenablog.com

(2)EditorWindowを閉じたら新しくEditorWindowを開くようにする

ウィンドウを閉じるとOnDisable ()が呼ばれるので、その中でウィンドウの生成処理を書きます。

(3)画像がチカチカでるようにする

白調の画像と黒調の画像を用意して、交互に表示することで見た目を表現します。

(4)音が鳴るようにする

AudioUtilityを使用して音を鳴らします。
tofgame.hatenablog.com


作ったものがこちら

youtu.be

終わりに

ウィンドウ出現数を制限しないと本当に大変なことになります(経験済み)。十分に注意してください・・・
それでは、楽しいブラクラライフを(?)

【古代の】Fortran導入してみた【プログラミング言語】

f:id:tofgame:20190428235503j:plain

Fortran、使ったことないな

なんとなく気になって導入してみました!
どうやら1950年代後半からあったプログラミング言語らしいです。
今回はFortran2008で書きます。

環境を整える

現在使っているPCがWindows10なので、Macでは事情が違うかもしれません。
Cygwinをインストールしました。
CygwinFortranコンパイラもインストールできます。
以下のページを参考にしました。
www2.kuma.u-tokai.ac.jp

いつもの(Hello,world!)

コードを書きます(拡張子は.f08)

tst.f08

program tst
  print *,'Hello World!'
end program tst

実行する

f:id:tofgame:20190509220745p:plain

実行できました!
ですが、直接exeファイルを開こうとするとエラーがでたので、ターミナル上で実行したほうが無難そうです。
f:id:tofgame:20190509221259p:plain

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

実行結果

f:id:tofgame:20190511211838p:plain

おわりに

計算に強い言語とのことなので、負荷が高い計算をやりたいときにFortranはいいかもしれません。
今後使えるタイミングがあれば積極的に使っていきます。

【Unity】エディタ拡張で音楽をながす方法 

f:id:tofgame:20190428235503j:plain
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);
    }
}

複数ウィンドウを作るとその分だけ音楽がながれます。

youtu.be

おわりに

作業中に音楽をならすミュージックプレイヤーウィンドウとかも作れそうですね!

3秒でわかる「リフレクション」【UnityC#】

f:id:tofgame:20190428235503j:plain

リフレクションとは

メタデータを使ってクラスやメソッドの情報にアクセスすることです!

メタデータは、クラス名やメソッド名、変数などの、プログラムデータに関する情報のことです。

リフレクションを使うことで、メタデータの取得はもちろん、メタデータからクラスや関数を呼び出すこともできます。

アセンブリからデータを呼び出すこともできます!すごい!

リフレクションプローブ(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

実行する

f:id:tofgame:20190511013422p:plain
うまく取れていそうですね!
メンバーの.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構造体)
になっています。

そして、Invoke()で関数を実行します。
引数に「TestClass」のインスタンスと実際に入れた引数を入れます。

実行する

f:id:tofgame:20190511031139p:plain
これで関数呼び出し完了です!

まとめ

・リフレクションはメタデータを使ってクラスやメソッドの情報にアクセスすること
・GetMember()などで他クラスのメタデータを取得できる
Invoke()で実行

参考にしました

docs.microsoft.com

3秒でわかる「フラグメントシェーダー」【Unity】

f:id:tofgame:20190428235503j:plain

フラグメントシェーダーとは

画面に投影される予定のピクセルの色データを加工するシェーダーです!
頂点シェーダーで加工したデータが別の工程を経た後、画面に投影される分のピクセルデータに変換されます。
そのピクセルデータを受け取り、再計算することでいろんな見えかたに変化させることができます。

前回(頂点シェーダー)

tofgame.hatenablog.com


前回と同じコードを使います。

シェーダーのコード

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秒でわかる「テイラー展開」

f:id:tofgame:20190429000018j:plain

テイラー展開とは

テイラーの定理から導かれる近似式展開です!
難しい式を一次式、二次式などのシンプルな形に近似できます。

 x=a付近で近似するとして、
 \displaystyle
f(x)=f(a)+f^{(1)}(a)(x-a)+\frac{f^{(2)}(a)}{2!}(x-a)^2+\cdots+\frac{f^{(n)}(a)}{n!}(x-a)^n+\cdots
 \displaystyle
=\sum_{n=0}^\infty \frac{f^{(n)}(a)}{n!}(x-a)^n

f(x)=x+1テイラー展開

まずはテイラー展開で一致しそうな式から見てみます。
x=0でテイラー展開します。

 \displaystyle
f^{(1)}(0)=1
 \displaystyle
f(x)=(0+1)+(x-0)=x+1

式が一致しました!

x=3でテイラー展開してみます。

 \displaystyle
f^{(1)}(3)=1
 \displaystyle
f(x)=(3+1)+(x-3)=x+1

これも一致します!

 f(x)=sin(x)テイラー展開

まずはx=0で1次近似します。
 \displaystyle
f^{(1)}(0)=cos(0)
 \displaystyle
f(x)\simeq sin(0)+cos(0)(x-0)=x


 sin(x) xだとあまりにも違うので、次はx=0で2次近似をします。
 \displaystyle
f^{(1)}(0)=cos(0)
 \displaystyle
f^{(2)}(0)=-sin(0)
 \displaystyle
f(x)\simeq sin(0)+cos(0)(x-0)+\frac{-sin(0)}{2!}(x-0)^2=x

f:id:tofgame:20190508201425p:plain

f^{(2)}(0)=-sin(0)なので、1次近似と同じ値になりました。次は3次近似をします。
 \displaystyle
f^{(1)}(0)=cos(0)
 \displaystyle
f^{(2)}(0)=-sin(0)
 \displaystyle
f^{(3)}(0)=-cos(0)
 \displaystyle
f(x)\simeq sin(0)+cos(0)(x-0)+\frac{-sin(0)}{2!}(x-0)^2+\frac{-cos(0)}{3!}(x-0)^3=x-\frac{1}{6}x^3

f:id:tofgame:20190508201438p:plain

少し近づきました!
計算していくとわかりますが、下記の式のようになります。
 \displaystyle
sinx=\sum_{n=0}^\infty \frac{(-1)^n}{(2n+1)!}x^{2n+1}

マクローリン展開

 x=0付近でテイラー展開するときを特にマクローリン展開と言います。
 \displaystyle
f(x)=f(0)+f^{(1)}(0)x+\frac{f^{(2)}(0)}{2!}x^2+\cdots+\frac{f^{(n)}(0)}{n!}x^n+\cdots
 \displaystyle
=\sum_{n=0}^\infty \frac{f^{(n)}(0)}{n!}x^n