リブラ

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

【UEFN】Playerの攻撃力上限を変更する

ダメージ増幅パワーアップの仕掛けを使用します

プレイヤーの攻撃力をダメージ増幅パワーアップから上げたい場合4.0で
制限されていますがVerseからなら上限がありませんでした



ボタンを押した時に攻撃力アップを付与

ダメージ増幅パワーアップは複数用意しなくても数値を変更して使いまわせるので
[player]float 型のMap等で攻撃力を管理できます。

【UEFN】デバイスのスケール制限を無視して拡大する

UEFNでデバイスを制限以上に拡大したい時に使えたので残しておきます

【拡大したいデバイス

空のアクタを配置してアクタのDefaultSceneRootをデバイスのStaticMeshComponentの可動性と合わせる
※可動性を合わせないと親子関係に出来ない

バイスをアクタの子にして親のアクタを拡大する


制限をそもそも外す方法あれば教えてください・・

【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();
        }
    }
}

【Unity】Textureにお絵描きする

今回やること
f:id:printf_Kei:20220129184032g:plain


まずはソースコード

Graphics.Blit関数によりShaderで加工したTextureをコピーするというのを繰り返すことでお絵描きしているように見せてます。
shader側では送られてきたUV座標と現在処理しているUV座標の差がsize以下なら塗りつぶし、それ以外はもとのTextureのまま処理するということをしています。
f:id:printf_Kei:20220130000830p:plain
絵を描くだけではなくVTFを利用したりすることで応用もできます。
f:id:printf_Kei:20220130001314g:plain

参考                 
nn-hokuson.hatenablog.com
esprog.hatenablog.com
www.youtube.com

【Unity】ScriptableObjectを編集する簡素なEditor拡張

RPGを作る課題の時に勝手に作成した副産物を紹介します。
f:id:printf_Kei:20220123143514p:plain
ソースコードかなり汚いから次作る時は直したいところ

難しいことは何もしてないですが応用できそうなので残しておきます。

どちらかと言えばこっからが本題

作成したデータが初期化される場合

ScriptableObjectのデータがコンパイル時や再起動時に初期化される現象がおきました
対処としてこちらの記事を参考にしました
tsubakit1.hateblo.jp
私の場合はシリアル化していないのが原因で、EnemyData構造体はシリアライズしてたけどScriptableObjectを継承したEnemyDatasのメンバをprivateで宣言していたためシリアル化されず初期化されてしまいました。
シリアル化についてはこちらを参照しました。
docs.unity3d.com
また、調べている時に別の理由で初期化される場合の記事を見つけたのでリンクしておきます。
kan-kikuchi.hatenablog.com

【Unity】蝶が羽ばたくエフェクトを作ってみる

www.klab.com
Klab株式会社様が運営されているサイトの
www.klab.com
こちらで紹介されている蝶シェーダーを勉強を兼ねて真似してみました。

meshを用意

元の記事では6頂点の板ポリを使用したましたが、今回はテクスチャを貼り付けないので5頂点で行います。
f:id:printf_Kei:20211227155751p:plain
Blender等で出力しても良いのですが、スクリプトで生成することにします。

var mesh = new Mesh();
        //meshの頂点
        var vertex = new Vector3[]{
            new Vector3(-0.1f,0.0f,-0.1f),//左下
            new Vector3(0.1f,0.0f,-0.1f),//右下
            new Vector3(0.0f,0.0f,0.0f), //中央
            new Vector3(-0.1f,0.0f,0.1f),//左上
            new Vector3(0.1f,0.0f,0.1f),//右上
        };
        //meshの三角形を定義
        var triangles = new int[]{
            0,3,2,
            2,4,1
        };
        mesh.SetVertices(vertex);
        mesh.SetTriangles(triangles, 0);
        //Assetとして出力
        AssetDatabase.CreateAsset(mesh, "Assets/ButterflyMesh.asset");

これを適当なスクリプトのStart関数に記載し実行すればAssetにmeshが出力されます。

頂点シェーダーで羽ばたかせる

f:id:printf_Kei:20211227162227p:plain
rotate関数の中身が記載されていなかったのですが、z軸で回転させる回転行列を生成してるだけだと思います。

half2x2 rotate(half theta) {
                    half angleCos = cos(theta);
                    half angleSin = sin(theta);
                    return half2x2(angleCos, -angleSin, angleSin, angleCos);
                }

f:id:printf_Kei:20211227171650g:plain

パーティクルシステムに適用

f:id:printf_Kei:20211227210255p:plain
ParticleSystemのCustomVertexStreamsを使用して、各パーティクルの中心座標をshaderに送ります。
Custom1.xyはダミーとして入れています。
f:id:printf_Kei:20211227230148p:plain
上の画像のようにCustomVertexSystemはTEXCOORDの使用されていないxyzwから順番に埋めていってしまうので、ダミーを用意し扱い易くしています。
shder側はこのようにして値を受け取ります

struct appdata
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;   //ダミー受け取り用にfloat4を使用
                float4 color : COLOR;
                float4 center:TEXCOORD1;
            };

元記事にもある通りダイナミックパッチングによるメッシュの結合に対応するために中心座標を受け取って計算しています。
f:id:printf_Kei:20211227232835p:plain

               float3 center = v.center;
               float3 local = v.vertex-center;
               half flap = _FlapIntensity * sin(_Time.y * _FlapSpeed);
               local.xy = mul(rotate(flap * sign(local.x)), local.xy);
               o.vertex = UnityObjectToClipPos(center+local);

これで蝶の仕組みはできたので色々アレンジできそうです。
今回はパーティクルから色を受け取りそれを反映するところで終わりました。

完成
f:id:printf_Kei:20211227154614g:plain
完成図