GodotPlayerへゲーム投稿する方法

GodotPlayerとは

godotplayer.com

フリーゲーム投稿サイトです。
Godot Engineで作ったゲームをHTML5形式でエクスポートし、
このサイトにアップロードすることでブラウザ上でゲームを遊べます。
Shared Array Bufferに対応し4.xのバージョンにも対応しています。
Godot Engineで作ったゲームをブラウザで遊んで欲しい!と思う方は、アップロード先の一つとして検討してみてはいかがでしょうか。

まずはクリエイターログイン

ゲーム投稿するには、事前にGoogleアカウントを使ったログインが必要です。

初めてGoogleログインすると、GodotPlayerのユーザー登録画面が表示されます。
2つの項目を入力しましょう。

  • ユーザーID名。ユーザープロフィール画面のURLに使用されます。後から変更できないので注意。
  • ユーザー表示名。いろんな画面で表示されます。

余裕のある人は、以下のURLからユーザープロフィールを設定しておきましょう。

https://godotplayer.com/account/profile

ゲームを登録する

ログイン後、画面の右上に「ゲームを登録」のボタンが表示されます。
ここからゲームを登録しましょう。

  • ゲームID名。 ゲームのURLに使用されます。後から変更できないので注意。
  • ゲームタイトル
  • 想定プレイ時間。 これはまだどこにも表示されないですが、余裕がある人は設定しておきましょう。
  • PCブラウザ 表示サイズ
  • Godot Engineのバージョン

ゲームを登録すると、「投稿したゲーム」の画面に先ほど登録したゲームが表示されます。 「設定画面へ」のリンクを押し、各種設定をしていきましょう。

ゲームプロフィールを設定する

  • ゲームタイトル
  • ゲームの紹介文、操作説明
  • サムネイル

など、プロフィールを設定しましょう。

ゲームをアップロードする

左側にあるサイドメニューから「HTML5 アップロード」を選択し、ゲームファイルをアップロードしましょう。
HTML5 アップロードの方法にもある通り、GodotPlayerではエクスポートによって作られた複数のファイルを選択しアップロードを行います。
アップロードが終わると紙吹雪が舞い散り投稿を祝ってくれます。

godotplayer.com

※itch.ioやPlicyのようにzipにまとめる必要はなく、またhtmlファイルをindex.htmlに命名しなおす必要はありません。

ゲームを公開する

テストプレイなどを行い、問題がないことを確認できたらゲームを公開しましょう。
公開設定画面で公開ステータスを変更することで対応できます。

公開後、TOPページをみて自分のゲームが公開されていることを確認しましょう。

まとめ

以上、GodotPlayerにゲームを投稿する方法でした。
もしよろしければ、ご利用ください。

「YOZORA MAKER」というゲームを作りました

f:id:coffee_ryo:20200309215003j:plain

はじめに

unity1weekというイベントに参加し、こんなゲームを作りました!

グレイズのスペルが間違っております!

どちらかというと好意的な反応が多めでほっとしています。
(評価項目については多少疑問を感じていますが)おかげさまでランキング入りしました。

f:id:coffee_ryo:20200309215807p:plain

左右上下に凄すぎる作品があって恐れ多い..

プレイいただいた皆様、ありがとうございました。
あとnaichiさん、最高のイベントをいつもありがとうございます。

「YOZORA MAKER」は、ボタン1つで完結するシンプルな避けゲームです。
作るに当たっては色々悩んだり考えたりすることが多かったです。
こちらの記事では、自身への備忘録的な意味合いで、どんなことを考えながら
本作を作っていったかをまとめたいと思います。

今回参加時の自身の心構え、方針

こんな感じのことをゆるふわっと考えながら参加したと思います。 結果としてシンプルなゲームにまとまってくれたのかなと。

  • 大量のゲームが投稿されるunityroomの環境下で、短時間でプレイ完結できて学習負荷が低いものを出す
  • お題はそこそこあっていれば良い こじつけでも良い
  • ランキング意識しながら作るのはしんどいので意識しない
  • 短期間で公開できるようにするため 使うアセットやスクリプト、シーンに配置されるゲームオブジェクト種類数はなるべく少なくする
  • 新規技術の習得として、Zenjectの一部機能を試す (ZenjectSceneLoader試しました)

一応社会人やってるので、なるべく短時間で遊べるゲームを作りたいなと考えていました。
それから、直近「Re Painter」というゲームを作っていたのですがシステム組むの激ムズなゲームでして...
次作るとしたらシンプルなものを作りたかったという気持ちもあります。

制作スケジュールについて

時間的には35h程度を使いました。
仕事で疲れていたので、平日は集中力あまりなかったと思います。

  • 0日目 : 6h 多分使うであろうアセット・ライブラリの設定、サウンドや画面遷移のスクリプティング GitLabでCIできる準備
  • 1日目 : 5h 企画 弾を撃って反動で移動する挙動の実装
  • 2日目 : 4h タイトル~結果シーンまでの最低限のゲームループ実装
  • 3日目 : 0h 仕事忙しくて確か作業してない
  • 4日目 : 2h 背景のドット絵を打つ
  • 5日目 : 3h BGMやSE付け、背景作り直し
  • 6日目 : 8h? タイトル画面のキャラのドット絵とか画面揺らしとか後めっちゃ追加してる
  • 7日目 : 6h? 結果画面のアニメーション周り、プレイヤーの挙動調整

GitLabのCIは無料枠?でやろうとしたのですが、WebGLのビルドが3時間以上かかってTimeoutとなってしまい、残念ながら実現できませんでした。

イデアだし

弾を撃って、反動でダッシュ出来て、体当たりで物体を壊せる的なものを考えていました。
iPadでなんか書いてたんですが、自分でも読めないほど汚い文字でもはや何を考えていたのか思い出せません。

f:id:coffee_ryo:20200309223720p:plain f:id:coffee_ryo:20200309223741p:plain f:id:coffee_ryo:20200309223753p:plain

バンパーとかなんだったっけ。

「学習負荷が低いもの」という観点で、マウス or キーボードの1ボタン操作にしたいなと考えてました。
で、自分の好みがキーボード操作だったのでキーボード操作に決定してます。
それから調整時間を削減するために、ステージ制で作らないことをイメージしていました。

仕事の都合で全部は時間的に間に合わなそうで、体当たりは仕様から消しました。

ゲームシステム

イデアが固まってきたところで、仕様を決めていきました。 初めから全て見えていた訳ではなくて、
実際にUnity上でゲームオブジェクトを動かしながら思いついたことを取り入れてきました。
ここら辺感覚でやってるので言語化が難しい...

  • プレイヤーキャラクター
    • 弾を撃てる
    • 弾を撃った逆方向に移動できる
    • 弾を撃てる方向は時間経過で回転する
    • 弾は連続して撃てず、クールタイムを設ける
    • プレイヤーが撃った弾がプレイヤーに当たるとゲームオーバー
  • スコア
    • 弾を撃った数だけスコアが高くなる (褒める)
    • 弾の近くで弾を打つと、グレイズショット判定として高スコア判定を付ける (すごく褒める)
    • 大量の弾がある過酷な環境でグレイズショット判定するとより高スコアになるような計算 (めちゃくちゃ褒める)

ゲームの設計としてはジレンマが発生するようなイメージを目標に考えました。
「これをやると高スコアが取れるかもしれないが、ゲームオーバーになる可能性も高い」
「これを続けていればしばらくは有利で安全だけど、いつか不利になってしまう」 など。

パラメータ調整

弾を撃つ方向の回転速度の調整だけ非常に難しくて、何度も調整していたと記憶してます。
遅すぎるとプレイヤーの位置移動の制御がうまい具合にできず運ゲーになってしまう、
早すぎると撃つ方向を定められず運ゲーになってしまう、みたいな悩みがありました。
実況していただいた方の様子をみると、ほんのわずかに遅くしても良かったかも知れない。

  • グレイズの距離は緩め
  • 弾を撃つ方向の回転速度は遅すぎず早すぎず。遊び手がプレイヤーオブジェクトを制御できるくらいの数値に。
  • 星を撃った後のクールタイム
  • 弾の速度は、意識すれば避けられる程度で、たまに運が悪くて高速弾が飛んでくるくらい

操作感とか演出など他

基本的には遊んでくれる人に対して、
画面上の各項目に意識をどれくらい持ってもらうかや視線を考えて作り込んでいきました。
これらも初めから設計できた訳ではなくて、その場その場で感じた違和感を潰して行きました。

タイトルの画面について

ゲーム起動直後はタイトル画面を「これはタイトル画面」と認識させたかったので
ゲームでは良くあるUI配置を取りました。
画面上部にタイトル名称のテキスト、下部に「PRESS SPACE」というテキスト、中央に動く白いキャラクターがいます。

f:id:coffee_ryo:20200309235926j:plain

タイトル画面では「PRESS SPACE」のテキストに注目させ、スペースキーを押して欲しかったので
「PRESS SPACE」のテキストに点滅アニメーションを加えました。

テキスト点滅なしの場合

f:id:coffee_ryo:20200310002618g:plain

テキスト点滅ありの場合

f:id:coffee_ryo:20200310002911g:plain

白いキャラクターの存在意義ですが、当初は背景の賑やかしというか、ゲームっぽい絵作りをしたかったので配置しました。
その後、「ゲーム始まった感」を出したくなったので
スペースキーを押したら白いキャラクターも一緒に反応してくれるようにしました。

振り返ってみると、「白いキャラクター」「スペースキー押すと動く」というのは
実際のゲームプレイの操作と連動していました。 次のゲームプレイの画面で中央にいる白いキャラクターを見て、「スペースキーで操作できそう」といった操作の予測がしやすかったのかなと思います。

f:id:coffee_ryo:20200310003908g:plain

ゲームの画面について

タイトル画面からはゲームプレイの画面に遷移させています。 ゲームプレイの画面では、5つの登場人物を出しています。

  • プレイヤーオブジェクト
  • 星を撃つ向きを示す矢印
  • スコアのテキスト
  • グレイズのテキスト

スペースキーを押すことでプレイヤーオブジェクトから星を撃つ向きを示す矢印方向へ星が放たれ
発射方向とは逆向きにプレイヤーオブジェクトが移動します。
開発当初、どの方向に星が発射されるか・その反動でどの方向にプレイヤーが移動するかが分かりにくかったので
プレイヤーオブジェクトの移動と矢印の回転を数フレーム停止させることで、対応しました。

星を撃つ前のプレイヤーオブジェクト・矢印の停止なし

f:id:coffee_ryo:20200311222553g:plain

星を撃つ前のプレイヤーオブジェクト・矢印の停止有り

f:id:coffee_ryo:20200311223838g:plain

プレイヤーオブジェクトが星に当たってしまった際の挙動ですが
星が動き続けていると当たったという事実に意識が行かないというか、
どの星に当たってしまったか理解できないかなと感じたので
全ての星の動きを停止させ、衝突した所を確認できるようにしました。
今思えば背景の横スクロールも止めた方が良かったかも知れません。

星に当たってしまった時の星の停止なし

f:id:coffee_ryo:20200311225012g:plain

星に当たってしまった時の星の停止有り

f:id:coffee_ryo:20200311225059g:plain

被弾時にはやっちまった感を出したかったので
画面揺らしと十字の白線エフェクトをつけました。エフェクトについてはだいぶ雑だったと反省してます。

スコア、グレイズのテキストについては、一応画面上には出していますが
おそらく遊び手的には避けるのに集中していて見る暇がないと思うので
極端に誇張せず表示するようにしました。

遊び手、やっぱり避けるのに集中しているはずなので
スコアの表示位置というか、表現方法についてはうまく背景とかその他使えないかとか思慮してたのですが
(スコアが高まるにつれて背景がゴージャスになるとか、BGMのテンポが早まるとか)
うまく纏まらず、やっつけで画面上部のテキスト表示となってしまいました。

スコアテキストは当初背景に溶け込んでしまい何か良くわからない存在だったので
背景とは別の存在ということだけ認識して欲しいがため画面遷移直後に一瞬アニメーションを入れてみました。

画面遷移直後の開始アニメーションなし

f:id:coffee_ryo:20200311225656g:plain

画面遷移直後の開始アニメーション有り

f:id:coffee_ryo:20200311225726g:plain

スコアのテキストはプレイヤーオブジェクトと被ってしまうことがあるのですが、
その際はスコアテキストを薄くしています。

近づいたら薄くするやつ

f:id:coffee_ryo:20200311230009g:plain

結果の画面について

スコア数だけだとうまくプレイできているのかどうかがランキングでしか確認できないのが
モヤっと感じていたので
作り手側からの評価として星表示を出すことにしました。
YOZORA MAKERではスコア1000が合格点で、ここを超えたら星の表示を虹色にするようにしました。

それから、結果の画面では星の評価とスコア数に注目させたいと考えていました。
星の評価とスコア数を一気に表示させると、認識感が下がる感じ...?なんと言えば良いんだろうか...を感じたので
1つずつ順番に表示させることにしました。

特にスコア数については最も注目して欲しいので強めのアニメーションを導入してみました。
このアニメーションは1weekベテランのRyosukeさん作「PIXBOX」のアニメーションを参考にしました。
(このアニメーションって何ていうんですかね先生?)

youtu.be

f:id:coffee_ryo:20200311230443g:plain

あとはこれ多分気付かれなくて失敗案件なのですが
スコアの数に応じて、背景のキラキラ感を増してます
(YOZORA MAKERというタイトル回収したかった...)

f:id:coffee_ryo:20200311230622j:plain

f:id:coffee_ryo:20200311230712j:plain

他細かいところ

  • 操作に対してきちんとSEをつける
  • ランキング画面はゲームに合わせて見た目に手を入れる
  • 画面遷移は初め白/黒のフェードアウトだったけど自分のゲームの場合安っぽく感じたので一手間加える

画面遷移アニメはcssにめっちゃ強い人のアニメーションが脳裏にあって、それを参考にしました。
yui540さんのアニメーションは観てて楽しい!

まとめ

仕事でだいぶ忙しかったので公開できないかも...と思いつつ睡眠時間削って作ってました。
だいぶ辛かった。 社会人で1weekやって公開した人はそれだけで5000兆点満点でしょう!
次回も予定が入ってないかぎり、参加して行きたいと思います。
よろしくお願いします!

unity1week お題「あつめる」に参加しました

概要

今回はsolid原則を意識したコードと、zenjectの使い方習得にフォーカスを当てて参加しました。
作ったゲームはこちら。

Golf | フリーゲーム投稿サイト unityroom

依存性逆転の法則を適用してみる

依存性逆転の法則を適用していないコード

プレイヤーオブジェクトを動かすコードを書いてみます。

f:id:coffee_ryo:20190707213138p:plain (ちょっとumlの線があってるか不安です..)

PlayerControllerというクラスを、処理の起点としました。
PlayerControllerはPlayerMoverクラスをメンバとして持ち、 PlayerMoverの処理を呼び出します。
PlayerControllerとPlayerMoverは別の名前空間に置きました。
(PlayerControllerはMono、PlayerMoverはPure)

処理の流れ・・・Mono→Pure
依存の向き・・・Mono→Pure

依存性逆転の法則を適用する

依存の向きをPure→Monoへ変更させてみます。

「抽象に依存させる」ために、interfaceを切って依存させてみました。

f:id:coffee_ryo:20190707213147p:plain

IPlayerMoverインターフェースを作りました。
PlayerControllerをIPlayerMoverインターフェースに依存させます。
IPlayerMoverインターフェースは、Monoに置きました。Pureに置いてしまうと、パッケージ間で見たときの依存の向きを逆転させられません。
IPlayerMoverの実装はPlayerMoverに任せました。

インターフェースに対してどの実装を使う?

今回はDIを使って解決しました。(zenject使った)

【Unity】ゲームパットの接続/切断時に通知を出してあげる

f:id:coffee_ryo:20190203020248g:plain

概要

#StrangeTelephone を開発されている方のツイートを見て、ゲーム側でゲームパット接続の通知を出してあげることに良さみを感じました。
接続した際に、これがゲームで使えるかどうかを教えてあげるのはプレイヤーに対して優しいですね。
Nintendo SwitchなんかでもJoyConくっつけたら画面に表示されますし。

これについて、Unityで実装をしてみました。

確認環境

Unity2018.2.20f1 Personal

Input.GetJoystickNamesを使う方法

docs.unity3d.com

スクリプト
using UnityEngine;
using System.Linq;

/// <summary>
/// ゲームパット接続/切断 サンプルコード
/// </summary>
public class OutputLog : MonoBehaviour {
    string[] CacheJoystickNames;

    void Start () {
        CacheJoystickNames = Input.GetJoystickNames();
    }
    
    void Update () {
        var joystickNames = Input.GetJoystickNames();

        // ※同一フレーム中に接続/切断した時については未検証
        // ※複数のゲームパットでは動作未検証
        if(CacheJoystickNames.Length > joystickNames.Length){
            Debug.Log("切断" + CacheJoystickNames.Except(joystickNames).ToList()[0]);
        }

        if(CacheJoystickNames.Length < joystickNames.Length){
            Debug.Log("接続" + joystickNames.Except(CacheJoystickNames).ToList()[0]);
        }

        CacheJoystickNames = joystickNames;
    }
}
結果

f:id:coffee_ryo:20190203013004p:plain

ゲームパット接続/切断時を取得することができました。

Rewiredのイベントを使う方法

assetstore.unity.com

様々なゲームパットの対応を用意にしてくれるAssetのRewiredを使用している場合、
Rewired側がイベントの用意をしてくれているので、公式ドキュメントにならえば良いです。

guavaman.com

Receiving Joystick connect and disconnect events

その他

あとはuGUIやDotweenなどで画面を作ってあげたり、通知時にSEを鳴らしたりすれば良さそうです。

f:id:coffee_ryo:20190203020248g:plain

【Unity】2Dゲーム 斜め移動の移動量が大きくなる件

概要

2Dのゼルダのような、見下ろし型でプレイヤーを四方八方動かせるようなゲームにおいて、
移動の実装方法によっては、斜め方向の移動速度が大きくなり手触り感に支障をきたす場合があります。

例えば、以下の処理の場合、inputX=1, inputY=1が入力されると
斜め方向の移動量は√2になります。
これは、三平方の定理を使えば算出できます。

using UnityEngine;

public class PlayerMover : MonoBehaviour {
    
    void Update () {

        var inputX = Input.GetAxisRaw("Horizontal");
        var inputY = Input.GetAxisRaw("Vertical");

        this.transform.position += new Vector3(inputX, inputY, 0);
    }
}

斜め移動の量を、水平や垂直方向と同じ様にするには、
以下のサイトの様に斜め移動時に補正値をかけることで対応できます。
斜めに移動させる | ゲームプログラミング入門~bituse~

角度が45,135,225,315度以外の時の実装方法が見当たらなかったので、
コードを書いてみました。

実装

using UnityEngine;
using System;

public class PlayerMover : MonoBehaviour {
    
    void Update () {

        var inputX = Input.GetAxisRaw("Horizontal");
        var inputY = Input.GetAxisRaw("Vertical");

        var moveVectorBeforeCorrection = new Vector2(inputX, inputY);

        //極座標の距離rを計算
        var r = Mathf.Sqrt(
            moveVectorBeforeCorrection.x * moveVectorBeforeCorrection.x +
            moveVectorBeforeCorrection.y * moveVectorBeforeCorrection.y
            );
        
        // 極座標のラジアンを計算
        var radian = Vector2.Angle(Vector2.right, moveVectorBeforeCorrection) * Mathf.Deg2Rad;

        // 斜め移動の補正
        // 斜め45度の時、補正を最大にする。水平や垂直の時は補正をかけない。
        //
        // ・角度が45,135,225,315の時→Cosが0になるので、rには0.7071fの補正値が乗算される
        // ・角度が0,90,180,270の時→Cosが1になるので、rには0.7071f+0.2928f = 1の補正値が乗算される(つまり補正されない)
        r *= (0.7071f + 0.2928f * Mathf.Abs(Mathf.Cos(2 * radian)));

        if(inputY >= 0){
            this.transform.position += new Vector3(r * Mathf.Cos(radian), r * Mathf.Sin(radian), 0);
        }else{
            this.transform.position += new Vector3(r * Mathf.Cos(radian), -r * Mathf.Sin(radian), 0);
        }
    }
}

角度が45,135,225,315度の時、移動量がもっとも大きくなってしまうので、
この際の補正値がもっとも大きくなる様に三角関数を組みました。

unityroomアドベントカレンダー2018 よもやま話

概要

渾身のバグに溢れる、プロトタイプを投稿しました。
よかったら遊んでください。PCブラウザでプレイできます。

RePainter | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

コンセプトについて

  • 自分の作ったオリジナル技で敵を倒していくロマン・かっこよさ
  • ゲームクリア=イラストうまいね!という評価をプレイヤーに与えるもの

を目指しています。

「アニメとかに憧れてイラストを描き始めた・・・」
「しかし描き始めると自分のイラストがクソすぎて挫折した・・・」
Twitterで神絵師がアップしている絵がめちゃくちゃ評価される・・・」
「誰にも評価されないからイラストやめる・・・」

このゲームは、
「そんな創作活動に挫折してしまった人をなんとか勇気付けて、もう一度復帰できたらいいな〜」
というところからスタートしてます。

将来的には対人戦であったり、村人に絵を描いてあげるアドベンチャー的要素とか謎解きとか
グラフィックとか音楽めちゃくちゃ気合い入れるとか
色々実験したいことがあるんですが
とりあえず1年間程度で作りきれる規模で進めています。
まだ完成していないけど次回作予定しています。

イラスト攻撃の実装方法について

描画については、今の所全てLineRendererに任せています。
気になる方がいらっしゃったら、こちらの記事をどうぞ。

coffee-ryo.hatenablog.com

coffee-ryo.hatenablog.com

今後について

リリースは2019年の夏か秋頃を予定しています。価格はわかりません。数百円かフリーゲームになるか。
本当はデジゲー博で出したかったのですが見事落選。。。!

「TokyoIndies」という月1の集まりで展示している場合があります。
この場で最新の進捗出しているので、ご興味持たれました方よかったら声かけていただけると嬉しいです。

twitter.com

【Unity備忘録】AudioMixer Normalize Effectをかけると音量が極端に小さくなる件

内容

unity 2018.2.13f1

  • 敵を爆発させるSE音を同時に10個再生
  • 音割れが激しいので、AudioMixerのNormalizeエフェクトを適用
  • 10個再生時の音割れは解消したが、10個再生後、単発で音を鳴らすとSEが小さすぎて聞こえない

対策

Normalizeエフェクトのパラメーターを調整

f:id:coffee_ryo:20181204141541p:plain

公式にリファレンスがあるが、理解ができなかったので色々試したところ
Fade in time プロパティの変更でうまくいった。

Fade in time プロパティを0にすると、音割れが発生する。
Maxにすると、音割れは発生しないがSEが小さすぎて聞こえなくなる現象が発生する。
→ このエフェクトは時間の経過により効き目が減衰する模様で、どれくらい経過したら減衰するかをこのパラメーターで調整できるっぽい

https://docs.unity3d.com/ja/current/Manual/class-AudioNormalizeEffect.html