前提・実現したいこと
初めまして!
unityでrpgのプログラミングに挑戦している初心者です。
unityでポケモン金銀のへんしんのように、
四角形平面オブジェクトをスクリプトから"ぐねぐね"させることは可能でしょうか?
どんな方法が考えられますか?
調べながら頑張ります。
私が思い付くのはシェーダーを使うことぐらいで。。
リンク内容
↑0:53頃へんしんがうつってます。
左辺で間隔を開けて3点、
右辺でもずらして3点。
左右に広げて戻す表示というと、
やはりシェーダー以外ではできないでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
おそらくおっしゃる通りシェーダーを工夫するのが楽なんじゃないかと思います。
例えばスプライト用のマテリアルとして下記のようなものを作り...
ShaderLab
1Shader "Sprites/Wobbled" 2{ 3 Properties 4 { 5 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 6 _Color ("Tint", Color) = (1,1,1,1) 7 [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 8 [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) 9 [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1) 10 [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {} 11 [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0 12 [PerRendererData] _TextureCenter ("Texture Center", Float) = 0.5 13 [PerRendererData] _TextureScale ("Texture Scale", Float) = 1 14 [PerRendererData] _Amplitude ("Amplitude", Float) = 0 15 [PerRendererData] _Wavenumber ("Wavenumber", Float) = 1 16 [PerRendererData] _Offset ("Offset", Float) = 0 17 } 18 19 SubShader 20 { 21 Tags 22 { 23 "Queue"="Transparent" 24 "IgnoreProjector"="True" 25 "RenderType"="Transparent" 26 "PreviewType"="Plane" 27 "CanUseSpriteAtlas"="True" 28 } 29 30 Cull Off 31 Lighting Off 32 ZWrite Off 33 Blend One OneMinusSrcAlpha 34 35 Pass 36 { 37 CGPROGRAM 38 #pragma vertex vert 39 #pragma fragment frag 40 #pragma target 2.0 41 #pragma multi_compile_instancing 42 #pragma multi_compile_local _ PIXELSNAP_ON 43 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 44 #include "UnitySprites.cginc" 45 46 struct v2fCustom 47 { 48 float4 vertex : SV_POSITION; 49 fixed4 color : COLOR; 50 float2 texcoord : TEXCOORD0; 51 float positionY : TEXCOORD1; 52 UNITY_VERTEX_OUTPUT_STEREO 53 }; 54 55 float _TextureCenter; 56 float _TextureScale; 57 float _Amplitude; 58 float _Wavenumber; 59 float _Offset; 60 61 v2fCustom vert(appdata_t IN) 62 { 63 v2fCustom OUT; 64 65 UNITY_SETUP_INSTANCE_ID (IN); 66 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 67 68 // スプライト向けの座標変換を行うが、このときに併せて振幅に応じて 69 // メッシュを水平方向に引き伸ばし、波打たせるための余地を確保する 70 float scale = _Amplitude + 1.0; 71 OUT.vertex = UnityFlipSprite(IN.vertex * float4(scale, 1.0, 1.0, 1.0), _Flip); 72 OUT.vertex = UnityObjectToClipPos(OUT.vertex); 73 OUT.texcoord = float2(_TextureCenter + (IN.texcoord.x - _TextureCenter) * scale, IN.texcoord.y); 74 OUT.color = IN.color * _Color * _RendererColor; 75 76 // メッシュ頂点のY座標を送る 77 OUT.positionY = IN.vertex.y; 78 79 #ifdef PIXELSNAP_ON 80 OUT.vertex = UnityPixelSnap (OUT.vertex); 81 #endif 82 83 return OUT; 84 } 85 86 fixed4 frag(v2fCustom IN) : SV_Target 87 { 88 // Y座標に応じてテクスチャをサンプリングする水平位置をずらす 89 IN.texcoord.x += _TextureScale * _Amplitude * sin(2.0 * UNITY_PI * _Wavenumber * (IN.positionY + _Offset)); 90 91 fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color; 92 c.rgb *= c.a; 93 return c; 94 } 95 ENDCG 96 } 97 } 98}
シーン上のスプライトオブジェクトには、シェーダーへパラメーターを送り込むための下記のような補助スクリプトをアタッチしたところ...
lang
1using UnityEngine; 2 3[RequireComponent(typeof(SpriteRenderer))] 4public class Wobbler : MonoBehaviour 5{ 6 private static readonly int TextureCenter = Shader.PropertyToID("_TextureCenter"); 7 private static readonly int TextureScale = Shader.PropertyToID("_TextureScale"); 8 private static readonly int Amplitude = Shader.PropertyToID("_Amplitude"); 9 private static readonly int Wavenumber = Shader.PropertyToID("_Wavenumber"); 10 private static readonly int Offset = Shader.PropertyToID("_Offset"); 11 12 [Min(0.0f)] public float amplitude; 13 [Min(0.0f)] public float wavenumber = 1.0f; 14 public float offset; 15 16 private MaterialPropertyBlock properties; 17 private SpriteRenderer spriteRenderer; 18 19 private void Update() 20 { 21 var sprite = this.spriteRenderer.sprite; 22 if (sprite == null) 23 { 24 return; 25 } 26 27 this.spriteRenderer.GetPropertyBlock(this.properties); 28 this.properties.SetFloat(TextureCenter, sprite.pivot.x * sprite.texture.texelSize.x); 29 this.properties.SetFloat(TextureScale, (sprite.texture.texelSize.x * sprite.textureRect.width) / ((this.amplitude + 1.0f) * sprite.bounds.size.x)); 30 this.properties.SetFloat(Amplitude, this.amplitude); 31 this.properties.SetFloat(Wavenumber, this.wavenumber); 32 this.properties.SetFloat(Offset, this.offset); 33 this.spriteRenderer.SetPropertyBlock(this.properties); 34 } 35 36 private void OnEnable() 37 { 38 this.spriteRenderer = this.GetComponent<SpriteRenderer>(); 39 this.properties = new MaterialPropertyBlock(); 40 } 41}
下図のようになりました。
ただし、スプライトには設定項目がいろいろありますが、設定によってはうまくいかないケースがあるかもしれません。特にMesh TypeはTightよりもFull Rectの方が無難かと思います。今回の例では波打ちの余地を作るために単純にスプライトのメッシュを水平方向に引き伸ばしてみたのですが、Tightだとメッシュの形がスプライトの不透明部分に合わせた不定形になりますので、波打ちに部分的な欠けが生じてしまう可能性があるでしょうね。
投稿2021/11/07 14:42
総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/08 12:35