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

ゲームで、ローマ字と日本語の使い方のUIチャレンジ

ゲームで英語やどんな外国語で書き方が難しいになれるから、UIデザインしながら何すればいいの?いいコツを紹介します。UnityやUnrealが使えるでも、本当に役に立つ! ゲームのUIデザインに気になったで、日本語勉強ながら自分のゲームで日本語を使ってやってみたかった感じです。ゲームでUIデザインはとあるチャレンジだと思うけど、全く違う言語を使えば、もっと高くチャレンジでしょう。 日本語で書いたブログ記事のは初めてです。自分が何年後でその記事をまた読めば、「その時代からもっと上手になった」と思えて欲しいな。外国人として別の考え方があれば、これで色々についてゲームプログラマーを手伝ってくればいい喜んで。 言語の書字方向 同じデザインを使って例です。言及がわかるか? 日本語では縦書きと横書きあるんですけど、ローマ字を使う言語だったら、あまり使いません。どうしてか、その言語たちには縦書がないのですか?理由が簡単。初めに違う文字が同じ幅や高さではないし、それに句読点を使えば難しになれるかもしれない。 たとえば、本やゲームの背表紙に文字が縦書きで90度傾いた。これで、ちょっと読みにくいだが別の方法がないのですね。 それより、地下鉄線の地図に面白いやり方がある。45ぐらい度で書けば、横書きほど広くない、そして縦書きほど読み方は難しくない。ゲームUIで同じ方法を使えるかどうか知らないけど面白いことだと思います。 文字の広さ 時々、店先は文字の高さが構わありません。 日本語に漢字があるから、短いテキストで色々書けて、UIデザインで便利です。ただ、一つ漢字だけの言葉は外国語で長いになれる。「雷」は英語で「Thunder」になるとか、「スキル」はフランス語で「Compétences」になるとか。 狭いところに長い言葉を書くために、文字の圧縮がよく起きます。できれば、特にローマ字だと、圧縮しないの方がいい。日本語だと、ちょっと圧縮されたのはデザイン選択になれる、たとえばエヴァタイトル画像のように。こいうい、読むやすい、かっこいイメージができます。 【おすすめポイント】UIデザインのどこでも、日本語の言葉よりちょっと広い言葉が書けば、いいです。さっき話したの例とか。 もちろん、言葉よりアイコンが使えるけど、アイコンの分かり方が難しいになれば、言葉を使うの方がいいです。それとも一緒でアイコンと言葉を書けます。外国の文化が違ってので、日本人と分かりやすいアイコンが外国人と分かりにくいになれるから、注意してください。 アイコンの意味のように、色の意味は文化の問題です。たとえば、赤い確認ボタンは日本でよく見たことですが、自分として赤が確認よりキャンセルボタンのイメージですよ。 おすすめポイントのまとめです。 フォントについて フォントの多様性が面白いだと思います。 サイトにもゲームにも、色々フォントを使うのは普通ことですね。日本語フォントやCJKフォントより、ローマ字のフォント作りはもっと簡単です。 ローマ字のフォント作りはあまり難しくない。AからZの文字、番号の文字、そしてアクセント付き文字と。それより日本語のフォントのために、いっぱい漢字が必要だから、漢字なしフォントもあるし、漢字が少ないフォントもあります。 例のため、明太子はひらがなで書きました。 日本語で書けるフォントの探しが難しかもしれないが、絶対ありますよ。形や色より、フォント選びはデザインの意味を持つ。とあるフォントが万年筆みたいとか、とあるフォントがモダーン感じあるとか、真面目の感じとか。「セリフ体」と「サンセリフ体」のように、日本語フォントには「明朝体」と「ゴシック体」があるから、何のためにを考えて正しいフォントを選びます。 その上、もっと別の体がありますよ!ローマ字で「スラブセリフ体」、日本語で「丸ゴシック体」、ソースコード用のは「等幅フォント」とか。 「セリフ体」だと、最近はほとんどボディコピーのために使っている、ちょっと古い感じだからだと思います。逆に「明朝体」はいつでも使えると思う、きれい鉛筆のいイメージがあるから。 日本製ゲームにローマ字が見せたら、「ニューロダン」などがよく使っています。多分、フォントワークスの使用が人気だから。悪いフォントじゃないけど、気づきやすいし、どこでも見えれば詰まらないになれると思います。ゲームには「詰まらない感じ」がダメでしょうね。別のフォントを使えばいいです。 【おすすめポイント】色々ローマ字フォントをよく調べて、「セリフ体」と「サンセリフ体」どっちを使えばいい考えて、面白いフォントを選んでなど。いい無料フォントもあるですが、商業利用ができるかどうか、ちゃんとチェックしてね。 それでは、文字の強調のために。 ローマ字だと「ボールド体」や「イタリック体」など使えますね。これで、たとえば同じ色のもテキストに、大切事がよく見えます。もちろん、日本語でもそう言うことができるけど、違うかどうかよく見えるかな。下線も使えるが、漢字の読み方は難しいにならないかな。外国人として読みにくいだと思います。限りが色々あります。 【おすすめポイント】ゲームに文字のサイズを注意してくだない。みなが大きくテレビ持っていないし、Switchの画面も大きくないし、字幕やメッセージが小さい文字で書けた読みにくいになります。最近、よく見えることですよ。文字の高さが設定に決定できれば一番いいです。 ゲームとの関係 さて、なぜかゲームと書き方はそんな大切な問題ですか? 第一の当然な思いは翻訳、又はローカライズと言うことです。翻訳はもちろん、とある言語から別の言語を訳すつもりです。時々、吹き替えもあります。ローカライズは翻訳より、ゲームをもっと変わります。たとえば、とある国の文化を調べてと、ゲームの失礼なことを変わりなきゃいけないとか。昔は人や物の名前も換えましたが、最近はもうしません。 もしデザインのどこか、翻訳者が選択した言葉がよく書けない場合は、答えが二つある。一つ目は外語のためにデザインを変わる。ふつ目は意味を変わるでも、文字を圧縮するでも、なんとか言葉を書くこと。もちろん、一つ目の方がいいですよ。翻訳者が一番いい言葉を決めたら、ただデザインが悪いので、変わることが良くないでしょう。 【おすすめポイント】UIデザインをしながら、別の言語をちょっとだけでも考えてください。自分で英語の言葉をチェックして、長いや難しい言葉になれるかどうか調べてね。これで、ローカライズの時が来たら、UIが問題になりません。 とあるゲームにローマ字を使うメッセージ テキストを見せることが時々簡単ではない、社内で作ったゲームエンジンを使るからとか。上の例を見たら、ローマ字の文字の整列が大丈夫ではない。遠く見ればあまり気づけないですが、ズームをすれば、問題が見えます。文字が同じベースラインに整列しません。ベースラインはローマ字の書き方で常識ですので、それも注意してください。 ソースコードで 自分で作ったメッセージシステムです。 とある物が外語でただ一つ名前があれば、難しい翻訳は必要ないです。たとえば、ローマ字を使えない言語の固有名詞だったら、どんな別の言語でも同じローマ字で書きますね。その場合は、ソースコードで二つフィールドを使ってもいいだと思います。一つ目は本名(日本語など)そして二つ目はローマ字で。 「ローマ字」の意味は「ラテン文字で日本語の書き方」だし、日本内だけの言葉だし、コードで「ラテン文字」を使うのほうがいいだと思います。 String name_ja = "梅田"; String name_latin = "Umeda"; 上の例の言うとおり、違う書き方のために、同じフィールドが名前の後で接尾辞が書けます。 フィールドの本名はnameだから、日本語でフィールドは「name_ja」と、ラテン文字では「name_latin」です。この例が駅の名前なので、ふりがな文字でもフィールドも使えると、「name_furigana」のフィールドになります。 name_jaよりname_originalを書いたが、どっちでもいいです。 【おすすめポイント】言葉が日本語ではないのところで、おすすめはフィールドでISO 639-1コードを使うことです。朝鮮語のコードがkoなので、「name_ko」になります。日本に別の産業規格があるので、ISO 639-1よりJIS X 0412-1があるのですけど、ゲーム作る産業でよく使うかどうか知りません。多分ソフトにISO 639-1コードがもっと人気かな。 今回はここまでです。読んでありがたいです。そのトピックで話したいなら、ツイッターは@komanakun、Wantedlyはこちらです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]URPで始める!シェーダー入門

シェーダーをいつかちゃんと勉強しなきゃと思ってる間に、UnityのアプデでSRPが出た!とか描画に関する大きな進歩があったみたいで、これはいよいよ後回しにしてると追いつけなくなるぞと思い、話題の HLSLシェーダーの魔導書 を読み始めました。 ▲この本 本当にイチから説明があり、シェーダー初心者の自分にも分かりやすいです! ただ、この本はあくまでHLSLシェーダーの本で、サンプルコードはWindowsアプリケーション上で動かすように作られているため、そのままUnityで記述することはできません。(アルゴリズムや基本的な関数などは丸々参考にできます。誤解なきよう) また、Unityには独自に用意されたHLSL関数群があり、例えばライトの取得などの方法も当然この本で記載されてるものと異なります。 ということで、 本で得たシェーダーの知識をUnityで実装をしてみる 次世代モバイルの標準になるURPの書き方にする の2つの目的で諸々まとめました。 同じくシェーダー初心者のUnityエンジニアの足がかりになれればと思います。 そもそもURPとは? Universal Render Pipelineの略称です。 「Render Pipeline」とは、ざっくり言うと 3Dの描画の手順のこと で、ゲームエンジンごと、ツールごとに異なります。 Unityも独自のレンダパイプラインで3Dを描画していましたが、近年のアップデートで、大幅な改善が入ったHDRPとURPというレンダパイプラインが追加されました。 URPはモバイル機を意識した軽量なレンダパイプラインで、これからのゲーム開発はとりあえずURPで作った方が良いらしいということだけ知っていれば十分だと思います。 詳しく知りたい方はこちらがオススメです! ちなみにHDRPは次世代ゲーム機を意識した超高機能なレンダパイプラインです。 HDRPの環境下で作られたUnityのデモ動画がこちら。 すげえ。 URPのプロジェクトの作り方 新規プロジェクト作成時に「Universal Project Template」を選択する Package Managerから「Universal RP」を検索してインストールする のどちらかで作れます。 URP版のUnlitシェーダー シェーダーを作るときは、上図のような「ただモデルにテクスチャを貼り付けるだけ」の最低限のシェーダーであるUnlit Shaderから書き始めると、シンプルなテンプレートから必要な機能を載せていけるので実装しやすいです。 Unityが提供してるUnlit Shaderのテンプレートを Create ▶︎ Shader ▶︎ Unlit Shader から新規作成することができます。 ただしこれは旧式のレンダパイプラインである、ビルトインレンダリングパイプラインでも動作する記述になっていて、URPに最適化された記述になっていないです。URPのメリットを享受できないことにもつながるため、まずはURP版のUnlitシェーダーを作ります。 Unlit.shader Shader "Custom/Unlit" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } LOD 100 Pass { Name "ForwardLit" Tags { "LightMode"="UniversalForward" } HLSLPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float fogFactor: TEXCOORD1; float4 vertex : SV_POSITION; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); CBUFFER_START(UnityPerMaterial) float4 _MainTex_ST; CBUFFER_END v2f vert (appdata v) { v2f o; o.vertex = TransformObjectToHClip(v.vertex.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.fogFactor = ComputeFogFactor(o.vertex.z); return o; } float4 frag (v2f i) : SV_Target { // sample the texture float4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); // apply fog col.rgb = MixFog(col.rgb, i.fogFactor); return col; } ENDHLSL } } } こちらのサイトを参考にさせてもらいました。 落ち影に関する記述も引用するとコードが長めになってしまうので、そちらは今回は取り除いています。 このシェーダーをモデルに反映するとテクスチャの色がそのまま反映され、陰影がなく立体感は表現されていないことが分かると思います。 備考:URPで用意されているUnlitシェーダー URPのUnlitシェーダーとしてはUniversal Render Pipeline/Unlitが用意されています。 ただ、300行にも渡る長いコードになっていてここから触り始めるには「おまじない」が多すぎるため、今回は最低限のコード量のテンプレートとして上記使います。 URP版Diffuseシェーダー Diffuseは、光の角度とモデルの面の向き(法線ベクトル)で影の暗さを決める、最もシンプルなシェーディングです。 Unity標準シェーダーにMobile/Diffuseがありますが、これはURP環境下では動きません(シェーダーエラーでお馴染みの真っピンクになる) 入門にちょうどいいので、さっきのUnlitシェーダーをベースにまずはこれを実装しつつ、シェーダーの書き方をまとめてみます。 ①Lighting.hlslをinclude まず、URPでライトを取得するための関数が用意されているLighting.hlslをincludeします。 Diffuse.shader #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" // <- 追加 #includeでは、計算に使う関数などがまとまっているファイルをシェーダーに含めることを宣言しています。 URP以前のレンダパイプライン(ビルトインレンダパイプライン)では、UnityCG.cgincなどのファイルをincludeしていましたが、URPではcom.unity.render-pipelines.universal以下のhlslファイルを使うことが多いようです。 ②構造体に法線情報を付加 次に、頂点シェーダー(vertメソッド)、ピクセルシェーダー(fragメソッド)で扱う構造体に法線情報を付加します。 Diffuse.shader struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; // <- 追加 }; struct v2f { float2 uv : TEXCOORD0; float fogFactor: TEXCOORD1; float4 vertex : SV_POSITION; float3 normal : NORMAL; // <- 追加 }; appdataは頂点シェーダーの引数に使う構造体として宣言していて、モデルの情報を格納する変数を定義しています。 v2fは頂点シェーダーの返り値兼、ピクセルシェーダーの引数に使う構造体として宣言していて、ピクセルシェーダーの計算に使う変数を定義しています。 変数名の横に:を挟んで記述されているPOSITIONなどのキーワードは、「セマンティクス」と呼ばれるもので、「3Dモデルのどのデータを使用するか」を指定するものです。 ▼セマンティクスの例 名前 説明 POSITION オブジェクトベースの頂点座標 SV_POSITION オブジェクトベースの頂点座標(頂点シェーダーの返り値版) TEXCORD UV座標 NORMAL 法線ベクトル ▼セマンティクスのリファレンス ③頂点シェーダーからピクセルシェーダーに法線情報を渡す 頂点シェーダーからピクセルシェーダーに渡すデータに法線情報を載せます。 Diffuse.shader v2f vert (appdata v) { v2f o; o.vertex = TransformObjectToHClip(v.vertex.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.fogFactor = ComputeFogFactor(o.vertex.z); o.normal = v.normal; // <- 追加 return o; } 頂点シェーダーは、引数にモデルの情報を持つ構造体を持ち、やりたい表現に合わせてモデルの情報をイジる処理を書く場所です。 例えば、一枚の板状のモデルを波や旗のように揺らめかせるような処理が書けたりします。 頂点シェーダーのメソッド名は#pragma vertex ○○というような記述で定義してます。 本記事でのコードでは#pragma vertex vertとしてるので、vertメソッドが頂点シェーダーの記述場所になります。 今回は特別な処理は無く、陰影の計算に使う法線情報を返り値に載せるだけです。 ④Diffuseシェーダーのアルゴリズムを書く ピクセルシェーダーで、ライトと法線の向きでできる影を考慮して各ピクセルの色を計算します。 Diffuse.shader float4 frag (v2f i) : SV_Target { // sample the texture float4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); //////////////////////// // ▼ここから // ライト情報を取得 Light light = GetMainLight(); // ピクセルの法線とライトの方向の内積を計算する float t = dot(i.normal, light.direction); // 内積の値を0以上の値にする t = max(0, t); // 拡散反射光を計算する float3 diffuseLight = light.color * t; // 拡散反射光を反映 col.rgb *= diffuseLight; // ▲ここまで追加 //////////////////////// // apply fog col.rgb = MixFog(col.rgb, i.fogFactor); return col; } ピクセルシェーダーは、引数に頂点シェーダーの返り値の構造体を持ち、モデルの各位置をどのような色にするかを決める処理を書く場所です。 今回のように陰影をつけたり、リムライトと呼ばれる縁取りのような表現、トゥーンシェーディングと呼ばれるアニメ調の塗り方など、絵作りに関する様々な手法をここで表現することができ、HLSLシェーダーの魔導書では「シェーダー プログラミングの花形」なんて言われたりしてしました。 ピクセルシェーダーのメソッド名は#pragma fragment ○○というような記述で定義してます。 本記事でのコードでは#pragma fragment fragとしてるので、fragメソッドがピクセルシェーダーの記述場所になります。   陰影については、モデルの法線ベクトルi.normalとライトの向きlight.directionの内積を計算して、結果が0に近づくほど暗くなり、0以下では真っ黒になるような計算をしています。 ここまでの実装で、ライトの方向に合わせてモデルに陰影が付くようになります。 ▲立体感が出ました 備考:数学関数について 内積を計算するdotや2つの数値の大きい方を返すmaxなど、HLSLには様々な数学関数が用意されています。 Unityのプログラムで言うとMathf.○○でアクセスできるような関数が揃っています。 リファレンスは下記ページ。 reflectやrefractのような光のベクトル計算に向いた関数などもあるみたいです。 環境光を反映 これで陰影は付きましたが、ライトと法線の向きの差が90度未満の面は真っ黒になってしまいます。 現実のライトでは床や壁からの間接光によってメインの光源が届かない部分もそれなりに照らされて、真っ黒な部分というのはあまりありません。 とはいえ間接光を真面目に計算すると膨大な計算量になってしまうため、大まかに間接光を再現するシンプルな手段として、モデル全体に一律で光を当てるという手法が使われていました。これを環境光(アンビエントライト)と言います。 Diffuseシェーダーに環境光を実装してみましょう。 まず、環境光の色の変数に定義します。 Diffuse.shader Properties { _MainTex ("Texture", 2D) = "white" {} _AmbientLight ("Ambient Light", Color) = (0.5,0.5,0.5,1) // <- 追加 } ~~中略~~~ ... float4 _MainTex_ST; CBUFFER_END float3 _AmbientLight; // <- 追加 v2f vert (appdata v) { ピクセルシェーダー(fragメソッド)の拡散反射光を乗算している部分に、環境光を加えます。 Diffuse.shader // 拡散反射光を反映 col.rgb *= diffuseLight; ▼▼▼書き換える▼▼▼ Diffuse.shader // 拡散反射光と環境光を足し算して、最終的な光を求める col.rgb *= diffuseLight + _AmbientLight; これで実装は完成です。 Propertiesの箇所に記述を追加したことで、マテリアルのInspectorビューにAmbient Lightの項目が追加されました。 色を調整することで、環境光(擬似的な間接光)を設定することができます。 シーンの環境に合わせて色を設定すると自然と馴染むようになります。 上図ではスカイボックスのグレーの部分に近い色を設定してみています。 〆 古典的なDiffuseシェーダーと環境光の実装を通して、Unityでのシェーダーの基礎的な書き方をまとめました。 HLSLシェーダーの魔導書を読み進めてまた学びが増えたら、同じような切り口で諸々まとめてみたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでマルチプレイする方法

Unity間で通信する方法を調べたので調べたアセットについて記録します。 マルチプレイ向け Photon 専用のPhotonサーバーを介して通信するため、NUTパンチの考慮は不要 利用者が多いので情報が手に入りやすい Photon~って名前の用語が沢山あるので最初は戸惑うが、現時点ではPUN2が無難な選択 音声通信機能あり 無償版の"FREE"と有償版の"+"がある 無料版はモバイル向けにビルドするにはProライセンスが必要 マッチメイキング対応で既存の部屋に参加したり、自分の部屋を作成したりできる。 転送量超過すると課金が発生するので注意 Photon Unity Networking 2 (PUN2) 推奨バージョン Photon Unity Networking (PUN) 現在非推奨でUnity2020以降サポートなし Photon Server サーバー側でロジックを組むことができるサービス サーバー側にデータを保持できる PUN*有償版より高価 Photon Cloud Photon Serverで動作するクラウド版 PUN*と同義 Photon Bolt ホストクライアント方式(P2P) NAT超え考慮必要 Photon Quantum オンラインマルチプレイヤーゲームのための高性能決定論的ECS(エンティティコンポーネントシステム)フレームワーク 情報が少ないので説明省略 Unet 公式アセットだが非推奨のアナウンスあり MLAPI(Mid level API) UNetの代替 無料 現在はUnity公式版に移行中 元々オープンソース個人で開発されていたネットワークゲーム用フレームワーク 1 つのクライアントがホストとして機能し、他のクライアントがそれに接続する、ホスト/リッスンサーバーモデル及び専用ゲームサーバーモデルに対応 旧版 Mirror オープンソースのネットワークアセット 非公式のUNETの後継ネットワークライブラリ P2P その他 以下、Unity公式から引用
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む