リブラ

グラフィックスプログラミングの勉強や制作の進捗がメイン

【Unity】スキャンするエフェクトを作る


ゲームでよくある目に見えないオブジェクトを強調するエフェクト

最初はShaderのパラメータを切り替えて一つのマテリアルで全てやってるのかなとか思ってたんですが
HorizonZeroDawnをやって、エフェクトの下にキャラクターは通常通り描画されていて
これエフェクト用の別オブジェクトを用意してるだけだ」となり作ってみることにしました。
※追記 ShaderのPassを増やして処理すればできそう。
完成図

スキャン演出用のShader作成

まずスキャンする側、今回はShaderGraphを使ってみようと思います
※2021.3.16f1 URPで作成しています

といってもスキャンする側はUnityJapanにあるのでそれを参考にさせて頂きました。
www.youtube.com

Built-inではScriptでDepthTextureを生成するように設定しないといけなかった気がするのでBuilt-inでやろうとしてる人はご注意ください。

次にスキャンされる側を作成します
半透明で描画するだけでいいのですが雰囲気出しのためドット風にします

そしてこのように子オブジェクトにCubeをもう一つ用意して作成したマテリアルに変更します。

しかしこのままでは壁の裏などに隠れているとZTestにより描画されません

そのためZTestを常にパスさせるためにDepthTestをAlwaysに変更します

これでShader部分は完成です。

スキャン処理作成

まずはスキャンされる側のコードです適当ですが
親にこのコンポーネントを付けて
Inspectorで子のハイライト用オブジェクトを指定します

public class HighLightObject : MonoBehaviour
{
    [SerializeField] private GameObject highLightObject;
    public void StartHilgiht()
    {
        StartCoroutine("Count");
    }
    private IEnumerator Count()
    {
        highLightObject.gameObject.SetActive(true);
        yield return new WaitForSeconds(0.7f);
        highLightObject.gameObject.SetActive(false);
    }
}

次にスキャンする側です
これもスキャンする側にこのコンポーネントとRigidBodyをアタッチします

public class ScanObject : MonoBehaviour
{
    void Update()
    {
        transform.localScale += Vector3.one * Time.deltaTime *0.9f;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.transform.TryGetComponent(out HighLightObject obj))
        {
            obj.StartHilgiht();
        }
    }
}