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

いつも忘れてしまうCanvas ScalerのUI Scale Modeでテキストをワールドに出すメモ

こういうことよ、という画像 ワールドのなかにテキストを固定で設置したいとき 手順メモ Textオブジェクトを追加 ここはふだんどおり Canvasオブジェクトの設定を変更 Canvas Scalerコンポーネントの設定を変更 「UI Scale Mode」を「Wolrd」に設定する。 「Dynamic Pixels Per うにゃにゃ」の数値を変更する。 Textコンポーネントの設定を変更 フォントサイズは小さくなる Width、Heightは任意で Pos系も任意で 総括 clusterでけっこうお世話になる設定なので、残しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】Shaderを用いて斜めHPバーを作ってみた

はじめに 皆さんは、HPゲージの表示のさせ方について悩んだことがあるでしょうか? Unityではゲージを表現するための機能がいくつか用意されていますが、元の機能のみではどうも思ったような表現が出来ないことがあります。 例えば、斜めのHPバーをImageのfillAmountで作ろうとすると、以下の画像のように現在値が増減させるときに縦に真っすぐな線になってしまいます。    こうではなく、右の画像のように傾きを持たせたいですね。 今回は、このような斜めになった、少しスタイリッシュなHPゲージをShaderを用いて作成していきます。 環境 Unityバージョン :Unity2020.3.18f1 テキストエディタ :Microsoft Visual Studio 2019 目次 よく使われるゲージの増減手法 Shaderを使う準備をする Shaderを書く 中身を見る C#スクリプトを書いて動かしてみる おわりに 1. よく使われるゲージの増減手法 1-1. Sliderを使う 斜めのHPゲージを作る前に、他にどのような手法が使われているか簡単に見ていきましょう。 Slider(スライダー)はツマミを掴み、ドラッグすることでゲージの値を変化させることが出来るものです。よくゲームの音量調整や明るさ調整などに使用されています。 このツマミを削除し、ゲージの変化をスクリプト側から行うことでHPゲージのようなふるまいをさせることも可能です。 エディタ上のタブのGameObject/UI/Sliderから作成できます。 1-2. ImageのfillAmountを使う fillAmountは、様々な手法でImageの表示面積を削ることができる機能です。縦にゲージを減らしたり、円形に減らすなど、Sliderより様々な表現を作り出すことが出来ます。 まず、GameObject/UI/ImageからImageを作成し、InspectorからImageコンポーネントのSource Imageに変化させるSpriteをアタッチします。その後、Image TypeからFilledを選択するとFill Amountのプロパティが表示されます。 実際にこのスライダーを動かしてみると、Imageが削られているのが確認できます。 Fill MethodやFill Originの値も変更して遊んでみましょう。 2. Shaderを使う準備をする では、すぐに斜めに傾けるShaderを書く...といきたいところですが、いくつか準備をする必要があります。 Spriteを用意する Shaderファイルを作成する ShaderをアタッチするMaterialを作成する MaterialをGameObjectにアタッチする 2-1. Spriteを用意する 今回はこちらの白色の画像を使用します。 Unityを3Dで起動し、この画像のTexture TypeをDefault → Sprite (2D and UI)へ変更し、Applyを押して変更を確定します。 2-2. Shaderファイルを作成する Projectウィンドウから、右クリックし、Create/Shader/Image Effect Shaderを選択します。 2-3. ShaderをアタッチするMaterialを作成する 2-2と同様にして、Create/Materialから新しいMaterialを作成します。 その後、先ほど作成したShaderファイルをドラッグ&ドロップでこのMaterialにアタッチします。 これで、このMaterialに先ほど作成したShaderが適用されました。 画像のように、Materialのプレビューが真っ黒になっていれば成功です。 2-4. MaterialをGameObjectにアタッチする 最後にこのMaterialを適用するGameObjectを作成します。 Hierarchyウィンドウから、右クリックし、UI/Imageから作成します。 すると、Canvasの中にImageコンポーネントを持つゲームオブジェクトが生成されます。 次に、Imageを選択し、先ほどの横長の画像をSource Imageに、作成したマテリアルをMaterialにアタッチします。 以下のような画像になっていれば大丈夫です。 最後に、一番下にあるSet Native Sizeをクリックし、Imageのサイズを整えます。 これによって、Imageにも真っ黒なMaterialが適用されました。 3. Shaderを書く では準備もできましたし、Shaderファイルを開いてみましょう。 いきなり大量にコードが出てきましたが、ご安心ください。今回はこのうちの一部を変更・追加するのみですので。 以下のように書き換えてみましょう。 SlantHPShader.shader Shader "Hidden/SlantHPShader" { Properties // プロパティを置ける { // 追加 _FillAmount("FillAmount", Range(0.0, 1.0)) = 1.0 // 値を増減させるためのプロパティ _Color ("Color", Color) = (1, 1, 1, 1) // 色を変更するためのプロパティ } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Blend SrcAlpha OneMinusSrcAlpha // 追加 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } // 追加 float4 _MainTex_TexelSize; // テクスチャのサイズに関する情報を持つ float _FillAmount; fixed4 _Color; fixed4 frag(v2f i) : SV_Target { // 追加 fixed4 color = _Color; // 処理中の座標の色を_Colorに float h = _MainTex_TexelSize.w; // テクスチャの縦のピクセル数 float w = _MainTex_TexelSize.z; // テクスチャの横のピクセル数 // 左端を斜めにする処理 if (i.uv.y > i.uv.x * w / h) { color.a = 0.0; // 色のアルファ値を0(透明)にする } // 右端を斜めにする処理 else if (i.uv.y < i.uv.x * w / h - (w - h) / h * _FillAmount) { color.a = 0.0; // 色のアルファ値を0(透明)にする } return color; } ENDCG } } } 1行目の名前は"Hidden/(このシェーダーの名前)"となるようにしましょう。それ以外の部分であればコピペしても正しく動作するかと思います。 4. 中身について さてこのスクリプトの中ではどのような動作が行われているのでしょうか。変更した部分について、詳しく見ていきましょう。 4-1. Propertiesブロック内 ShaderLab: Properties シェーダーを使って Unity の マテリアルインスペクター でアーティストが設定するパラメーターを定義できます。 ここで宣言した変数が、MaterialのInspector画面から調整できるようになります。 作成したMaterialのInspectorを見てみると、下画像のようにFillAmountとColorの2つの値が調整できるようになっていることがわかります。 実際にこの値を動かしてみましょう。 FillAmountの値を動かすと、0から1の範囲で、それに合わせて用意していたImageのゲージが変化していきます。しっかり傾いた状態を維持していますね。 Colorは今回、Imageコンポーネントの色を取得するつもりなので、ここでは白色のままにしておきます。 4-2. fragブロック内 このブロック内では、Imageの両端が斜めになるような数学的な処理と色変更を行っています。 斜めの表現を作るために、描画する範囲を領域の考え方を用います。 上の画像のように、まず両端の傾け度合いを考えます。今回は一番単純な45度の傾きを考えました。 用意したSpriteの横の長さをw、縦の長さをhとすると、このような式を作ることができます。 次にこれを直接プログラムに書き記したいところですが、xとyを表現する際に使用するi.uvという変数はそれぞれ0~1の範囲しか持たないため、上の式を下図のように書き換える必要があります。 xy方向の長さをそれぞれ1とする場合、それぞれの値にwやhの逆数を掛けることで割合を求めることが出来ます。 さらに、この右辺の切片の部分にPropertiesブロック内で宣言したfillAmountの値を掛けることでゲージの増減を考えることが出来ます。つまり、このようになります。 y > \frac{w}{h} x - \frac{w - h}{h} \times fillAmount そして最後に、これをプログラムに落とし込みます。 今回は領域内を描画するのではなく、反対に領域外を描画しない(不透明度を0にする)方法を取ります。そのため、図に表示されている不等号を反対向きにする必要がありますね。 // 左端を斜めにする処理 if (i.uv.y > i.uv.x * w / h) { color.a = 0.0; // 色のアルファ値を0(透明)にする } // 右端を斜めにする処理 else if (i.uv.y < i.uv.x * w / h - (w - h) / h * _FillAmount) { color.a = 0.0; // 色のアルファ値を0(透明)にする } そして、この条件に一致する場合にcolor.a = 0.0と不透明度を0にすることで、範囲外を見せないようにしています。 5. C#スクリプトを書いて操作してみる では最後に、このFillAmountの値をC#スクリプトから変更してみましょう。 GaugeController.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GaugeController : MonoBehaviour { private Material mat; // Materialのインスタンス private Image img; // アタッチされたゲームオブジェクトのImageコンポーネント [SerializeField, Range(0.0f, 1.0f)] private float fillAmount = 1.0f; // ゲージ量 // Start is called before the first frame update void Start() { img = GetComponent<Image>(); // Imageコンポーネント取得 mat = Instantiate(img.material); // Materialのインスタンス生成 mat.SetColor("_Color", img.color); // Materialの色指定 img.material = mat; // ImageのMaterialをインスタンス化したMaterialに変更 } // Update is called once per frame void Update() { mat.SetFloat("_FillAmount", fillAmount); } // ゲームオブジェクトが破棄されたときに呼び出される private void OnDestroy() { // インスタンスを持っていたら破棄する if (mat != null) { Destroy(mat); } } } 5-1. Materialのインスタンスを作成する 現在ImageコンポーネントにアタッチしているMaterialは、Assetsフォルダ内のMaterialを直接指定しています。そのため、このままFillAmountの値を変更しようとすると、他のゲームオブジェクトまで値が変更されてしまいます。 それを回避するために、スクリプト内でMaterialのインスタンスを生成し、アタッチしなおしています。 5-2. 色や値を変化させる 実際にこのスクリプトをゲームオブジェクトにアタッチしてみましょう。 色も実際のHPバーっぽく黄緑色にしてみました。 そして実行し、スクリプトのFillAmountのスライダーを動かすと、実際に動くのが確認できます。 これで、斜めに傾いたHPバーが完成しました。 この値を別スクリプトから参照したり、色を変えたりと様々な場面で使うことが出来そうです。 6. おわりに 今回は、斜めに傾いたHPバーをShaderを用いて作成しました。 まさか、数学の領域の知識を使うことになるとは思わず、Unityで使う場面があったことに喜びを隠せませんでした。 ただ、Shaderの中にif文を書くことは、パフォーマンスの低下に繋がるためあまり良くないという話をよく耳にします。そのため、これを如何にして改善するのか、今後の課題にしたいと思っています。 ありがとうございました! 参考文献
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】Cinemachine で即座にバーチャルカメラの位置にリセットする

Unity が所持する強力なカメラシステム Cinemachine ですが、位置の初期化でつまづいてしまったので備忘録です。 確認バージョン Unity 2020.3.13f1 Cinemachine 2.6.10 はじめに Cinemachine はカメラ本体とは別にバーチャルカメラという仮想の概念があり、このバーチャルカメラ間をカメラ本体が渡り歩いていくイメージで、効率よく滑らかなカメラワークを実現できます。 ですのでバーチャルカメラをワープ1させたとしても、カメラ本体はそれに遅れる形で滑らかにバーチャルカメラの位置まで移動していきます。 ですが、配置、リスポーン、テレポートなど、補間などせずすぐにバーチャルカメラの位置に合致してほしいシチュエーションはありますよね。 たとえカメラ本体(CinemachineBrain)の transform を直接設定しても、内部の補間計算は続いているため、結局補間途中の位置に戻されてしまいうまくいきません。 今回はカメラ本体をすぐにバーチャルカメラの位置に飛ばすやり方のメモになります。 方法 要するに補間処理を打ち切ってやれば OK でして、やり方はバーチャルカメラの位置を変える処理の直後で CinemachineVirtualCameraBase.PreviousStateIsValid を false に設定するだけです。 _cinemachineVirtualCameraBase.PreviousStateIsValid = false; 私は CinemachineBrain 側からアプローチしたかったので、次のように使いました。 (_cinemachineBrain.ActiveVirtualCamera as CinemachineVirtualCameraBase).PreviousStateIsValid = false; ちょっと名前が直感的でないため意図が読みにくいコードですが、これでやりたいことが達成できましたので、同じようなことでつまづいている方の参考になれば幸いです。 参考 Unity Forum: Proper way to 'reset' follow camera? CinemachineVirtualCamera の Follow や LookAt のターゲットを変える、もしくは transform を直接設定するなど。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む