簡単な手書きエフェクトをUnityのTimelineを使って再生する
はじめに
簡単な手書きエフェクトを描いてUnityに持ち込んでみました。 その過程をメモしておきます。
Cinemachineでカメラの揺れを入れてみた。 pic.twitter.com/vb6AHqkIof
— 折登 いつき (@MatchaChoco010) 2019年1月23日
Kritaで手書きエフェクトを描く
Kritaにはアニメーション機能が存在します。 その機能を使ってエフェクトを描きました。
エフェクトを手書きしてみようと思ったけど難しい。かっこいいエフェクト作れるようになりたい……。 pic.twitter.com/Y0vcRdRoKk
— 折登 いつき (@MatchaChoco010) 2019年1月23日
Animation with Krita — Krita Manual version 4.1.7
作成したエフェクトを一枚のテクスチャに収めます。
今回は10コマでしたが、8コマや16コマ32コマなどの テクスチャサイズをきれいに割り切れるもののほうが素敵ですね。
Kritaのグリッド表示機能を使うと配置が楽になります。
Grids and Guides Docker — Krita Manual version 4.1.7
エフェクト用のメッシュをBlenderで作成する
エフェクト用にUVを開いた板ポリを用意しました。
単純な板ポリだけでなく立体的な形状とかにしてみるのも面白そうです。
UnityでUVをずらして表示するシェーダを作成する
作成したShaderは次のとおりです。
Shader "Unlit/effect001"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Multiply ("Multiply", Float) = 10
_T ("T", Float) = 0
}
SubShader
{
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
ZWrite Off
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Multiply;
float _T;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// float t = _Time.y * 24;
float t = _T;
o.uv.y /= 10;
o.uv.y *= -1;
o.uv.y -= 0.1 * floor(t);
if (t < 0 || t >= 10) {
o.uv = 0;
}
return o;
}
float4 frag (v2f i) : SV_Target
{
float4 col = tex2D(_MainTex, i.uv);
col.rgb *= _Multiply;
return col;
}
ENDCG
}
}
}
_T
という値を渡していること、UVのy方向を1/10にしていること、
t
をfloor
している部分がポイントです。
floor
によってコマ送りが表現できています。
_Multiply
は後のBloomで光らせるためにいれています。
マテリアルの_Tを操作するアニメーションクリップを作成する
エフェクト用メッシュをシーンに配置します。
先ほど作ったシェーダからエフェクト用のマテリアルを作成します。 マテリアルのテクスチャに作成したテクスチャを渡します。
マテリアルをエフェクト用メッシュに設定します。
エフェクト用メッシュを選択した状態で、アニメーションウィンドウからアニメーションを作成します。
マテリアルの_T
の値をアニメーションするプロパティとして登録します。
fpsを24にして、1フレームずつ-1から10までキーフレームを打ちます。
Timelineにアニメーションクリップを配置する
今回はエフェクトにTimeline機能を使ってみます。
新しくPlayable Directorと名付けた空のGameObjectを作成します。
Playable Directorを選択した状態でTimelineウィンドウのCreateボタンを押します。
作成するとPlayable Directorというコンポーネントと Animatorというコンポーネントが追加されます。
Animatorはいらないので削除します。
Playable DirectorのBindingsのAnitation Trackに エフェクト用メッシュのAnimatorを登録します。
アニメーションクリップをタイムラインに配置します。
タイムラインの長さを固定長にして2秒にしました。
エフェクト用メッシュのアニメーションはタイムラインでコントロールするので、 コントローラをNoneにします。
エフェクトをループ再生するためにPlayable DirectorのWrap ModeをLoopにします。
ここまでの作業で次のようになります。
Post ProcessingのBloomを適用する
微妙だと思ってたエフェクトもUnityに持ち込んでBloomをかけたらそこそこの見た目になってしまった。Bloom強い。 pic.twitter.com/IC6v5Hq7Nm
— 折登 いつき (@MatchaChoco010) 2019年1月23日
「Window>Pcakage Manager」からPost Processingを入れます。
カメラにPost Processin Layerを追加し、LayerをPostProcessingに変更します。
新しいGameObjectを作成しLayerをPostProcessingにして、 Post Processing VolumeをアタッチしてBloomを設定します。
この作業でよい感じにエフェクトが光るようになります。
Cinemachineのカメラ揺れを入れる
Cinemachineでカメラの揺れを入れてみた。 pic.twitter.com/vb6AHqkIof
— 折登 いつき (@MatchaChoco010) 2019年1月23日
Package ManagerからCinemachineをインストールします。
CameraにCinemachine Brainをアタッチします。
Virtual Cameraと名付けた空のGameObjectを配置します。
Cinemachine Virtual Cameraをアタッチします。 Noiseを加えることで手ブレを与えられます。
Add ExtensionからImpulse Listenerを追加します。 これで衝撃を受け取れるようになります。
Timelineから衝撃を発生させたいのですが、 Timeline上でのイベントはUnityのバージョン2019以降になるようです。 そのため、ここではアクティベーショントラックを利用して衝撃を発生させます。
空のオブジェクトを作成してImpulse Sourceと名付けます。
Cinemachine Impulse Sourceスクリプトをアタッチします。
このスクリプトのGenerateImpulse ()
メソッドを呼ぶことで衝撃を発生させます。
activeをfalseにしておきます。
Impulse Sourceに次のスクリプトをアタッチします。
using System.Collections;
using System.Collections.Generic;
using Cinemachine;
using UnityEngine;
public class ImpulseSource : MonoBehaviour {
void OnEnable () {
GetComponent<CinemachineImpulseSource> ().GenerateImpulse ();
}
}
OnEnable()
のタイミングで衝撃を発生させるスクリプトになります。
Timelineにアクティベーショントラックを追加します。
Impulse Sourceを登録します。
アクティベーショントラックはGameObjectのactiveを切り替えます。 衝撃を発生させたいタイミングでアクティブになるようにトラックを編集します。
これでTimelineの特定のタイミングでカメラを揺らせるようになりました。
Cinemachineでカメラの揺れを入れてみた。 pic.twitter.com/vb6AHqkIof
— 折登 いつき (@MatchaChoco010) 2019年1月23日
おわりに
今回は単純な板ポリに手書きのエフェクトを貼り付けるだけでしたが、 もっと複雑なメッシュを利用したりパーティクルを組み合わせたりして 色々なエフェクトが作れそうですね。