手前のオブジェクトだけテクスチャを使ってマスクをかける

まずカメラを二つ作成して同じ位置に用意する。
(奥のほうだけレンダリングするカメラと、手前のオブジェクトだけをレンダリングするカメラ)

奥のほうだけレンダリングするカメラをcam_0とする。
手前のオブジェクトだけをレンダリングするカメラをcam_1とする。

cam_1でレンダリングしたい手前のオブジェクトにはmaskというレイヤーを作ってそのレイヤーに指定しておく。

planeを用意してmask用のshaderを指定したマテリアルを付ける。
下記mask用shader(ビルトインシェーダーのTransparent Cutoutを改造したもの)

Shader "Unlit/Transparent Cutout_mask" {
Properties {
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
    Tags { "Queue" = "Geometry+10" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    LOD 100
    ColorMask 0
    Lighting Off

    Pass {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f {
                float4 vertex : SV_POSITION;
                float2 texcoord : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed _Cutoff;

            v2f vert (appdata_t v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.texcoord);
                clip(col.a - _Cutoff);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
        ENDCG
    }
}

}


上記のmask用shaderはビルトインシェーダーのTransparent Cutoutを改造したもので、変更した点は2つ(他のshaderでも改造する際は下記の二つを足しておけば良い)

レンダーキューをGeometryの後に描画する(今回はマスクの後ろにあるオブジェクトのレンダーキューはGeometry(2000)なのでGeometry+10になっているが、他のレンダキューの場合、そのキューより後にレンダリングするように設定してあげれば良い)

"Queue" = "Geometry+10"


ColorMask 0と記載することですべてのカラーチャネルのレンダリングを無効化します(ようはこのオブジェクトはレンダリングしないよということ)

ColorMask 0


あとはこのshaderでマテリアルを作ってアルファ付きのテクスチャを貼っておく。

次にカメラの設定
cam_1のinspectorでClearFlagsをDepthOnlyにして
CullingMaskをmaskのみに設定
これでcam_1はmaskしかレンダリングしない
f:id:shinobigiken:20170802090316p:plain

cam_0はCullingMaskでmaskを外す
これでcam_0はmask以外をレンダリングすることになる
f:id:shinobigiken:20170802090227p:plain

下記のようになる
f:id:shinobigiken:20170802091037p:plain

houdiniでデジタルアセットを作ってunityにimport

デジタルアセットとはhoudiniのパラメーターがunityでいじれる
データの上書きもラク
頂点アニメーションも出来る
かなり便利だが、unity側の負荷がどうなのかは未検証


Houdiniの設定

例えばGridの次にMountainを繋いでSphereをコピーする
次に、このsopを全部選択
f:id:shinobigiken:20170802083103j:plain

Assets > NewDegitalAssetFromSlection

すると
CreateNewDigitalAssetFromNodeというwindowが出てくるので
OperatorNameとOperatorLabelを適当に決める(これがなんなのかまだ理解してない)
SaveToLibraryでデジタルアセットを保存するディレクトリを指定する
そしてAccept
f:id:shinobigiken:20170802083118p:plain

すると
EditOperatorTypePropertiesというWindowが出てくる
これはUnity側にどのパラメーターを仕込むのかを決める事が出来る

EditOperatorTypeProperties > Parameters > ExistingParametersの

例えばMountainのTimeのパラメーターの文字の部分を
EditOperatorTypePropertiesのrootにドラッグドロップすると
rootの子供にTimeが出来る。
この右側のパラメーターでUnityのInspectorに表示される値の設定が出来る。
f:id:shinobigiken:20170802083135p:plain

Assets > SaveAssets > testをクリックしてデジタルアセットを上書き
これでHoudiniの設定は終わり


次にUnityの設定
デジタルアセットを入れたいシーンを開いて

C:\Users\Public\Documents\Unity Projects\Houdini_Engine_Project_16.0.633

houdini-engine.scripts.unitypackageをimport
するとunityの上のほうにHoudiniEngineという項目が出来るので
そこのLoadHoudiniAsseteで上記で作ったデジタルアセットをimport

InspectorのHoudiniParmsでHoudiniで弄った設定した値をいじれる
f:id:shinobigiken:20170802083149p:plain

Albedoの色相をスクリプトで変える

UnityEngine.Color.HSVToRGB関数を使ってHSVの値を調節しています

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class hsv : MonoBehaviour
{
    //inspectorにsliderで0~1までのfloatで表示
    [Range(0.0f,1.0f)]
    public float h = 1 ;
    public float s = 1 ;
    public float v = 1 ;

    void Update()
    {
        //rgbをhsvに変換
        GetComponent<Renderer>().material.color = UnityEngine.Color.HSVToRGB(h,s,v);
    }
}


f:id:shinobigiken:20170727080619g:plain

Soft Edge UnlitのHSV(色相,彩度,明度)をいじれるように改造

Soft Edge Unlitをたまに使うのですがそれをHSV(色相,彩度,明度)をいじれるように改造したShader

Shader "Custom/Soft Edge Unlit_HSV" {
	Properties{
		_Color("Main Color", Color) = (1, 1, 1, 1)
		_MainTex("Base (RGB) Alpha (A)", 2D) = "white" {}
		_Cutoff("Base Alpha cutoff", Range(0,.9)) = .5
		_Hue("Hue", Range(0,360)) = 0
		_Sat("Saturation", Range(0,30)) = 1
		_Val("Value", Range(0,4)) = 1
	}
		SubShader{
			Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout_hsv" }
			Lighting off
			Cull Off
			Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fog
			#include "UnityCG.cginc"
			
			struct appdata_t {
				float4 vertex : POSITION;
				float4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f {
				float4 vertex : SV_POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				UNITY_VERTEX_OUTPUT_STEREO
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed _Cutoff;

			v2f vert(appdata_t v)
			{
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.color = v.color;
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}

			//RGB to HSV 関数(ここでHSVの値を調整してFragmentShaderに返してる)
			fixed3 rgb_to_hsv(fixed3 RGB, half3 shift)
			{
				fixed3 RESULT = fixed3(RGB);
				float VSU = shift.z*shift.y*cos(shift.x*3.14159265 / 180);
				float VSW = shift.z*shift.y*sin(shift.x*3.14159265 / 180);

				RESULT.x = (.299*shift.z + .701*VSU + .168*VSW)*RGB.x
					+ (.587*shift.z - .587*VSU + .330*VSW)*RGB.y
					+ (.114*shift.z - .114*VSU - .497*VSW)*RGB.z;

				RESULT.y = (.299*shift.z - .299*VSU - .328*VSW)*RGB.x
					+ (.587*shift.z + .413*VSU + .035*VSW)*RGB.y
					+ (.114*shift.z - .114*VSU + .292*VSW)*RGB.z;

				RESULT.z = (.299*shift.z - .3*VSU + 1.25*VSW)*RGB.x
					+ (.587*shift.z - .588*VSU - 1.05*VSW)*RGB.y
					+ (.114*shift.z + .886*VSU - .203*VSW)*RGB.z;

				return (RESULT);
			}

			fixed4 _Color;
			half _Hue, _Sat, _Val;

			//FragmentShader
			fixed4 frag(v2f i) : SV_Target
			{
				half4 col = tex2D(_MainTex, i.texcoord) * _Color;
				clip(col.a - _Cutoff);
				half3 shift = half3(_Hue, _Sat, _Val);
				//rgb_to_hsv関数を呼び出し引数の色を入れて返してもらう
				return fixed4(rgb_to_hsv(col, shift), col.a);
			}
			ENDCG
		}

		Pass{
			Tags{ "RequireOption" = "SoftVegetation" }
			ZWrite off
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fog
			#include "UnityCG.cginc"

			struct appdata_t {
				float4 vertex : POSITION;
				float4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f {
				float4 vertex : SV_POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				UNITY_VERTEX_OUTPUT_STEREO
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float _Cutoff;

			v2f vert(appdata_t v)
			{
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.color = v.color;
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}

			fixed4 _Color;
			fixed4 frag(v2f i) : SV_Target
			{
				half4 col = _Color * tex2D(_MainTex, i.texcoord);
				clip(-(col.a - _Cutoff));
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
		ENDCG
		}
	}
}


FragmentShaderでrgb_to_hsv関数を呼び出してその中でHSVの加工をした値を返してもらい最終出力する。


参考
https://forum.unity3d.com/threads/problem-with-getting-hue-shift-shader-right.89041/

瞬きをループ(コルーチンを使って指定した秒数ごとにテクスチャを切り替える)

using UnityEngine;
using System.Collections;

public class EyeBlink : MonoBehaviour
{
    public Texture _textureA;
    public Texture _textureB;
    public Material _mat;

    void Start()
    {
        //BlinkLoop_コルーチン呼び出し
        StartCoroutine(BlinkLoop_());
    }

    private IEnumerator BlinkLoop_()
    {
        //whileでひたすらループさせる
        while (true)
        {
            //5秒に一回、0.05秒だけ_textureBに切り替わる
            yield return new WaitForSeconds(5.0f);
            _mat.SetTexture("_MainTex", _textureA);
            yield return new WaitForSeconds(0.05f);
            _mat.SetTexture("_MainTex", _textureB);
        }
    }
}

自身の親の親のオブジェクトのComponentを入れる

単純で.parent.parentというように二回「.parent」を入れるだけ

    //親の親のgameobjectを入れる変数
    private GameObject _parent;
    //AnimatorComponentを入れる変数anim
    private Animator anim;

    void Start(){
        //自身の親の親のgameobjectを_parentに入れる
        _parent = gameObject.transform.parent.parent.gameObject;
        //変数animに_parentのAnimatorのcomponentを取得して入れる
        anim = _parent.GetComponent<Animator>();
    }
  void Update(){
        if (何かしたら){
        //animのtaberuをtrueにする
        anim.SetBool("taberu", true);
    }

使いそうなMathf関数

Deg2Rad, Rad2Deg
degree(度)からradian(ラジアン)の変換
float deg = 30.0f;//度
float rad = deg * Mathf.Deg2Rad;//ラジアン

radian(ラジアン)からdegree(度)の変換
float rad = 10.0f;//ラジアン
float deg = rad * Mathf.Rad2Deg;//度
ちなみに三角関数(sin,cosなどに入れるsin(hoge)はラジアンの値で計算される)


円周率
Mathf.PI
Mathf.PIは3.141593

Abs関数
絶対値を返す
マイナスでも+の値になる(0からの距離)
Mathf.Abs(-0.5f)

Ceil関数
切り上げした値を返す
Mathf.Ceil(1.4f)
//2

Floor関数
切り捨てした値を返す
Mathf.Floor(1.4f)
//1

Round関数
四捨五入した値を返す
Mathf.Round(1.4f)
//1

Min関数
最小値を返す
Mathf.Min(0.1f, 0.5f)
//0.1f

Max関数
最大値を返す
引数は何個でも入れられる
Mathf.Max(585,431,111)
//585

Clamp関数
範囲内に制限
第一引数が変化させたい値,第二引数は最小値,第三引数は最大値
Mathf.Clamp(10,-5,5)
//5

Clamp01関数
minが0,maxが1のclamp関数
Mathf.Clamp01(5.0f)
//1.0f

Pow関数
累乗した値を返す
第一引数が変化させたい値,第二引数が累乗する値
Mathf.Pow(2,2)
//4

Sin関数
Mathf.Sin(radian)

Cos関数
Mathf.Sin(radian)

Repeat関数
第二引数までの値をひたすら繰り返す関数
下記をupdate関数に書くとひたすら0~1の値を繰り返してくれる
Mathf.Repeat(Time.time,1)

PingPong関数
第二引数までの値に行ったらまた0まで戻ってをひたすら繰り返す関数
Mathf.PingPong(Time.time,1)

PerlinNoise関数
x,y座標を引数として、0.0から1.0までの乱数(ノイズ)floatが返る(noisechopと同じ)
Mathf.PerlinNoise(Time.time,1.0f)

例えばgameobjectのtransformに下記のように入れたとしたらxの値がnoiseでふらふらする
Vector3(Mathf.PerlinNoise(Time.time,1.0f),0,0);