20210914のUnityに関する記事は4件です。

GLSLからHLSLへ変換する方法

ShadertoyのGLSLのソースコードをHLSLへ変換するShaderManというツールがあるのですが、結構癖があるので説明します。 使い方などは以下にやり方が載っているのでそれを参考にしましょう。 ドキュメントが古い Open ShaderMan from Tools\ShaderManと書かれていますが、実際には2021年現在はWindow\ShaderMan です。 エディタの癖が強い コピへして、スクロールしようとすると、Macのマジックパッドなどでスクロールできず、矢印キー下(↓)で進んでいくと、下のコードへ辿り着けると言う仕様になっており、最初文字数制限で下にいけないのかと思ってしまうくらい、非常にわかりにくいUIです。 構文を少しでも違うと、変なエラーが出る 例えば、Shadertoyでよくある以下のようなメイン関数で void mainImage( out vec4 fragColor, in vec2 fragCoord ) in を抜いた状態でconvertを走らせると、以下のようなバグが起こります。 i.uvfi.uvri.uvai.uvgi.uvCi.uvoi.uvli.uvoi.uvri.uv i.uvfi.uvri.uvai.uvgi.uvCi.uvoi.uvli.uvoi.uvri.uv <省略> 変更しないといけないコード iFrame -> Time.y tex2Dlod(_MainTex, uv, x) -> tex2Dlod(_MainTex, float4(uv, x, 0))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity ScalerPanelベースサイズに応じたサイズ変更

パネルのサイズを固定にして、その配下に固定で、画像やテキストを配置。 パネルのスケールを変更するのみで、比率に応じた倍率にする。 ここでは640x480に固定。倍率は小さい方に合わせる。画面いっぱいに黒画面などを置いて、縦の空きや横の空きをごまかす。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PanelScaler : MonoBehaviour { void Awake() { //Application.targetFrameRate=20; ScaleChange(); } void ScaleChange(){ const float fixed_width=640f; const float fixed_height=480f; var sw=Screen.width/fixed_width; var sh=Screen.height/fixed_height; var scale=Mathf.Min(sw,sh); Debug.Log(scale); gameObject.transform.localScale=new Vector3(scale,scale,1); } } パッケージ https://github.com/gnjo/UnitySamples
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DynamicBoneはアタッチした順番によって挙動が変わる場合がある

↓の記事で検証したんですが、同じクラスのコンポーネントの実行順はアタッチした順の逆順になります。 【Unity】同じクラスのコンポーネントの実行順はアタッチした順の逆順になる説 それだけ聞くと、だから何だって感じなんですが、実はこれがDynamicBoneの挙動に影響する場合があります。 以下のような場合です。 DynamicBoneで揺らすオブジェクトにDynamicBoneColliderをアタッチする DynamicBone"A"と"B"があり、"A"にDynamicBoneCollider"C"がアタッチされていて、"B"は"C"と衝突するように設定されています。 そして、"A"に何らかの力が加わって右に揺れた場合を考えてみます。 "A"が先に実行された場合 まず"A"が先に実行され、右に揺れます。 その後、"B"がコライダーに押しのけられて右に移動します。 これは想定通りの動きですね。 "B"が先に実行された場合 問題はここからです。 まず"B"が先に実行されます。何の力も加わっていないので、"B"は動きません。 その後、"A"が右に揺れます。 この時、すでに"B"の計算は終わっているので"B"は動きません。 DynamicBoneは毎フレームDynamicBoneの影響を受けていない状態から計算するので、この場合では"B"が"A"の動きに影響されて動くことはありません。 DynamicBoneの子オブジェクトに別のDynamicBoneをアタッチした場合も、このような挙動になります。 これでは困りますね。 対策 同じクラスのコンポーネントは最後にアタッチしたものから順に実行されるので、コンポーネントをコピーしてから削除してアタッチし直すことで実行順を変えることが出来ます。 先に実行されて欲しいコンポーネントをアタッチし直しましょう。 この挙動の原因が分からなくて2時間くらいのたうち回ったので、この情報が誰かの役に立てば幸いです…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity1週間ゲームジャムでのゲーム開発を時系列に沿って細かく紹介します

概要 Unity1週間ゲームジャムという、1週間でゲームを作るイベントに参加しました 実際にゲームを作る過程を紹介することでゲーム制作初心者の方の背中を押せると嬉しいです 作成したゲーム 今回作成したゲームはワクチン注射で世界を救えです。←のリンクから実際にプレイすることができます。PC推奨です 人々にワクチンを摂取させていくことでウイルスの感染を食い止めるゲームです 詳しいルールはゲームページをご覧ください クラス図 クラス図は以下の様になりました 最近、設計を勉強しているのできれいな設計になるように気をつけました 真ん中のGameEventクラス当たりで依存関係が逆転できていてきれいな構造ではないでしょうか 作成の過程 作成の過程を時系列でご紹介します 1日目 午後10時くらいから制作を開始しました 企画決め 今回のお題は「ちゅう」ということでした マインドマップを作ってみます ちなみに、マインドマップ作成に使用したのはオンライン作図ツールのMiroです。操作にストレスが無いのでおすすめです いくつか案を派生させましたが結局、フレッシュなネタということでワクチン注射をテーマに決めました 続いて、ゲームシステムを考えます イメージを膨らませる為にあえて文章無しでアイデアを書き出してみました Miroは標準機能で絵文字を検索して挿入でき、非常に便利です アイデアは以下の通りです 「健康な人」は「ワクチン」を摂取すると「免疫を獲得した人」になる 「健康な人」は「ウイルス」に接触すると「感染者」になる 「感染者」は一定時間経つと「免疫を獲得した人」か「死んだ人」になる 「免疫を獲得した人」か「死んだ人」になる確率は年齢層によって変化する 「感染者」は定期的にウイルスを撒き散らす 「医者」は周囲のウイルスを消す 続いて、ゲーム画面を考えました 始めは以下の様に、人がバラバラに配置して感染が広がる様子を考えてみました 画面左上のバーが時間経過で増えていき、満タンになるとワクチンの摂取が可能になる想定です しかし、これだと人の動きを制御するのが面倒くさそうだと思いました そこで以下の様にグリッド配置にしてみました これなら人の移動を考える必要も無いし、見た目がパズルゲームっぽくてゲームシステムに合っていると思ったのでゲーム画面はグリッド配置に決定しました Unityプロジェクト作成 初日にUnityプロジェクト作成を済ませていると翌日に作業する際の心理的なハードルが下がるため、Unityプロジェクトはいつも初日に作ります ついでに、Gitリポジトリ化も済ませました Unity内でコミットしたいのでGithub for Unityというアセットを使っています 人の顔の画像アセットをどうするか考えました Miroで作った画面イメージが可愛くて気に入ったので、絵文字を使うことに決めました 絵文字をゲーム制作に使っていいか調べたところ、絵文字は各社が独自に作っていることを知りました OS毎に絵文字の見た目が違うのはそんな理屈だったのか... 幸い、Twitter社が公開しているTwemojiがクレジット表示をすれば作品に使用してもいいとのことだったのでこれを使用することに決めました 絵文字の検索にはEmojipediaを使用して必要な絵文字を透過pngで全てDLしました 人の顔をグリッド状に並べるまでして今日はおしまいです 2日目 ワクチン接種機能追加 実装初日はユーザー操作によって画面が変わるところまでを目標にしました まずは人オブジェクトを操作するための「Human」クラスを作成しました マウスクリック検知にはEvent Triggerコンポーネントを使用しました 人オブジェクトにEvent TriggerコンポーネントとHumanクラスをアタッチして、Event TriggerのPointerDownイベントでHumanクラスの「ワクチンを摂取する」関数を呼ぶように設定しました 「ワクチンを摂取する」関数内では顔画像をワクチン接種後の状態に変えています これで、人の顔をクリックした時にワクチンを摂取して顔画像を変える処理ができました 感染機能追加 次に、感染が広がる仕組みの実装に着手しました 人オブジェクトが相互に隣人を監視すると無駄な処理が増えたり制御が複雑になると考えました そこで、HumanManagerクラスを作成してこのクラスが感染の広がりを制御するようにしました とりあえず、難しくするために感染者が周囲8マスにウイルスを拡散するようにしました 以上で2日目は終わりです。目標より進みました 3日目 死亡機能追加 感染者が死亡する機能を追加しました ひとまず、感染者が1ターンで死亡するようにしました ここで一旦テストプレイをしてみました すると、ものすごいスピードで感染が広がっていき、中々感染を食い止めることができませんでした そこで、感染者からのウイルスの拡散を周囲8マスから上下左右4マスのみに変更しました これでそれなりの難易度になりました 3日目は以上です。最低限のゲームループができました 4日目 この日は作業しませんでした ゲームでもしてたかな... 5日目 人の種類を追加 ゲームをより複雑にする為に年齢層のバリエーションを増やしました 企画段階では年齢層毎の差異を死亡確率にしていましたがそれだとランダムなため再現性が低く、短時間で遊べるパズルゲームに不向きだと思いました そこで、感染と死亡までのターン数を年齢層毎の差異とすることにしました 子クラスを作成するのではなく、プレハブバリアントを使用することで成人を子供と老人に派生させました また、年齢層毎にパラメーターが異なることをわかりやすくするために画面下に説明を追加しました TextMeshPro用にいくつか日本語フォントアセットを持っているのでそれからゲームの雰囲気に合っているものを選びました 以上で5日目は終わりです 6日目 6日目は土曜なのでたくさん進めました ゲームオーバーとクリア機能追加 ゲームオーバー画面は以前作ったゲームからコピーしてきました ゲームクリア画面はゲームオーバー画面をプレハブバリアントとして派生させて作成しました 文字色などで違いをつけました 文字やボタンのアニメーションにはDOTweenを使用しました。使いやすくて好きです ボタンにはModern UI Packを使用しました。おしゃれなボタンのプリセットが揃っています。UnityデフォルトのボタンはUnity臭くて使えません ゲームオーバー/クリアイベントは以下の記事で紹介されている、ScriptableObejctを使用したものを採用しました ScriptableObjectを使用してゲームを構築する3つの方法 ゲームオーバークラスとそれを通知するHumanManagerが疎結合になりました イベントの追加やデバッグ用にインスペクターのボタンから実行がしやすくて便利でした 以上で6日目は終了です 7日目 タイトル画面作成 ゲームタイトルを提示するのと難易度選択のためにタイトル画面を作成しました グラデーションを入れて結構凝ったつもりですが見返すとすごく安っぽく見えます。なんでだろ。背景の情報量が少ないからかもしれません 各難易度はシーンをコピーして作成しました 何度もプレイして人の年齢層毎の割合やゲームオーバーになる死亡者のしきい値を調整しました 音楽追加 最後の仕上げとしてSEとBGMを追加しました ボタン押下時やワクチン接種時、ゲームオーバー/クリア時にSEを追加するとクオリティが一気に上がった気がして満足です 素材は魔王魂さんから拝借しました。ありがとうございます 何度選択ボタンを押してシーン遷移するときにボタン押下SEが途切れてしまう問題が発生しましたがDontDestroyOnLoadすることで回避しました。 こちらの記事が参考になりました また、タイトル画面のBGMが初回時のみ鳴らない問題が発生しましたが、これは解決できませんでした Unityroomの他のゲームを遊んでもその様になっているゲームを見つけたのでUnityのバグだと思いたい 以上で7日目完了です 18時ごろにはビルドしてUnityroomにアップロードできました テストプレイすると何故か起動しませんでした。 この問題はUnityroomの設定で使用メモリを1GBにすると解消しました 一般公開 20時になると、ゲームは一般公開され皆さんに遊んでもらうことができました 評価やコメントがついて閲覧数が増えていく様子を見ると作って良かったなあと思いました おしまい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む