- 投稿日:2021-12-30T17:41:43+09:00
BPMに合わせてオブジェクトを点滅させる(HDRP/lit編)
HDRPでオブジェクトを点滅させたい させたいですよね。 最初はHDRP/litの_EmissiveIntensityをスクリプトから操作して点滅させようとしましたが、値は変わるのにGameViewに反映されませんでした。 あきらめて、_BaseColorで点滅させられるように作りました。 EmissiveColorを前もって明度の高い色(白)にしておけば、 ぴかぴか点滅してくれます。 色はスクリプト上でいじります。 インスペクタ―で設定できるのはBPMだけです。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class EmissionBlinking : MonoBehaviour { private Material material; private float length = 1.0f; public int bpm = 120; void Start() { material = GetComponent<Renderer>().material; } void Update() { float span = bpm / 60; //1秒に何ビートか? float val = Mathf.PingPong(Time.time * span * 2f, length); //BPMの拍に合わせて点灯させるために *2 する Color color = new Color(1.0f - val * val, 0f, 0f); //RGBで任意の色にする material.SetColor("_BaseColor", color); } } プログラミングなんてできねえ! と思いながら始めたC#学習も、なんとかかんとか触りだけはこなせました。 よい映像制作につながるように来年もがんばります。
- 投稿日:2021-12-30T17:34:43+09:00
Firebase Local Emulator Suite を.NET SDK で利用する
FirebaseのEmulatorをJavaScriptのSDKを使って利用する方法はネット上に豊富にあるのですが、 .NETのSDKを使ったやり方はあまり情報が無かったので記事にしました。 Emulatorの構築方法についてはこの記事では割愛させていただきます。 基本的には環境変数を設定してから呼び出す流れでいけるはずです。 実際にやってみたのは以下2つ。 Cloud Firestore FirebaseAdmin Auth cloud Firestore // 環境変数にemulatorへの向き先を設定 Environment.SetEnvironmentVariable("FIRESTORE_EMULATOR_HOST", "localhost:8080"); var firestoreDb = new FirestoreDbBuilder() { // 何でも良さそう? エミュレータ起動時に指定したproject名にしておけば安心 ProjectId = "testproj", // エミュレータへの接続を強制しておけば安心 EmulatorDetection = Google.Api.Gax.EmulatorDetection.EmulatorOnly, }.Build(); FirebaseAdmin Auth // 環境変数にemulatorへの向き先を設定(ローカルでデフォルト設定ならlocalhost:9099) Environment.SetEnvironmentVariable("FIREBASE_AUTH_EMULATOR_HOST", "localhost:9099"); FirebaseAdmin.FirebaseApp.Create(new FirebaseAdmin.AppOptions() { // でたらめで良いので何らかのCredentialを指定する Credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromAccessToken("mocktoken"), // エミュレータ起動時に指定したproject名 ProjectId = "testproj", }); 番外編 非公式のGoogleCloudStorageエミュレータ、fake-gcs-serverへの接続はこんな感じ。 .NETから使う際は起動時に-external-urlで自身のURLを引数指定してやる必要がある模様。 gitのexsamplesに.NETから呼び出す用のDockerファイルが用意されているので、それを使えば手っ取り早い。 var client = new StorageClientBuilder() { // URLはフルで指定 BaseUri = "http://localhost:5678/storage/v1/", // 認証無しで接続 UnauthenticatedAccess = true, }.Build();
- 投稿日:2021-12-30T13:14:50+09:00
ResXManagerを使用して多言語対応を行う
0. はじめに Visual Studioで多言語対応が必要なアプリケーションを開発する際、ResXManagerという拡張機能が便利そうだったので、使用方法などを簡単にまとめてみました。 ResXManagerは、各言語リソースファイルを開かなくとも、専用の画面で言語キー(文字列)を追加/更新/削除できる機能になります。 1. ResXManagerをダウンロードする Visual Studioメニューの「拡張機能 > 拡張機能の管理」から、ResXManagerをダウンロードします。 ※ダウンロード後、変更を反映するため、Visual Studioの再起動が必要かと思います。 2. 言語リソースファイルを追加する まずは準備として、ソリューションエクスプローラーコンテキストメニューの「追加 > 新しい項目」からリソースファイルを作成します。 名前は何でもいいですが、私は「Strings.resx」としました。 3. ResXManagerを使ってみる Visual Studioメニューの「ツール > ResX Manager」を選択すると、ResX Resource Managerが起動します。 3-1. デフォルトの言語を変更する Configurtionタブの「Netural Resouces Language」から、デフォルトの言語を変更できます。 元々は英語になっているかと思いますので、日本語に変更しました。 3-2. 言語を追加する Mainタブの「Add new language」から、言語を追加できます。 今回は英語・フランス語を追加してみました。 対応するリソースファイル(Strings.en.resx、Strings.fr.resx)が自動で生成されます! 3-3. キー(文字列)を追加する 「Add new key」から、キー(文字列)を追加できます。 文字列を追加しない場合は、赤塗りで表示されます。 3-4. キー(文字列)を削除する 「Delete selected items」から、キー(文字列)を追加できます。 4. 出力してみる class Program { static void Main(string[] args) { // 日本語 Console.WriteLine(Strings.HelloWorld); // 英語 Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); Console.WriteLine(Strings.HelloWorld); // フランス語 Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR"); Console.WriteLine(Strings.HelloWorld); } } 5. おわりに 「〇〇言語に〇〇キーの文字列が設定されていない!」ということにすぐ気づけるのでとても便利ですね(今回この拡張機能を使おうと思ったきっかけがコレでした) 私が必要としていた機能は上記に記載した範囲でしたが、他にも「キー(文字列)のコピー/ペースト」「エクセルへのインポート/エクスポート」 といったことが行えるみたいです 良いお年を!!!!!
- 投稿日:2021-12-30T12:22:51+09:00
Unityの学習まとめとして超簡単なRPGを作ってみた!
はじめに 普段はWebアプリ関連のお仕事をしているのですが、「久しぶりにUnity触りたい!」という気持ちになったので約2週間程度ではありますが集中的にUnityを勉強して超簡単なRPGを作ってみました。 (一応2年半前にも一度Unity熱が上がり、少し勉強していた時期はあるので今回が完全に初見という感じではありません。) ゲームの内容 ゲームの内容としては、単純にドラゴンを倒して村を救うぞ!という感じの王道なやつです。 以下に作ったゲームの簡単な解説を記載していきます。 ゲームスタート画面 プレイヤーのパワーアップイベント 簡単なオープニングが終わった後、フィールドへプレイヤーが配置されます。 さあ、ボスであるドラゴンを倒しにいくぞ!と言いたいところですが、いきなりボス戦というのも何かなぁ...と思ったので一度村に行って装備を最新にするというイベントを挟む必要があるようにしてみました。(村に行かなくてもドラゴンとは戦えますが確実に負けるようになっています。) ポツンと存在する村 村にてパワーアップイベント 村でのパワーアップイベント後にはHPや攻撃力が増えています。 ※フィールドではランダムでスライムが出てきます。 パワーアップ前 パワーアップ後 ドラゴン戦(ボス戦) 森を駆け巡り、ドラゴン(ボス戦)へ辿り着きます。 エンディング 無事に倒したら簡単なエンディングが始まり、ゲーム完了となります。 実装内容 ここからは簡単に実装を振り返ってみたいと思います。 フィールドでの敵とのエンカウント エンカウントについては以下の2つの種類があるかと思います。 ランダムエンカウント →フィールドを歩いていたら一定確率で敵と遭遇(止まっているときは遭遇しない) シンボルエンカウント →敵があらかじめ見えており、戦いたい敵をある程度選べる 今回はファイナルファンタジーのようなエンカウントをイメージしていたので前者のランダムエンカウント方式にしてみました。 ロジックは色々と考えてみたのですが、単純にプレイヤーが動いている かつ ランダムで特定の数字が出るという内容にしてみました。 FieldManager.cs var playerSpeed = Player.GetComponent<Animator>().GetFloat("Speed"); var RateEncount = Random.Range(0, 1200); if(playerSpeed > 1.0f && RateEncount == 50) { PlayerFieldLocation = Player.transform.position; // 位置保存 Player.GetComponent<PlayerController>().MoveSpeed = 0; // シーン遷移中(フェードイン中)は動かないようにする。 fade.FadeIn(2.0f, () => { // 戦闘シーンへの遷移処理 }); } シーン遷移のトランジション 敵とエンカウントした際は戦闘シーンに移るかと思いますが、ただフェードインするだけ、というのも物足りないので渦を巻くトランジションを入れてみました。 敵とエンカウントすると以下のようにトランジションが出てフェードインします。 こちらも特に凝ったプログラムを書いているわけではなく、tsubaki_t1さんが作成してくれたトランジション用のライブラリとFor youさんが提供してくれているルール画像を利用することですんなりと作成できました。 ターン制バトル 敵とエンカウントした場合はバトルシーンに移り、ターン制のバトルが始まります。 ターン制のロジックについては「ゲージがたまったら攻撃アクションを選択できる」ようにしました。 「ゲージをためる」「攻撃アクションを選択後の動作」についてはそれぞれ以下のようにプログラムを書きました。 ゲージをためる SlideController.cs private void FixedUpdate() { // 省略 // ゲージはUnityEngine.UIのスライダーを用い、一定量ずつ増加します。 playerSlider.value += 0.004f; // ゲージがたまり、まだ戦闘アクションが選択されていなかったらパネル表示をします。 if(playerSlider.value == 1 && !AttackButtonController.HasPushButton) { PlayerPanel.SetActive(true); } } 攻撃アクションを選択後の動作 AttackButtonController.cs public void PushAttackButton() { HasPushButton = true; Panel.SetActive(false); // 攻撃アクション選択後はパネルを非表示にする。 var attack = Random.Range(PlayerManager.Attack - 15, PlayerManager.Attack + 15); // 与えるダメージは攻撃力の±15 // 攻撃内容が決まったゲームオブジェクトと与えるダメージをDictionaryで管理 // 敵も同様の実装を行う BattleManager.TurnOrders.Add(Player, attack); } BattleManager.cs void Update() { // プレイヤーも敵も攻撃情報がない場合は何もバトル処理を行わない if (!TurnOrders.Any()) return; // 省略 // バトルターン順に攻撃を行っていく。 var turnCharactor = TurnOrders.First(); if (!IsDuringMotion) { // 省略 StartCoroutine(DelayCoroutine(0.4f, () => { turnCharactor.Key.GetComponent<Animator>().SetTrigger("Attack"); })); } } 会話イベント RPGにかかわらず、ゲームにおいて会話イベントを必要とする場面は多いと思いますが、こちらはFungusというとても便利なアセットがあったのでこちらを利用しました。 あくまで例ではありますが、村での会話シーンは以下のように設定しています。 基本的にはUI上でセリフを設定したり、選択UIも設定できます。状況によってセリフを変更したい場合はif文も入れ込むことができるのでとても便利です。 もしプログラムを実行したいときはCall Methodを選択することでプログラム側のメソッドを呼び出すことも可能です。 おわりに すごく久しぶりにUnityを触ってみましたが、やはりUnityを使うとサクッとゲームが作れるのでとても便利ですね! 無料のアセットも充実していたので、アニメーションや村作成についてはすごく助かりました。 今後の展望としては、パーティーを組んだり攻撃以外のアクション(魔法やアイテム使用、レベルアップなど)も入れていきたいです。