20201129のUnityに関する記事は3件です。

UnityのMecanimアニメで、ムービープレーヤーのスライダーのような制御がしたい

やりたいこと

  • ムービープレーヤーのスライダーのような制御がしたい
    • アニメ全長の任意の位置へジャンプしたいです。
  • アニメの任意のフレームを再生したい
    • シーケンシャルな再生でなく、任意のフレームに対してランダムにアクセスして、スクリプト制御で正逆任意の速度で再生したいです。
検証環境
  • Unity 2019.4.x (LTS)

方法

具体例

以下のコードでは、対象のスライダーとアニメーターが、コードがアタッチされたオブジェクトの子孫の何処かに存在することを前提にしています。

AnimeSlider.cs
using UnityEngine;
using UnityEngine.UI;

public class AnimeSlider : MonoBehaviour {

    private Slider slider;
    private Animator animator;

    /// <summary>初期化</summary>
    void Start () {
        slider = GetComponentInChildren<Slider> ();
        slider.onValueChanged.AddListener (OnChangeSlider);
        animator = GetComponentInChildren<Animator> ();
        animator.speed = 0; // 再生をポーズ
    }

    /// <summary>スライダが変化</summary>
    public void OnChangeSlider (float _) {
        animator.Play (0, -1, slider.normalizedValue);
    }

}
  • これによって、スライダーの位置に応じた任意のフレームが再生されます。
  • ループするアニメの場合は、スライダの左端と右端で同じフレームが表示されます。
    • 同じにしたくない場合は、slider.normalizedValue * 0.9999999fとかにします。
  • ポーズを解除する場合は、animator.speed = 1;します。

蛇足

複数の同じアニメを時間差で表示
AnimeSlider.cs
using UnityEngine;
using UnityEngine.UI;

public class AnimeSlider : MonoBehaviour {

    private Slider slider;
    private Animator [] animators;

    /// <summary>初期化</summary>
    void Start () {
        slider = GetComponentInChildren<Slider> ();
        slider.onValueChanged.AddListener (OnChangeSlider);
        animators = GetComponentsInChildren<Animator> ();
        foreach (var animator in animators) {
            animator.speed = 0; // 再生をポーズ
        }
    }

    /// <summary>スライダが変化</summary>
    public void OnChangeSlider (float _) {
        for (var i = 0; i < animators.Length; i++) {
            var time = slider.normalizedValue - ((float) i / animators.Length);
            if (time < 0f) { time += 1f; }
            animators [i].Play (0, -1, time);
        }
    }

}


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

外部スクリプトの変数を取得する方法

途中だけどごめんねー

この記事でできること

  • 外部のスクリプトにある変数を取得できるようになる。

参考例

  • Sceneにはplaneとcubeを設置して、それぞれにPublicの変数を設ける。

a03.png

  • planeオブジェクト
    • testA.cs
    • 変数intTestAは10

a01.png

  • cubeオブジェクト
    • testB.cs
    • 変数intTestBは20

a02.png

using UnityEngine;

public class testA : MonoBehaviour
{
    public int intTestA = 10;
}

using UnityEngine;

public class testB : MonoBehaviour
{
    public int intTestB = 20;

    testA script;

    void Start()
    {
        script = GameObject.Find("Plane").GetComponent<testA>();
        Debug.Log(script.intTestA);
    }
}

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity / ARFoundation】 AR空間の変形のつなぎ目を滑らかにする

1. はじめに

以前、ARKit3を使ってAR空間上のカメラ映像の一部分を変形させるという記事を書きました。

この記事を書いた時点ではあまり気にならなかったですが、よく見てみると変形のつなぎ目が目立ってしまい、あまり空間に溶け込んでいません。

Pasted_Image_2020_11_29_15_13.jpg

そこで、今回 AR空間の変形のつなぎ目を滑らかにするようにシェーダーを書き換えてみたので、そのテクニックを紹介します。

2. 準備

基本準備は、ARKit3を使ってAR空間上のカメラ映像の一部分を変形させるに記載しているので、そちらをご覧ください。

3. 実装

変形処理のつなぎ目を滑らかにするため、シェーダー (CameraPlane.shader)を書き換えます。
Planeの中心から遠ざかるにつれ、パラメタを小さくし、つなぎ目では変形させないようにします。
そこで、tex2Dlodを使って、テクスチャ情報から頂点をいじる処理を追加します。
下記の画像をインポートし、_ScopeTexとして利用します。

hole.png

また、Thresholdによって変形のパラメータを調整できるようにします。
追加する処理はこのような感じです。

float4 deform = tex2Dlod (_ScopeTex, float4(IN.uv.xy,0,0));
float ratio = _Threshold * deform;
float4 _vertex = IN.vertex;
float ampX = 0.1f * sin(_Time * 100 + IN.vertex.x) * ratio;
float ampZ = 0.1f * sin(_Time * 100 + IN.vertex.z) * ratio;
_vertex.xyz = float3(IN.vertex.x + ampX, IN.vertex.y, IN.vertex.z + ampZ);

全文はこちら

CameraPlane.shader
Shader "Custom/CameraPlane"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        // _ScopeTexと_Thresholdを追加
        _ScopeTex ("Texture", 2D) = "white" {}
        _Threshold("Threshold", Range(0,10))= 0.0
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

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

            struct v2f
            {
                float4 vertex : POSITION;
                float4 color : COLOR;
                float2 uv : TEXCOORD0;
                float2 screenpos : TEXCOORD1;
            };

            sampler2D _MainTex;
            sampler2D _ScopeTex;
            float _Threshold;

            v2f vert(appdata_t IN)
            {
                v2f OUT;
                // --------- : 追加
                float4 deform = tex2Dlod (_ScopeTex, float4(IN.uv.xy,0,0));
                float ratio = _Threshold * deform;
                float4 _vertex = IN.vertex;
                float ampX = 0.1f * sin(_Time * 100 + IN.vertex.x) * ratio;
                float ampZ = 0.1f * sin(_Time * 100 + IN.vertex.z) * ratio;
                // ---------
                _vertex.xyz = float3(IN.vertex.x + ampX, IN.vertex.y, IN.vertex.z + ampZ);

                OUT.vertex = UnityObjectToClipPos(_vertex);
                OUT.uv = IN.uv;
                OUT.color = IN.color;

                float4 objectToClipPos = UnityObjectToClipPos(IN.vertex);
                float4 spreenPos = ComputeScreenPos(objectToClipPos);
                float2 uv = spreenPos.xy/spreenPos.w;

                OUT.screenpos = uv;
                return OUT;
            }

            fixed4 frag(v2f IN) : COLOR
            {
                float2 xy = IN.screenpos.xy;
                half4 c = tex2D(_MainTex, xy);
                return c;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

4. 実行結果

処理を入れる前

変形のつなぎ目がわかる状態になっています。
Nov-29-2020 16-58-00.gif

処理を入れた後

変形のつなぎ目がわからない✨
Nov-29-2020 16-59-02.gif

5. おわりに

今回はARFoundation向けのシェーダーを紹介しましたが、その他のプラットフォームでも適用できそうなテクニックの紹介でした?

おまけ

変形処理をちょっと変えたやつです。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む