忍者ブログ
まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

曲線のプログラムを色々作ってみたものをTwitterにアップしたので忘備録としてまとめておきます。
制作に当たって下記のサイトさまを参考にさせて頂きました。
http://www.ne.jp/asahi/music/marinkyo/matematiko/kurbo.html.ja
https://r-dimension.xsrv.jp/classes_j/sine_cosine/

















PR
Steamで実績を実装してみたので忘備録として書いておきます。
(書いてる筆者はド素人ですので色々間違っている可能性あります)
大前提としてSteamworks.NETをUnityにインストールしておいて下さい。
インストール方法は
https://ktstg.blog.shinobi.jp/Entry/1011/
で書いています。

当初は実績なんて無くても良いかなーと思っていたのですがゲームリリース後に実績目的で遊ぶ人もいるので実装した方が良いよとアドバス受け実装してみました。
ランキングと比べると実績の実装は簡単なのでやってみても良いと思います。
実装にあたり
Steam実績を実装する(Steamworks側設定編)
Steamの実績をUnityで実装する【Unity】【Steam】
コチラのサイトさんを参考にさせて頂きました。

まずはSteamworks管理画面のデータ&実績から実績を開きます。


実績にはクリアで達成などのオンオフのみで実装できる実績と、100万点とったら実績といった数値データが必要な実績があると思います。
これの数値データが必要な実績で何%まで達成みたいな表示を行いたい時は「データ&実績」のデータ画面でデータを先に作る必要がありますが今回は使わないので書きません。
(上記参考サイトさんで解説されています)
逆にオンオフのみで達成出来る実績の場合はデータを作る必要はなく実績の方だけ作れば良いです。

まずは実績アイコンを作ります。
実績アイコンは256x256のjpg画像が推奨されていますが実際に表示される時は凄く小さく表示されるので最少サイズの64x64くらいで表示されると思って作った方が良いです。
取得していない時のアイコンは取得している時のアイコンをモノクロにした物にします。

こんな風に作りましたが、実際の画面では全然文字が読めませんでした(笑)

実績画面で実績の項目を作っていきます。

新しい実績ボタンをクリックすると実績作成の項目が出てきます。
それぞれの意味は
API名:Unityでプログラムなどから指定する時の名前

進行状況:オンオフのみの実績なら「なし」最小値/最大値も0で良い。何%まで達成の表示を行うときはデータ画面で作成したAPI名を選択して最小値/最大値を入力する

ディスプレイ名:実績の名前。Steamクライアントなどで表示される実績名です。

説明:ディスプレイ名の下に表示させる実績の説明(「ステージ1をクリアした」みたいな感じ)

設定:データを修正できる人を設定
Client / ゲームアプリから更新(基本はコレを選択する)
GS / 自分でサーバーを立ててソコから更新する
Offical GS / Steamゲームサーバーから更新する

非表示?:獲得するまで表示しない(隠し実績)

達成アイコン:実績解除後のアイコン(カラー推奨)

未達成アイコン: 実績解除前のアイコン(白黒推奨)

以上をそれぞれ埋めていきます。アイコンは設定してもすぐに反映されません。途中で一度保存してから再度読み込むと上手くアップロード出来るようです。

@Unityへの実装
まずはスクリプトの最初にusing Steamworks;を記述します。Steamクライアントも起動させておかないとエラーになります。

実績解除の流れとしては
1.SteamManager.Initializedで初期化
2.SteamUserStats.RequestCurrentStats();でtrueが返ってくるか判別
3.SteamUserStats.SetAchievement("作成したAPI名");で実績解除
4.SteamUserStats.StoreStats();で解除を反映する(ポコンする)
と言った感じ

実際の実績解除はこんな風に書いています。


あと、すべての実績を解除した時の実績を作りたいなと思ったので
SteamUserStats.GetAchievement("作成したAPI名", out bool);で解除した実績を調べられる(trueだと実績を解除している)ので全ての実績を調べて解除するようにしました。


@実績のローカリゼーション
作った実績を色々な言語にローカリゼーションしたい時はSteamworks管理画面のデータ&実績から実績のローカリゼーションを選択します。


作成したい言語にレ点を入れて保存。


ALL Languagesを選択してローカリゼーションデータをダウンロードします。


ダウンロードしたデータをテキストエディタ等で開きます。

設定したい言語の所が空白になっているので埋めて上書き保存します。

保存したファイルを選択してアップロードすればOK


実績画面に戻ると言語が選択出来るようになっています。


これで上手く出来るはずなんですが自分の場合は日本語だったからか上手く反映出来なくて、結局実績を作成する画面のEditで一つづつ更新しないと駄目でした。
Steamでオンラインランキングを実装してみたので忘備録として書いておきます。


オンラインランキングを実装する流れとしては
①Steamworks管理画面にランキングを作成
②Steamworks.NETをUnityにインストール
③UnityにてオンラインランキングをC#で実装
といった感じになります。

実装にあたり
Steamのランキング(リーダーボード)をUnityで実装する【Unity】【Steam】
Unity製ゲームで、Steamのランキング実装をするには
コチラのサイトさんを参考にさせて頂きました。

①Steamworks管理画面にランキングを作成

Steamworks管理画面のテクニカルツールにあるSteamworks設定編集→データ&実績→ランキングを選択します。
ランキングを追加で任意の名前を付けて作成します。

パラメータの内容はSteamworksの説明から抜粋
*********************************************************************
名前-ここには、内部開発用に意味のある名前を設定します。
コミュニティ名-ランキングをコミュニティハブに表示する場合は、ここに一般公開用の名前を設定します。 名前が入力されていない場合は、ランキングは表示されません。
並べ替え方法-ランキングの並べ替え順序を設定します。 順位が基準のランキングでは昇順を使用し、 ハイスコアが基準の場合は、降順を使用してください。
表示タイプ-ランキングで表示するデータのタイプを決定します。 数値、秒またはミリ秒から選択します。
書き込み-これが「信頼済み」に設定されている場合、クライアントによってランキングスコアを設定することはできず、SetLeaderboardScore WebAPIによってのみ設定できます。 デフォルトでは設定されていません。
読み取り-これが「フレンド」に設定されている場合、ゲームはユーザーのフレンドのランキングスコアのみを読み取ることができます。すべてのスコアはWebAPIによって常に読み取り可能です。 デフォルトでは設定されていません。
*********************************************************************
書き込みと読み込みは特別な事をしない限りは設定する必要なさそうです。
並べ替え方法1位から順番に表示したい場合は降順にします。

実施したいランキングの数だけ作成します。
(例えばイージーとノーマルとハードに分けたかったら3個作る)
ランキングを作成したらココでの設定は終了です。


②Steamworks.NETをUnityにインストール
アセットストアにもあるみたいですが公式の?Githubからダウンロードするのが良さげ
Releases · rlabrecque/Steamworks.NET
ちょっと下にあるSteamworks.NET_20.1.0.unitypackageをダウンロードしてAssets→Import Package→Custom Packageでインストールします。

インストールしたらゲームプロジェクトフォルダの一番上の階層にsteam_appid.txtがあると思うので、それを開くのですがUnityからは見えないのでWindowsからテキストエディタで開きます。
初期は480?かと思いますので、自分のゲームのID(Steamworksに表示されているゲームタイトルの横にある数字)を入力して保存します。
保存したらココでの設定は終了です。


③UnityにてオンラインランキングをC#で実装
※オンラインランキングを使用するときはUnityと同時にSteamも立ち上げておかないとエラーが出るので注意が必要です。

ランキングを使用するスクリプトには一番初めに
using Steamworks;
を記述する必要があります。

ランキング送受信する時のC#スクリプトはこんな感じ

リーダーボードの取得


ランキングの取得


スコアの送信


流れとしてはリーダーボードを取得してランキング取得して表示もしくは送信を行うだけなので、ランキングの取得とスコアの送信が出来れば何とかなる感じです。
取得した順位はテキストなどに入れて表示すればランキング表が出来ます。

ただ、あまり頻繁に取得すると表示制限?が掛かるみたいで取得出来なくなるので、あまり更新頻度は上げない方が良さそうです。
沙羅曼蛇やグラディウスシリーズに出てくるテトランっぽい敵が作ってみたいと思い実装してみました。

アルゴリズムを検索してみてもあまり出てこなかったので忘備録として書いておきます。
考え方としては
1本目、腕の中心から決めた角度の腕の長さの円を描ける座標計算をします。その計算した座標を2本目の中心座標とします。

2本目、1本目で計算した中心座標から決めた角度の腕の長さの円を描ける座標計算をします。その計算した座標を3本目の中心座標とします。

3本目、2本目で計算した中心座標から決めた角度の腕の長さの円を描ける座標計算をします。その計算した座標を4本目の中心座標とします。
以下腕の長さだけ繰り返し。
要は普通に多関節の腕を作る感じです。
このまま回転させてもファンタジーゾーンのウインクロンみたいな感じで腕は真っすぐのままなのですが、ここで各腕に回転させる角度を一定の間隔で少しづつずらしてプラスするとテトランのようにウネウネする感じで回転してくれます。


ソースだとこんな感じ。
中心の腕が親、続く腕が子というイメージです。
**************************************************************
        Vector3 pos1 = transform.position;
//1本目の計算
        pos[0] = transform.GetChild(0).position;
        pos[0].x = pos1.x;//腕の中心座標
        pos[0].y = pos1.y;//腕の中心座標
        pos[0].z = -0.1f;
        rad[0] += 0.05f;
        ds[0] = 0.4f;
        ux[0] = Mathf.Cos(rad[0]) * ds[0] + pos[0].x;//次の腕の中心座標
        uy[0] = Mathf.Sin(rad[0]) * ds[0] + pos[0].y;//次の腕の中心座標
        transform.GetChild(0).rotation = Quaternion.Euler(0, 0, (rad[0] * Mathf.Rad2Deg));//回転表示
        transform.GetChild(0).position = pos[0];
//2本目の計算
        pos[1] = transform.GetChild(1).position;
        pos[1].x = ux[0];//腕の中心座標
        pos[1].y = uy[0];//腕の中心座標
        pos[1].z = -0.2f;
        rad[1] += 0.05f;
        ds[1] = 0.4f;
        ux[1] = Mathf.Cos(rad[1]) * ds[1] + pos[1].x;
        uy[1] = Mathf.Sin(rad[1]) * ds[1] + pos[1].y;
        transform.GetChild(1).rotation = Quaternion.Euler(0, 0, (rad[1] * Mathf.Rad2Deg));//回転表示
        transform.GetChild(1).position = pos[1];
//3本目の計算
        pos[2] = transform.GetChild(2).position;
        pos[2].x = ux[1];//腕の中心座標
        pos[2].y = uy[1];//腕の中心座標
        pos[2].z = -0.3f;
        rad[2] += 0.05f;
        ds[2] = 0.4f;
        ux[2] = Mathf.Cos(rad[2]) * ds[2] + pos[2].x;//次の腕の中心座標
        uy[2] = Mathf.Sin(rad[2]) * ds[2] + pos[2].y;//次の腕の中心座標
        transform.GetChild(2).rotation = Quaternion.Euler(0, 0, (rad[2] * Mathf.Rad2Deg));//回転表示
        transform.GetChild(2).position = pos[2];
以下腕の数だけ繰り返し・・・

キーボードQボタンを押すと腕がウネウネする。
        if (Input.GetKey(KeyCode.Q))
        {
            rad[0] += 0.06f;
            rad[1] += 0.04f;
            rad[2] += 0.02f;
            rad[3] += 0.0f;
        }
**************************************************************
初期設定時にradの値を0~6.28の間で設定すれば好きな向きに腕を伸ばす事が出来ます。

上記を纏めるとこんな感じ。
**************************************************************
        float rad_plus = 0.05f
        Vector3 pos1 = transform.position;
        for (int i = 0; i < emax; i++)
        {
            pos[i] = transform.GetChild(0).position;
            if (i == 0)//腕の中心
            {
                pos[i].x = pos1.x;//腕の中心座標
                pos[i].y = pos1.y;//腕の中心座標
            }
            if (i != 0)//中心以外~先端まで
            {
                pos[i].x = ux[i - 1];
                pos[i].y = uy[i - 1];
            }
            pos[i].z = -i;
            
            rad[i] += rad_plus;
            ds[i] = 0.4f;
            ux[i] = Mathf.Cos(rad[i]) * ds[i] + pos[i].x;//次の腕のx座標
            uy[i] = Mathf.Sin(rad[i]) * ds[i] + pos[i].y;//次の腕のy座標
            transform.GetChild(i).rotation = Quaternion.Euler(0, 0, (rad[i] * Mathf.Rad2Deg));
            transform.GetChild(i).position = pos[i];
        }
        if (Input.GetKey(KeyCode.Q))
        {
            for (int i = 0; i < emax; i++)
            {
                float j;
                j = i;
                rad[i] += rad_plus - (j / 100);//腕を回転させる
            }
        }
**************************************************************
腕の画像は下記画像のような中心から外側に向かうような画像にしておかないと上手く腕が繋がりません。
Unityのスプライト機能を使ってラスタースクロールを実装してみました。
考え方としては画像を1ドットづつのスプライトに分割してサインカーブに合わせて動かす感じ。

まずはラスタースクロールさせたい画像を用意します。
今回は768x128ドットの画像を使いました。

画像を選択したらInspectorのSprite ModeをMultipleに変更してからSprite Editorをクリックします。
Sprite Editorが開いたらSliceを押してTypeをGrid By Cell Sizeに変更しXを768、Yを1にに変更してSliceボタンを押すと768x1ドットで画像が分割されます。

追加した画像の再生マークを押すと
round01_0
round01_1
round01_2
round01_3
round01_4
round01_5...
みたいな感じで画像が追加されていると思います。


Hierarchyタブで右クリックから空のゲームオブジェクトを作成します。Round01と言う名前にしました。
追加された画像を全て選択して、作成したゲームオブジェクトにドラッグします。この時そのままドラッグするとアニメ作成画面になるのでAltを押しながら追加すると子として登録されます。


これでRound01という親オブジェクトに1ドット毎に128個の分割された子オブジェクトが追加されました。これを親オブジェクトから操作して行きます。
まずC#スクリプトを作成してRound01のアタッチします。

Round01のスクリプトはこんな感じ
*******************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Round01 : MonoBehaviour
{
    private Vector2[] pos = new Vector2[128];
    private float[] zure = new float[128];
    private float speed  = 0f;
    private float sindou = 0.10f;
    private float haba   = 0.8f;
    private float sp = 0.1f;
    void Start()
    {
        
    }
    void Update()
    {
        for (int i = 0; i <= 127; i++)
        {
            pos[i] = transform.GetChild(i).position;
            pos[i].x = zure[i];
            pos[i].y = (i * -0.01f);
            transform.GetChild(i).position = pos[i];
            zure[i] = haba * Mathf.Sin(sindou * i + speed);
        }
        speed += sp;//スピード 
    }
}
*******************************************
親オブジェクトから子オブジェクトを操作する時はGetChild()を使うと出来るようなのでGetChild(i)を使って親オブジェクトから子オブジェクトを移動させています。

zure[i] = haba * Mathf.Sin(sindou * i + speed);でサインカーブの計算をしてラスターっぽく動かしています。
sp,sindou,habaの数値を色々変更すると動きが変わります。
Twitter
カレンダー
03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
最新コメント
[04/20 kt.]
[04/19 うぇむ]
[11/24 kt.]
[11/21 NONAME]
[11/24 kt.]
プロフィール
HN:
kt.
性別:
男性
自己紹介:
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
忍者ブログ [PR]