質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

845閲覧

unityでスプライトをぐねぐねさせたい

shioduke-kurage

総合スコア1

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/11/07 09:01

編集2021/11/07 11:07

前提・実現したいこと

初めまして!
unityでrpgのプログラミングに挑戦している初心者です。

unityでポケモン金銀のへんしんのように、
四角形平面オブジェクトをスクリプトから"ぐねぐね"させることは可能でしょうか?
どんな方法が考えられますか?
調べながら頑張ります。

私が思い付くのはシェーダーを使うことぐらいで。。

リンク内容
↑0:53頃へんしんがうつってます。

左辺で間隔を開けて3点、
右辺でもずらして3点。
左右に広げて戻す表示というと、
やはりシェーダー以外ではできないでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

Bongo

総合スコア10811

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shioduke-kurage

2021/11/08 12:35

回答ありがとうございます! ふむやはりシェーダー。。! 実はシェーダーを書いたことはなくて、 まだわからないところがありますが。。 今から頑張って読み解いてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問