Help us understand the problem. What is going on with this article?

【Unity】残像を残しながらオブジェクトを拡大・縮小する

はじめに

タイトルの通りです。
アントマン&ワスプの大きさが変わるラボ(https://youtu.be/8_rTIAOohas の30秒あたり)に衝撃を受けたので再現してみました。

できたもの

縮小

5a28b8d38073102f667c200d164f3ae4 (1).gif
これでゴーストに襲撃されても安心

拡大

be976b87425f23119b10b77ee202ef23.gif
うーん(微妙)

方針

  • 拡大・縮小したいオブジェクトのPrefabを作る
  • 残像分(5個くらい)配列を作り、少しずつサイズとアルファ値を変化させる
  • Updateにぶっこむと処理が速すぎて残像が残らないので、コルーチンを使って遅延させる

コード

C#

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

public class Shrink : MonoBehaviour
{
    public GameObject objPrefab;
    GameObject[] obj = new GameObject[5];
    //float TimeCount = 0;
    bool small = false;
    bool big = false;
    int count = 4;
    float a = 0.6f;
    float size;
    private Material material;

    void Start()
    {
        obj[0] = Instantiate(objPrefab) as GameObject;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            small = true;
        }

            if (small == true)
        {
            Coroutine coroutine = StartCoroutine("SizeGenerator", 0.05f);
            small = false;
        }

        if (Input.GetMouseButtonDown(1))
        {
            big = true;
        }

        if (big == true)
        {
            Coroutine coroutine = StartCoroutine("SizeGenerator", 0.05f);
            big = false;
        }
    }

    private IEnumerator SizeGenerator(float waitTime)
    {
        if (small == true)
        {
          size = 0.5f;
        }

        if (big == true)
        {
            size = 2.0f;
        }

        for (int i = 1; i <= count; i++)
        {
            for (int j = i; j >= 0; j--)
            {
                if (i == j)
                {
                    obj[i] = Instantiate(objPrefab) as GameObject;
                    float alpha = Mathf.Pow(a, j);
                    obj[j].GetComponent<Renderer>().material.SetFloat("_Alpha", alpha);
                }
                else
                {
                    obj[j].transform.localScale = obj[j].transform.localScale * size;
                }    
            }
            yield return new WaitForSeconds(waitTime);
        }

        //destroyする用
        for(int k=0; k<8; k++)
        {
            //配列回すようループ
            for (int l = obj.Length-1; l > 0; l--)
            {
                float alpha = Mathf.Pow(a, l)* Mathf.Pow(a, k);
                if (obj[l] != null)
                {
                    obj[l].GetComponent<Renderer>().material.SetFloat("_Alpha", alpha/2);
                }
                if (alpha < 0.05)
                {
                    Destroy(obj[l]);
                }
            }
            yield return new WaitForSeconds(waitTime);
        }
    }
}

左クリックで縮小、右クリックで拡大

シェーダ

Shader "Custom/Custom"
{
    Properties{
    _MainTex("Water Texture", 2D) = "white" {}
    _Alpha("Alpha", Range(0,1)) = 1.0
    }

    SubShader{
        Tags { "Queue" = "Transparent" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard alpha:fade 
        #pragma target 3.0

        struct Input {
            float2 uv_MainTex;
        };

    half _Alpha;
    sampler2D _MainTex;

        void surf(Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = _Alpha;
        }
        ENDCG
    }
        FallBack "Diffuse"
}

テクスチャとアルファ値のみのsurfaceシェーダ

注意

  • 残像処理を行うために複製したオブジェクト同士の衝突判定を無くす必要あり
  • 拡大の場合、オブジェクトのRigidbody→is Kinematicにチェックを入れないとオブジェクトがふっ飛ぶ(なぜ...?)

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away