個人アプリ開発で月収5万円目指す

アプリ個人開発 まるブログ

アプリ開発覚え書き

厳選!私が実際に役に立ったUnity,iOS おすすめ動画講座【随時追加】

f:id:marumaro7:20200624224539p:plain

はじめに

みなさんプログラミングの勉強どうやって進めていますか??

私のおすすめは断然これ!


Udemy です。

友人から教えてもらったのですが、一流講師の講座が時間を選ばず受けられます。

セール時には1000円台から受講できるので本を買うより安くコスパ最強です。

エンジニアにマンツーマンで教えてもらおうと思うと、
1時間2500円が相場なので、それを考えると定価で購入してもお得だと思ってます。
とはいうものの、副業するならコストはできるだけ抑えたいので購入はセール時が狙い目です。

質問し放題に加えて、30日間返金保障なので安心して購入できます。

Udemyというか動画教材の欠点としては、
あとで見返すときに「確認したいところがわからない」
ということがあるので、Qiitaやブログなどでメモを残しておくと良いかもしれません。

Udemyでは細かくセクションごとに分かれ探しやすくなっていますが、
それでも不思議、私は探す笑

私が実際に役に立ったUdemyのおすすめ講座を紹介します。

Unity教材

Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】

Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】

【感想】
Unity教材で迷ったらこれで間違いなし! marumaro7.hatenablog.com ↑こちらの記事でも紹介しましたが、Unityの基礎だけでなく、
超つまづきやすいAndroidiOSのリリース手順まで解説しています。
なんですかこれ、、、神ですか?

Unity3D入門の決定版!RPG開発の基本をUnityインストラクターと共に進めるハンズオンコース【スタジオしまづ】

Unity3D入門の決定版!RPG開発の基本をUnityインストラクターと共に進めるハンズオンコース【スタジオしまづ】

【感想】
Unityで3Dをやりたいならこれ!
基礎から学ぶので初心者でも安心♪

Unityゲーム開発入門:Unityインストラクターが教えるマリオ風2Dアクションゲームを作成する方法【スタジオしまづ】

Unityゲーム開発入門:Unityインストラクターが教えるマリオ風2Dアクションゲームを作成する方法【スタジオしまづ】

【感想】
自分でマリオみたいなゲームが作れる幸せ!
マリオメーカーよりも自由に!

[初心者向け] Blender 2.8でアニメーションを作成して Unity で動かすまでの30分講座

[初心者向け] Blender 2.8でアニメーションを作成して Unity で動かすまでの30分講座

【感想】
3Dモデルに命を吹き込む!
Unity×Blenderで制作の幅が広がります。
Blenderのインストールは事前に必要です。

Unity2Dパズルゲーム開発入門:Admob広告実装と高速にスマホゲームを量産する実践テクニック講座【スタジオしまづ】

Unity2Dパズルゲーム開発入門:Admob広告実装と高速にスマホゲームを量産する実践テクニック講座【スタジオしまづ】

【感想】
とにかく量を作る!
なるほど量産テクニックです。

Unityインストラクターが教えるシャドウバースのような本格2Dカードゲーム開発コース【スタジオしまづ】

Unityインストラクターが教えるシャドウバースのような本格2Dカードゲーム開発コース【スタジオしまづ】

【感想】
Unityのチュートリアルをなにかしらやったことある人向けです。
カードゲームの基礎はここに。

iOS教材

【iOS13対応】未経験者がiPhoneアプリ開発者になるための全て iOS Boot Camp

【iOS13対応】未経験者がiPhoneアプリ開発者になるための全て iOS Boot Camp

【感想】
ベストセラーだけあって初心者でもわかりやすい
Firebaseとの連携も解説されているのが個人的に嬉しいポイントです。

おわりに

Unity教材全部スタジオしまづやないか!と思いました?
だってわかりやすいんだもの、、、

【Udemy】初心者OK!Unityアプリ開発収益化 講座まとめ(無料有り)

はじめに

こんにちは、ゲーム開発プラットフォーム「Unity」を使って
個人アプリ開発をしている まる です!
まる|未経験でもわかるUnity C#入門本を執筆中 現在131ページ (@maruappdev) / Twitter

最強のインプットはアウトプットということで、
勉強も兼ねてUdemyにてアプリ開発収益化に関する講座をリリースしております。

※現在、講座総登録者数は1850名様を突破しました!
 ご登録していただいた方、本当にありがとうございます!


講座本数が増えてきましたので、
講座情報や割引クーポン情報などをこの記事にまとめることにします。


講座一覧

現在4つの講座をリリースしております。

【Unity】Android & iOS対応 超簡単!ボタンクリックゲームを作成する方法

講座時間:52分

Unityで簡単なスマホ向けゲームを制作する講座です。
アプリ作成の雰囲気をつかんでいただくことができます。
無料です!

www.udemy.com


Unityのインストールから学びたいという方は、
Unity公式さんが出されているこちらの無料講座がオススメです。
Unityの無料チュートリアル - ユニティちゃんが教える!初心者向けUnity講座 | Udemy

【Unityアプリ収益化入門】「急上昇アプリランキング1位」を獲得した個人開発者が教えるユニティスマホアプリ開発コース

講座時間:4時間30分

Unityで簡単なスマホ向けゲームを制作し、
広告付きの GooglePLay と App Store にリリースする講座です。
アプリリリースだけでなく、広告を付けて収益化することもできるようになります。
また、収益をアップさせるポイントも併せて解説しています。

www.udemy.com


収益アップのポイントを自分のアプリで実践した結果がこちらです。

marumaro7.hatenablog.com

【Unityアプリ収益化入門2】コピペで簡単課金実装!!アプリ内課金を最短距離で実装する ユニティスマホアプリ開発コース

講座時間:3時間

アプリリリースができるようになったら、アプリ内課金を付けてみましょう!
手順自体は決まっているのでコピペで実装するだけです。
私が実装した時は、ネットに情報が無くかなり苦労しましたが、もう大丈夫です。

実際にアプリ内課金商品を販売してみると、
こんな価格でだれも買わないだろうという価格で設定しても
意外と購入していただけますので世界の広さを感じます。

www.udemy.com

【Unityアプリ収益化入門3】コピペで簡単プッシュ通知機能実装!収益向上を目指すユニティスマホアプリ開発コース

講座時間:4時間

アプリリリースができるようになったら、プッシュ通知を実装するのも良いです。
こちらも基本的なところの手順自体は決まっているためコピペで実装するだけです。
私が実装した時は、ブログ記事などにこれといった情報が無く、なかなかに苦労しました。

こちらの内容は、一部ブログ記事でもまとめておりますので、
実際に実装してみて、もっと先が知りたいのであればご利用ください。

marumaro7.hatenablog.com

収益化入門3とありますが、収益化入門2のアプリ内課金は実装していなくても
プッシュ通知機能は実装可能です。

www.udemy.com

おわりに

私の今後の動向としては、UnityでのC#プログラミング解説本を作ろうとしています。

開発速度を加速させるには、プログラミングの知識を上げる必要があると感じており、
学習を進めるうえで、アウトプットを通してインプットをすることにしました。

まとめた内容は共有したいと考えていますので、
内容にご興味あれば、
まる|未経験でもわかるUnity C#入門本を執筆中 現在131ページ (@maruappdev) / Twitter
をフォローお願いします。

最後まで読んでいただきありがとうございました。 ではでは〜。

【Unity】Google Mobile Ads v6.1.2→v7.0.2 に上げた際のエラー対応

環境

Unityバージョン2021.3.3f1

2022.8.6追記
Unityバージョン2020.3.18f1では今回の対応が自動で行われていました。

はじめに

Google Mobile Ads v6.1.2→v7.0.2
とした時にはまったのでメモ

いろいろ過程でいじくりましたので参考程度に。


v6.1.2のパッケージでインポートしたファイルは全て削除し、
そこからv7.0.2のパッケージを入れています。

v6.1.2のファイルを削除するとアプリIDの設定がリセットされるため、
v7.0.2を取り込み後、アプリIDを入力してください。

また、パッケージを入れたのみで、広告のコードは書いていない段階のお話になります。

エラー内容

ビルド時、 R8が〜 JAVAが〜 というエラーが出てきますが関係ありませんでした。

対策

過程でいろいろいじくりまわしましたが、
対策は、競合ファイルを削除する。
これだけでした。
(再現の検証はしていませんので参考程度にして下さい。)

プロジェクトのところで「core」や「android」で検索すると、
バージョン違いの同名ファイルがあるので古いバージョンのファイルを削除して下さい。

画像内ので印をつけたファイルを削除しました。

おわりに

結果、単純なことでしたが、
検証などで朝活3日分潰しましたので、
どなたかの時短になれば報われます。

他の記事

marumaro7.hatenablog.com

【Unity】【Xcode】 Validate App エラー対応 Invalid Bundle. The bundle at '◯◯.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.

環境

MacOS:Monterey 12.4
Unity:2021.3.3f1
Xcode:13.4.1
Google Mobile Ads:v7.0.2
PlayFabSDK:2.138.220621

はじめに

XcodeでVaridate Appを行ったところ、

下記のエラーが発生しました。

Invalid Bundle. The bundle at '◯◯.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.


日本語訳

バンドルが無効です。 '◯◯.app/Frameworks/UnityFramework.framework'のバンドルには、許可されていないファイル'Frameworks'が含まれています。

※◯◯にはアプリ名が入ります。

対策

対策はこちらの記事の通りです。

zenn.dev

1.Editorフォルダ下にスクリプトを新規作成

「XcodeSwiftVersionPostProcess」という名前でスクリプトを新規作成
 作成したスクリプトをEditorフォルダ下に移動します。

2.スクリプト編集

スクリプト内容はこちらの内容にします。

using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
 
namespace Editor
{
    public static class XcodeSwiftVersionPostProcess
    {
        [PostProcessBuild(999)]
        public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
        {
            if (buildTarget == BuildTarget.iOS)
            {
                ModifyFrameworks(path);
            }
        }
 
        private static void ModifyFrameworks(string path)
        {
            string projPath = PBXProject.GetPBXProjectPath(path);
           
            var project = new PBXProject();
            project.ReadFromFile(projPath);
 
            string mainTargetGuid = project.GetUnityMainTargetGuid();
           
            foreach (var targetGuid in new[] { mainTargetGuid, project.GetUnityFrameworkTargetGuid() })
            {
                project.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO");
            }
           
            project.SetBuildProperty(mainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
 
            project.WriteToFile(projPath);
        }
    }
}
 

スクリプト内容

先ほどのスクリプトは以下を自動で設定する内容となります。

Unity-iPhoneターゲットの場合、
「Always EmbedSwiftStandartLibraries」を"Yes"に設定する必要があります。

それ以外のターゲットの場合、
「Always EmbedSwiftStandartLibraries」を"No"に設定する必要があります。

参考

forum.unity.com

forum.unity.com

github.com

【Unity】iOS ビルドエラー BuildFailedException: Burst compiler (1.6.5) failed running stdout: Failed to determine xcode installation path - "xcode-select -p" is XCode installed? xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),

バージョン

MacOS:Monterey 12.4
Unity:2021.3.3f1
Xcode:13.4.1
Google Mobile Ads:v7.0.2


はじめに

Google Mobile Adsを入れて初期設定しただけのプロジェクトで
Unityのビルドボタンを押したところ
下記のエラーが発生

BuildFailedException: Burst compiler (1.6.5) failed running

stdout:
Failed to determine xcode installation path - "xcode-select -p" is XCode installed? xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

stderr:



日本語訳

BuildFailedException:バーストコンパイラ(1.6.5)の実行に失敗しました
stdout:
xcodeのインストールパスを特定できませんでした-「xcode-select-p」はXCodeがインストールされていますか? xcrun:エラー:無効なアクティブな開発者パス(/ Library / Developer / CommandLineTools)、次の場所にxcrunがありません:/ Library / Developer / CommandLineTools / usr / bin / xcrun

stderr:

対策

Xcodeのパスが取得できていないとのことなので設定します。

ターミナルを開きます。




Xcode最新版に切り替えるため、ターミナルに以下を入力し、エンターを押します。
(ターミナルでの操作となりますので自己責任にてお願いします。)

sudo xcode-select --switch /Applications/Xcode.app




入力後、パソコンのパスワードの入力されるので入力します。
(パスワードを入力してもターミナル上には表示されません。)

パスワード入力後、特に変化はありませんが、設定完了です。

これでビルド再トライをしたところ、
Unityでのビルドが成功しました。

おわりに

ビルドは通りましたが、CocoaPodsアップデートしろのエラーが出たので別で書きます。

iOS framework addition failed due to a CocoaPods installation failure. This will will likely result in an non-functional Xcode project.

After the failure, "pod repo update" was executed and succeeded. "pod install" was then attempted again, and still failed. This may be due to a broken CocoaPods installation. See: https://guides.cocoapods.org/using/troubleshooting.html for potential solutions.

pod install output:

Analyzing dependencies
Adding spec repo trunk with CDN https://cdn.cocoapods.org/

CocoaPods 1.11.3 is available.
To update use: gem install cocoapods

For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.11.3

[!] GoogleAppMeasurement requires CocoaPods version >= 1.10.2, which is not satisfied by your current version, 1.10.1.

追記
今回もこの内容でアップデートしてエラー無くなりました。

marumaro7.hatenablog.com

参考

answers.unity.com

com4tis.net

【Unity】AdMobのUnityAdsメディエーション設定 勝手にUnityAdsが停止していた話

はじめに

メディエーション設定していたUnityAdsが停止されたため経緯と対応をメモ

経緯

こちらのアプリをリリースした際、リワード広告のメディエーション設定をしており、
UnityAdsの広告が問題無く表示されている状況でした。

maruapps.com

メディエーションの設定方法はこちら

marumaro7.hatenablog.com

開発が進み、バナー広告を実装して
UnityAdsメディエーションを設定し、AdMobのメディエーション管理画面をみると、、、

「データが取得できません」と表示されるようになっていました。
(これに気付いたのはアップデートバージョンをリリースして一週間後とかなので、
表示されなくなったトリガーがわからない状態です。)

原因はUnityAdsダッシュボード

放置したり再設定したり、うまくいっているアプリの設定と見比べたり・・・
いろいろとやって見つけたのがこれ

Unityダッシュボードで広告が無効になっている!!!
そして有効にできない・・・

対応

Unityフォーラムを見る限り、
Unityに問い合わせるしかなさそうだったので問い合わせしました。

Unityダッシュボード
→Help and Support
→File a ticket
→Monetization
→Ads Fraud
で問い合わせました。
(Monetizeで問い合わせするとAds Fraudで問い合わせてねっって連絡きます(経験済み))

結果

下記返答があり、ここから2,3日で無事広告が有効になりました。
(OFFになっていた広告設定はUnity側で勝手ONに設定してくれてました。)

Hello,

Thank you for your patience.

We have taken the time to re-evaluate this case, and the fraud team has decided to reconcile this account. Please allow up to 24 hours for the Fraud team to process the reconciliation request. ,

Please make sure to read and follow our Monetization Terms of Service agreement to not generate any revenue through Invalid Activity, such as: - Triggering abnormal and continuous ad engagement patterns - Testing with live ads and triggering clicks and installs - Promoting incentivized clicks to end users - Promoting real world rewards including cash, gift cards, cryptocurrencies, etc. - Copyright infringement - VPN apps,

If there are signs of similar activity detected in the future, your account will be locked permanently.,

Revenue generated from fraudulent traffic will be reset, but you are welcome to use Unity Ads again.,

Regards,,

Unity Fraud Team

おわりに

エラー原因がUnityAdsダッシュボードの広告有効無効設定にあると
気付くまで2ヶ月くらいかかってしまいました。
(ずっと違う設定いじってました><)

この記事で早期改善に役立てていただければ幸いです。

他の記事

marumaro7.hatenablog.com

【iOS】 Certificate証明書の更新 (現在ご利用のiOS Distribution証明書の有効期限まであと30日になりました。)

はじめに

iOS Distribution Certificate証明書の更新方法になります。

証明書の有効期限は1年なので1年毎に行う必要があります。

やることは簡単なのですが、いつも忘れるのでメモ

1.証明書の作成

まずは、こちらの記事内容をそのまま行います。

marumaro7.hatenablog.com

こちらはiOSリリース手順ということで1〜5のシリーズになっています。
今回はシリーズ1の「証明書の作成 Certificate」の項目だけを行います。

初回時と違うこと

前回作ったCertificateSigningRequestファイルがあると思いますので、
上書きされないよう名前を変えて保存してやる必要があります。(上書きしても問題無いかも)
私は画像のように数字を入れて保存しています。

注意点

「1.証明書の作成」にて
CertificateSigningRequest.certSigningRequest ファイルを新しく作成したら
古い方のファイルは必ずゴミ箱へ移動してください。
Xcodeでストアへアップロードする過程で権限エラー?が発生します。

2.Profilesの更新

デベロッパーサイトのProfilesにアクセス
https://developer.apple.com/account/resources/profiles/list

更新したいProfileを選択します。
(今回は赤枠のものを更新します。)


このような画面になるので「Edit」を押す。


Certificateを選択する画面になるので、
今回作ったCertificateを選択する(有効期限が一番長いもの)
→Save


Profileが作成されるのでDownloadを押す。


ダウンロードしたファイルをダブルクリックしてXcodeに適用する。
(ダブルクリックすれば勝手にXcodeが起動します。)


他にもアプリを出しているのであれば、
そのProfileを選択して上記の「Edit〜Xcodeに適用」を繰り返してください。

おわりに

スムーズに更新できましたら幸いです。

他の記事

marumaro7.hatenablog.com

【Unity】LitJsonでジャグ配列を文字列へ変換する

はじめに

LitJsonでジャグ配列を使う メモ

・Unity標準のJsonUtilityではジャグ配列を文字列に変換できない
・LitJsonを使用すれば使えるようになる
ということでLitJsonを使用していきます。
使用するにはまず、前準備が必要です。

前準備

Githubからファイルをダウンロードします。
github.com

Code→DownLoad ZIP
f:id:marumaro7:20220319042353p:plain

ダウンロードしたファイルの「src」というフォルダを
UnityのAssetsに入れます。
f:id:marumaro7:20220319043524p:plain

これで準備完了です。

使い方1

いきなりジャグ配列を使うとわかりにくいので、
int型とstring型の変数を使ったサンプルを載せます。
やっていることは下記です。
・セーブされた文字列を元のクラスの形に戻す(セーブデータがあれば)
・変数を変更
・文字列への変換&セーブ

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using LitJson;

public class LitJsonTest : MonoBehaviour
{
    string json;

    private void Start()
    {
        Player player = new Player();

        //セーブキーを持っていたら処理
        if (PlayerPrefs.HasKey("SaveKey"))
        {
            json = PlayerPrefs.GetString("SaveKey");//セーブデータから文字列を読み込み

            print("json = " + json);

            player = JsonMapper.ToObject<Player>(json);//読み込んだ文字列からPlayerクラスの値を設定

            print("HP = " + player.hp);
            print("Name = " + player.name);
            print("SkillName = " + player.skillName);
        }


        //データを変更
        player.hp += 10;
        player.name = "勇者";
        player.skillName = "abc";

        json = JsonMapper.ToJson(player);//playerクラスを文字列に変換
        PlayerPrefs.SetString("SaveKey", json);//文字列をセーブ

        print("json = " + json);
    }
        
}

public class Player
{
    public int hp;
    public string name;
    public string skillName;
}

結果

初回実行時(セーブデータがないので変数の変更 と 保存のみ) f:id:marumaro7:20220319053836p:plain

2回目実行時 f:id:marumaro7:20220319053949p:plain

ポイント

名称の書き方が不適切かもしれませんが、重要なのはこの2つです。

文字列への変換

JsonMapper.ToJson(変換したいクラス);

文字列からクラスへの変換

JsonMapper.ToObject<クラス名>(保存していた文字列);

ジャグ配列を使用

本題のジャグ配列を文字列へ変換するサンプルです。
先ほどのサンプルで書いていたPlayerクラスの変数はジャグ配列一つにしました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using LitJson;

public class LitJsonTest : MonoBehaviour
{
    string json;

    private void Start()
    {
        Player player = new Player();

        player.skillId = new int[3][];//最初の要素数の指定

        player.skillId[0] = new int[2];
        player.skillId[1] = new int[3];
        player.skillId[2] = new int[4];


        //セーブキーを持っていたら処理
        if (PlayerPrefs.HasKey("SaveKey"))
        {
            json = PlayerPrefs.GetString("SaveKey");//セーブデータから文字列を読み込み

            print("セーブデータから読み込んだjson = " + json);

            player = JsonMapper.ToObject<Player>(json);//読み込んだ文字列からPlayerクラスの値を設定
                        
            for (int i = 0; i < player.skillId.Length; i++)
            {
                for (int n = 0; n < player.skillId[i].Length; n++)
                {
                    print("復元後SkillId" + "[" + i + "][" + n + "] = " + player.skillId[i][n]);
                }
            }
        }


        //データを設定
        for (int i = 0; i < player.skillId.Length; i++)
        {
            for (int n = 0; n < player.skillId[i].Length; n++)
            {
                player.skillId[i][n] = i + n;
            }
        }

        json = JsonMapper.ToJson(player);//playerクラスを文字列に変換
        PlayerPrefs.SetString("SaveKey", json);//文字列をセーブ

        print("セーブしたjson = " + json);
    }
        
}

public class Player
{
    public int[][] skillId;
}


結果

初回実行時 f:id:marumaro7:20220319060653p:plain

2回目実行時 f:id:marumaro7:20220319061233p:plain

ジャグ配列の文字列化と復元ができることが確認できました。

おわりに

Unity標準のJsonUtilityの方が処理速度が早いらしいので
JsonUtilityで処理できないときだけLitJsonを使うと良さそうです。

参考

blog.lab7.biz

nekosuko.jp