Wallpaper Engineで動かせるプログラムをUnityで作る

Wallpaper Engineでは、Unityで作成したプログラムも使用できるらしいので試してみました。
まだ大したことはしていませんが、デスクトップ画面でカーソル操作に反応するユニティちゃんのプログラムを作成してみました。

サンプルはこちらにあります。
　→　[GitHub](https://github.com/mochi5420/Wallpaper_unitychan)


クリックするとYou Tubeへ飛びます。
[![hqdefault.jpg](https://qiita-image-store.s3.amazonaws.com/0/157713/41c5b2f9-44c2-d260-9b14-b9e5ff621164.jpeg)
](https://youtu.be/EWdsvkM1urA)


# 今回やったこと
デスクトップの背景でカーソルに対応して動作するものを作る

- カーソルの操作でユニティちゃんの動きを制御
- カーソルが動いた時にキラキラさせる


# 使用したもの
- Wallpaper Engine
- Unity 5.5.0f3(64-bit)
- SDユニティちゃん 3Dモデルデータ

# Wallpaper Engineとは
デスクトップの背景に動画を設定できるソフトみたいです。
有料（400円くらい）ですが、so coolなので是非購入をオススメいたします。Steamからダウンロード可能です。
→[Wallpaper Engine](http://store.steampowered.com/app/431960/)

このページではWallpaper Engineについては詳しく触れませんが、Wallpaper Engineでは動画の代わりにUnityでビルドしたプログラムも動作させることができるみたいなのでやってみました。

#実装
##1.カーソルの動きに追従するものを作る
カーソルを動かすと追従し、クリックするとジャンプしてくれるユニティちゃんを作りたいと思います。

まず[SDユニティちゃん](http://unity-chan.com/download/releaseNote.php?id=SDUnityChan)のデータをダウンロードし、Assetsの中へインポートしておきます。

地面や背景は好きなものにしていただければ大丈夫です。
僕は真っ白なPlaneの上にUnityちゃん（humanoidの方）をぽつんとおいたシンプルなシーンにしました。
背景はMain CameraのClear FlagsをSolid Colorに変更し、Background(色)をPlaneと同じ色にしました。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/9a3b95e2-9450-e959-54d4-ee0136626d4d.png)

![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/945461a6-c16a-6bfd-222d-e8cb43598980.png)


ここから、Unityちゃんの動きを設定していきます。
次のような行動を取らせたいと思います。

1.　基本その場待機で、カーソルがｘ軸方向に一定量離れたら追いかける
2.　体の全体が常にカーソルの方を向く
3.　左クリックでジャンプ


まず、ユニティちゃんにカーソルを追いかけさせるための目標物（target）を作成します。
今回は、目に見えないくらいのサイズのsphere(CursorにRenameしました)にスクリプトを設定して、常にディスプレイのカーソルの位置に来てもらうような仕組みにしました。（他にいい方法がすぐに思いつかなかったため）
スクリプトは次のようにしました。

```CursorPosition.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CursorPosition : MonoBehaviour {

    // Update is called once per frame
    void Update()
    {
        Vector3 ScreenPos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 CursorPos = new Vector3(Input.mousePosition.x, 
                                         Input.mousePosition.y,
                                         ScreenPos.z);  // Z軸方向には移動させないので初期位置のまま
        transform.position = Camera.main.ScreenToWorldPoint(CursorPos);
    }
}

```

このスクリプトを先程の極小CursorにAddしておき、ユニティちゃんのスクリプトのtargetにこいつを指定することで追従させよう！って感じですね。あんまりスマートじゃない気はしますが。
ユニティちゃんとCursorの初期位置関係はこんな感じに、Z軸方向に約１ｍずらして設置しました。X,Y方向は適当でも大丈夫です。

![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/aca9d6ee-faaf-f23f-8770-14770ca6db43.png)


　

次にユニティちゃんの設定です。
まずAnimatorですが、次のように設定しました。（顔の設定はまた後日やります…）

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/586cf964-8e22-eacb-a8c1-eb69923a8388.png)

StandingとWalking間の遷移は、Bool型のWalkがtrueかどうかで判断します。
また、Triggerで設定したJumpがtrueになると、どのstateからでもjump状態に遷移します。
Standing～Walking間のTransitionのHas Exit Timeのチェックはどちらも外しておいてください。

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/ec9e9661-8fe9-cef2-e567-990fe369d3c6.png)

次に、ユニティちゃん（humanoid）に予めアタッチされているIK Look At(Script)のIK Activeにチェックを入れ、Look At Obj に先程作ったCursorを設定します。

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/74a8a958-c607-1965-255f-c4d4ca3cd824.png)

これでユニティちゃんの顔が常にカーソルの方を向いてくれるようになります。

最後に、動きを制御するスクリプトを書いて終了です。
元からアタッチされているIdleChangerを書き換えましょう。

```IdleChanger.cs
using UnityEngine;
using System.Collections;

namespace UnityChan
{
    // Require these components when using this script
    [RequireComponent(typeof(Animator))]

	public class IdleChanger : MonoBehaviour
	{
	
		private Animator anim;						// Animatorへの参照
		private AnimatorStateInfo currentState;		// 現在のステート状態を保存する参照
        public bool isGUI = true;
        
        static int standingState = Animator.StringToHash("Base Layer.Standing@loop");
        static int walkingState = Animator.StringToHash("Base Layer.Walking@loop");

        public Transform lookAtObj = null;

        private float startPosZ;

        // Use this for initialization
        void Start ()
		{
			// 各参照の初期化
			anim = GetComponent<Animator> ();
			currentState = anim.GetCurrentAnimatorStateInfo (0);
            startPosZ = transform.position.z;
            transform.position = new Vector3(transform.position.x, transform.position.y, startPosZ);
        }
	
		// Update is called once per frame
		void  Update ()
		{
            
            //向く方向の決定
            transform.LookAt(new Vector3(lookAtObj.position.x, 0, lookAtObj.position.z), new Vector3(0,1,0));

            //左クリック時の処理
            if (Input.GetButtonDown("Fire1"))
            {
                anim.SetBool("Jump", true);
                transform.position = new Vector3(transform.position.x, transform.position.y, startPosZ);
                
            }

            //カーソルが移動した時の処理
            //targetとの距離がしきい値dxより大きくなったら歩く
            float dx = transform.position.x - lookAtObj.position.x;

            if (lookAtObj != null)
            {
                
                if (Mathf.Abs(dx) > 0.3f)
                {
                    currentState = anim.GetCurrentAnimatorStateInfo(0);
                    anim.SetBool("Walk", true);
                }
                else
                {
                    anim.SetBool("Walk", false);
                    currentState = anim.GetCurrentAnimatorStateInfo(0);
                }
            }
            

            if (currentState.fullPathHash == walkingState)
            {
                transform.position = new Vector3(transform.position.x - Mathf.Sign(dx)*0.01f, transform.position.y, startPosZ);
            }

            if (currentState.fullPathHash == standingState)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, startPosZ);
            }
        }

    }
}

```
このスクリプトのlookAtObjにCursorをアタッチすることをお忘れなく。
しきい値や掛け算されている定数は、お好みで微調整してください。
こうすることで、カーソルがx軸方向に離れたら追ってきてくれるようになると思います。
またクリックするとジャンプしてくれます。かわいい。


##2.カーソルが動いた時にキラキラさせる
カーソルの軌跡みたいなのを表現したかったので、パーティクルでやってみました。
パーティクルを使うのは初めてなので色々勉強しながら調整しました。

特にこちらのサイトを参考にさせて頂きました。テクスチャも使用させて頂きました…ありがとうございます。
[【Unity】ﾊﾞﾄﾙｶﾞｰﾙﾊｲｽｸｰﾙの星ｴﾌｪｸﾄっぽいものを作る～Part1～](http://daradaraunity.blog.fc2.com/blog-entry-2.html)

本当はCursorにParticle Systemをアタッチしたかったのですが何故かできませんでした（パーティクルが生成されなかった…泣）
なので、空のGameObjectを作成し、Particle Systemをアタッチし、Cursorの子にする、という手段を取りました。

![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/84fe39d6-07d7-9286-44d2-475459cb33d2.png)

パーティクルに使用するTextureとMaterialの設定は以下の通りです。

![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/d25bd8fb-58c2-fb57-4b97-7502ec4f0210.png)


![8.PNG](https://qiita-image-store.s3.amazonaws.com/0/157713/54da522f-380a-10ce-7f1e-7e2d7f7ef4d8.png)


特にShaderの種類をParticle/Additiveにすると、RGB値が(1,1,1,1)になってしまう（恐らく）ため、白背景と区別がつかず全然見えなかったので、乗算（しかもdouble）にしてみました。

続いてパーティクル自体の設定はこんな感じです。

![13.png](https://qiita-image-store.s3.amazonaws.com/0/157713/fc00baf9-d2d6-206b-9c41-d7f139998b88.png)

まだ挙動を理解してない箇所も少しあるので、設定が変なところもあるかもしれません。（特に色関連のところ）
ですがとりあえずこれでキラキラする軌跡を表現できるようにはなりました。

![AGDRec-セグメント 1.gif](https://qiita-image-store.s3.amazonaws.com/0/157713/c209e431-c6de-8dc2-1747-1fa9130ae84c.gif)


# あとがき
お試しで作ったものなのでクオリティはまずまずですが、とりあえずデスクトップでユニティちゃんが動いてくれたので今回は目的達成です。
Wallpaper Engineではキーボード入力は受け付けないとの噂ですが、それも近々試してみたいと思っています。
あとは、音に反応するものとか…