FC2ブログ
    04 «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.31.» 06

    ハルシオンシステムの気ままBlog

    株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

     

    【ハルシオンブログ】UnityプロジェクトにFirebaseとAdmobを入れたらビルドが通らない!だれか助けて!後半! 

    おはようございます!
    5月も最終日になりました。
    緊急事態宣言も伸びて、一応6/20までとのことだけど、いつまでなのかもわからなくなりましたね。
    今年いっぱい緊急事態のままかもしれません。
    早く飲みに行きたいですな。

    さてさて、こんな感じでIOSのビルドにはまってる日々におさらばです。
    http://halcyonsystemblog.jp/blog-entry-796.html

    続報です。

    こちらの記事にも書いてますが、環境はこちら。

    <環境>
    MacBook Air
    ●M1ではない
    ●Big Sur 11.1
    ●Unity 2020.1.0f1
    ●Xcode12.2
    iPhoneXR
    ●iOS 14.0?(覚えてない)

    上記の環境でビルドが始まりました。

    記事のようにビルドが通らない!

    このプロジェクトは、数か月前の話になりますが、Firebaseだけが入っていた時はビルドが通っていたんです。
    今回AdmobのSDKを入れて久しぶりにビルドをしたらはまった感じになります。

    上記記事のあと、Firebaseを消してGoogleAdsのSDKのみを入れてビルドをするとUnity側でcocoapodsのエラーがなくなりビルドが成功しました。
    これはいける!?と思いXcodeでビルドをし、iphoneへ転送したところ、アプリが起動しない!
    ログをみるためにXcodeのプレイボタン(△のやつ)で起動しようとすると、こんなエラーが・・・・



    この時iPhoneのiOSを14.6にしていました。
    色々ビルドができないときに「バージョンあげてみたらいけるかもよ?」的なことをどこかのブログに書いてたので、あげちゃったんです。

    その後にやったことはこちら。

    ①Firebase、GoogleAdsを完全に削除
     消したはずが色々残ってたりするので、完全に消します。
     消す場所は以下の通り。
      Assets>ExternalDependencyManagerフォルダ
      Assets>Firebaseフォルダ
      Assets>GoogleMobileAdsフォルダ
      Assets>Plugins>IOSフォルダ
      また、PackageにExternalDependencyManagerがある場合は、PackageCacheからそのフォルダも消してみました。
      
    ②ExternalDependencyManagerだけいれてみる
     https://github.com/googlesamples/unity-jar-resolver
     ここにあるやつを入れます。
     解凍して、external-dependency-manager-latest.unitypackageを実行でインポートしました。
     これを入れないと、Unityでビルドしたときにxcworkspaceができないんす・・・・俺だけかな?
     
    ③iOS14.6に合うように、Xcodeも12.5にアップデート
     Xcode12.5はiOS14.5までが対応範囲と書いてますが、Xcode12.5が最新なのでとりあえず最新にしておきました。

    ④Unityビルドを経てXcodeでArchiveして実機転送
     Firebase、GoogleAdsがない状態ですが、無事実機でアプリが動いた!
     
    ⑤GoogleAdsの最新を落としてぶち込む
     この状態で実機まで転送したら無事うごいた!
     
    ⑥Firebasaeの最新を落としてぶち込む
     ついにFirebase+Admobで実機でうごいた!
     
    ということで、今回の戦いはここまで。
    2週間戦うという長期戦でしたが、なんとか動くところまで持っていけました。

    あ・・・・色々フォルダ消したりしてたから課金まわりが動いてたの今動かないかも・・・・・Playfabもなんか大事なデータ消しちゃったかも・・・・
    この辺ちょっと再確認が必要そうですが、いったんここで終了とさせていただきます。

    最終的な環境はこちら。

    <環境>
    MacBook Air
    ●M1ではない
    ●Big Sur 11.4
    ●Unity 2020.1.0f1
    ●Xcode12.5
    iPhoneXR
    ●iOS 14.6

    あれ?いつのまにBigsurのバージョン上がってたんだろう?

    では、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】DOTweenのSetAsが少し便利? 

    こんにちは。
    大坂です。

    最近知ったのですが、DOTweenにSetAsなんていう機能があります。
    あらかじめ指定しておいたTweenParamsやTweenerをセットして、
    複数のTweenで共通のものを何回も書かなくてよくしてくれる機能です。

    こんな感じで使えますね。

    TweenParams param = new TweenParams().SetEase(Ease.OutBack).SetLoops(-1);

    test_1.DOLocalMoveX(100f, 1f).SetAs(param);
    test_2.DOLocalMoveY(100f, 1f).SetAs(param);


    どこからでも参照できるところに準備しておけば共通でアニメーションさせるときなんかに便利ですね。
    変更するところも一元化できますしね。

    凄い短いですけどこれにてノシ

    Category: Androidアプリ紹介

    tb 0 : cm 0   

    【ハルシオンブログ】UnityプロジェクトにFirebaseとAdmobを入れたらビルドが通らない!だれか助けて!(悲痛な叫び 

    こんにちは。坂内っす。
    じめじめした日が続きますね。
    もう梅雨きたんですか?まだですよね。
    早くこのじめじめした世界からおさらばしたいところです。

    さて、ここ1週間IOSのビルドではまってます。

    <環境>
    ●MacBook Air
    ●M1ではない
    ●Big Sur 11.1
    ●Unity 2020.1.0f1


    はまってる内容としてはこんな感じ。
    https://shirokurohitsuji.studio/2021/05/02/googlemobileads-h-file-not-found-xcode-fail/

    まぁ前提条件としてUnityビルド時に「.xcworkspace」ができないのがまずは問題ですね。

    はい、そんなこんなで検索するとこんな記事もヒットします。

    https://qiita.com/noprops/items/f997a438fabb64c15f10

    cocoapodsがうまく入ってないようです。

    ということで、ここに書いてあることは10回くらいやりました。

    ほかにもいろんな記事がありますよ。
    大体目についたのはやりました。

    「.xcworkspace」ができない!

    Unityでのビルド時にこんなエラーが出ます。


    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
    [!] CocoaPods could not find compatible versions for pod "FirebaseCore":
    In Podfile:
    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/CoreOnly (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseCore (= 6.7.0)

    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseAnalytics (= 6.5.0) was resolved to 6.5.0, which depends on
    FirebaseCore (~> 6.7)

    CocoaPods could not find compatible versions for pod "GoogleAppMeasurement":
    In Podfile:
    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseAnalytics (= 6.5.0) was resolved to 6.5.0, which depends on
    GoogleAppMeasurement (= 6.5.0)

    Google-Mobile-Ads-SDK (~> 8.2) was resolved to 8.4.0, which depends on
    GoogleAppMeasurement (~> 7.0)


    pod repo update output:

    Updating spec repo `cocoapods`
    $ /usr/bin/git -C /Users/xxxxx/.cocoapods/repos/cocoapods fetch origin --progress
    $ /usr/bin/git -C /Users/xxxxx/.cocoapods/repos/cocoapods rev-parse --abbrev-ref HEAD
    master
    $ /usr/bin/git -C /Users/xxxxx/.cocoapods/repos/cocoapods reset --hard origin/master
    HEAD is now at ff691bf4d471 [Add] NendSDK_iOS_MoPub_CustomEvent 7.0.5.0

    remote: Enumerating objects: 3263, done.
    remote: Counting objects: 0% (1/3263)
    remote: Counting objects: 1% (33/3263)
    remote: Counting objects: 2% (66/3263)
    remote: Counting objects: 3% (98/3263)
    remote: Counting objects: 4% (131/3263)
    remote: Counting objects: 5% (164/3263)
    remote: Counting objects: 6% (196/3263)
    remote: Counting objects: 7% (229/3263)
    remote: Counting objects: 8% (262/3263)
    remote: Counting objects: 9% (294/3263)
    remote: Counting objects: 10% (327/3263)
    remote: Counting objects: 11% (359/3263)
    remote: Counting objects: 12% (392/3263)

     ・
     ・
     ・
     ・


    ????
    さてなんでしょうね?

    色々調べていると、ここで「pod setup」>「pod install」をするとxcworkspaceができるとかなんとか。

    pod setupは正常に完了します。

    pod installはこんな感じになります。


    xxxxx@AAAMacBook-Air AAA % pod install
    Analyzing dependencies
    [!] CocoaPods could not find compatible versions for pod "FirebaseCore":
    In Podfile:
    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/CoreOnly (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseCore (= 6.7.0)

    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseAnalytics (= 6.5.0) was resolved to 6.5.0, which depends on
    FirebaseCore (~> 6.7)

    CocoaPods could not find compatible versions for pod "GoogleAppMeasurement":
    In Podfile:
    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
    Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
    FirebaseAnalytics (= 6.5.0) was resolved to 6.5.0, which depends on
    GoogleAppMeasurement (= 6.5.0)

    Google-Mobile-Ads-SDK (~> 8.2) was resolved to 8.4.0, which depends on
    GoogleAppMeasurement (~> 7.0)



    バージョンがうんぬん。

    Unityビルドをした後に、ビルドされたフォルダにある「Podfile」を変更。


    source 'https://github.com/CocoaPods/Specs.git'
    source 'https://github.com/CocoaPods/Specs'
    platform :ios, '11.0'

    target 'UnityFramework' do
    pod 'Firebase/Analytics', '6.24.0'
    pod 'Firebase/Core', '6.24.0'
    pod 'Google-Mobile-Ads-SDK', '~> 8.2'
    end
    target 'Unity-iPhone' do
    end
    use_frameworks!



    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓


    source 'https://github.com/CocoaPods/Specs.git'
    source 'https://github.com/CocoaPods/Specs'
    platform :ios, '11.0'

    target 'UnityFramework' do
    pod 'Firebase/Analytics'
    pod 'Firebase/Core'
    pod 'Google-Mobile-Ads-SDK'
    end
    target 'Unity-iPhone' do
    end
    use_frameworks!



    それぞれのFrameworkのバージョンを消してみました。

    この状態でpod install


    xxxxx@AAAMacBook-Air AAA % pod install
    Analyzing dependencies
    Downloading dependencies
    Installing Firebase (8.0.0)
    Installing FirebaseAnalytics (8.0.0)
    Installing FirebaseCore (8.0.0)
    Installing FirebaseCoreDiagnostics (8.0.0)
    Installing FirebaseInstallations (8.0.0)
    Installing Google-Mobile-Ads-SDK (8.5.0)
    Installing GoogleAppMeasurement (8.0.0)
    Installing GoogleDataTransport (9.0.0)
    Installing GoogleUserMessagingPlatform (2.0.0)
    Installing GoogleUtilities (7.4.1)
    Installing PromisesObjC (1.2.12)
    Installing nanopb (2.30908.0)
    Generating Pods project
    Integrating client project

    [!] Please close any current Xcode sessions and use `Unity-iPhone.xcworkspace` for this project from now on.
    Pod installation complete! There are 3 dependencies from the Podfile and 12 total pods installed.



    成功!?

    無事「.xcworkspace」ができました!

    xcworkspaceからXcodeを開きビルド!!


    ld: warning: arm64 function not 4-byte aligned: _unwind_tester from /Users/xxxxx/AAA/AAAforios/Libraries/libiPhone-lib.a(unwind_test_arm64.o)
    Undefined symbols for architecture arm64:
    "_GADURequestInterstitial", referenced from:
    _Externs_GADURequestInterstitial_m77D58C1021B0E1A9320F3326857B18C58380315E in GoogleMobileAds.iOS.o
    (maybe you meant: _Externs_GADURequestInterstitial_m77D58C1021B0E1A9320F3326857B18C58380315E)
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)


    こんなエラーがでました・・・・・

    ぐぬぬぬぬぬう

    さて私はここからどうすればよいでしょうか・・・・??

    IOSビルド詳しい方教えてくだせー!

    ほんとIOSビルドむk(ry

    何がいけないのだろうか??

    ってことで、またビルドに戻ります・・・・あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 2   

    【ハルシオンブログ】SuperTextMeshの文字送りアニメーションを途中で止めたかった 

    こんにちは。
    大坂です。



    以前【ハルシオンブログ】SuperTextMeshで1文字ずつの文字送りをやってみた。の記事がありましたが、これ途中で止めたかったので試しました。

    単純に「Time.timeScale = 0f;」をしたら止まるかなーと思ったんですがデフォルトだと止まらないですね。

    一応止まらないのを確認したやつ。

    ※画像をクリックすると動きます。

    止まらないですね。
    Time.timeScaleで止めたい場合は、SuperTextMeshのTimingのところに「IgnoreTimeScalse」という項目があるので、チェックを外すと止まるようになります。


    確認。

    ※画像をクリックすると動きます。

    ちゃんと止まりましたね。
    ということで何かに使えると思うので紹介でした。
    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】抽象クラスの簡単な使い方。抽象クラスとはなんぞや? 

    おはようございます。坂内です。

    全国雨のようで、じめじめした1日になりそうですね!
    そういえば、今年もBitsummitを実施するようです。

    https://bitsummit.org/ja/%e3%82%a4%e3%83%b3%e3%83%87%e3%82%a3%e3%83%bc%e3%82%b2%e3%83%bc%e3%83%a0%e3%81%ae%e7%a5%ad%e5%85%b8%e3%80%8cbitsummit-the-8th-bit%e3%80%8d-%e3%83%87%e3%83%99%e3%83%ad%e3%83%83%e3%83%91%e3%83%bc/

    デベロッパー、パブリッシャー、メディア限定らしいですけどね。
    これ、一応俺もいけるのかな?
    行くかわかりませんが・・・・

    さて、本日は抽象クラスを簡単に紹介します。

    抽象クラスとはなんぞや?

    「抽象メソッドを1つ以上もっているクラス」のことです。

    では、抽象メソッドとは??

    「実装はしないが、メソッドの規約だけを定義したメソッド」のことです。

    はい、何を言っているのか分からない人いますね。


    実際にコードをみてみましょう。

    [Enemy.cs]

    using UnityEngine;

    public abstract class Enemy : MonoBehaviour
    {
    protected string _name;
    protected int _exp;
    protected int _money;

    public Enemy(string name, int exp, int money) {
    _name = name;
    _exp = exp;
    _money = money;
    }

    public abstract void Attack();

    public void ShowStatus() {
    Debug.Log("なまえ:" + _name);
    Debug.Log("経験値:" + _exp);
    Debug.Log("所持金:" + _money);
    }
    }



    ここでは、Attackのメソッドがabstractになっており、処理が書かれていません。
    これが抽象メソッドです。
    「Enemyを継承して作るクラスには、Attackという名前の処理が書かれているメソッドが必要だよ」という感じになっています。

    では、Enemyを継承したクラスを見てみましょう。

    [Slime.cs]

    using UnityEngine;

    public class Slime : Enemy
    {
    public Slime(string name, int exp, int money) : base(name, exp, money) {
    // コンストラクタ
    }

    public override void Attack() {
    Debug.Log("スライムの攻撃");
    }
    }



    Enemyを継承したSlimeというクラスを作成しました。
    先ほどの抽象メソッド「Attack」をoverrideで処理を書いてますが、Attackを書かないとエラーになります。
    「親クラスでabstractのメソッドは子のクラスで処理を書いてね」ってことですね。
    overrideで処理を書きましょ。

    では、実際にSlimeクラスのオブジェクトを作って、AttackやShowStatusをやってみます。

    [Blog20210517.cs]

    using UnityEngine;

    public class Blog20210517 : MonoBehaviour
    {
    void Start()
    {
    Slime slime = new Slime("スライム", 100, 50);
    slime.Attack();
    slime.ShowStatus();
    }
    }





    こんな感じになります。

    もちろん別の敵を作成もEnemyクラスを継承して作ります。

    Enemyを継承にして敵のクラスを作る場合は、絶対にAttackの処理を書かないといけないという制約が作れます。

    これが抽象クラスの基本的な使い方になります。

    ということで、今日はここまで!あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】UnityのProject内の検索 

    こんにちは。
    大坂です。

    誰でも知っているやつでがUnityのプロジェクト内のスクリプトやらを検索するバーがありますよね。
    まぁ文字列をいれたら単純に検索をしてくれるんですが。
    これちょっと便利なのが、対象を選択してから検索文字を消すとそのフォルダに飛んでくれるところですね。


    ※クリックすると動きます。

    あと検索は間にスペースをいれるとor検索してくれますね。

    ※クリックすると動きます。

    フォルダが多くなったりすると移動するのも大変なので使うと少し便利ですね。
    では今週もこれにてノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】あれ?ScriptableObjectの数値が変わってるんだけど?シャローコピーとディープコピーについて 

    おはようございます。坂内っす。
    ゴールデンウィークも終わりましたね。
    皆様どのように過ごしたでしょうか・・・・??え?なんでもないです。

    Unityにおけるディープコピーについて。

    ScriptableObjectでデータの管理をしている時に、そのデータをそのままゲーム中で使い更新すると、元のScriptableObjectのデータも更新されてしまい、困ることありませんか?

    こんな感じ。

    [EnemyData.cs]

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

    [CreateAssetMenu(menuName = "SObject/Create EnemyData")]
    public class EnemyData : ScriptableObject {

    public List<EnemyParam> enemyData = new List<EnemyParam>();

    [System.Serializable]
    public class EnemyParam {
    public string enemyName;
    public int maxHp;
    public int hp;
    public int atk;
    public int def;
    public int exp;
    public int gold;
    }
    }


    こんな感じでScriptableObjectのクラスを用意。

    オブジェクト自体はこんな感じにしてみました。


    これでScriptableObjectは完成。

    実際にこのデータを使ってみます。

    画面はこんな感じ



    [Blog20210510.cs]

    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20210510 : MonoBehaviour
    {
    [SerializeField] EnemyData enemyData;
    [SerializeField] Button btnAttack;
    [SerializeField] Text lblMessage;
    [SerializeField] Slider sldEnemyHP;
    [SerializeField] Text lblEnemyHP;

    EnemyData.EnemyParam enemy;
    int attackPower = 100;

    private void Start() {
    // とりあえず敵はスライム
    enemy = enemyData.enemyData[0];
    sldEnemyHP.maxValue = enemy.maxHp;
    sldEnemyHP.value = enemy.hp;
    lblEnemyHP.text = $"{enemy.hp} / {enemy.maxHp}";
    btnAttack.onClick.AddListener(AttackToEnemy);
    }

    void AttackToEnemy() {
    int damage = attackPower - enemy.def;
    // ダメージのブレ
    damage = Mathf.RoundToInt(Random.Range(damage * 0.8f, damage * 1.2f));
    lblMessage.text += enemy.enemyName + "に " + damage + "のダメージを与えた\r\n";
    enemy.hp -= damage;
    if (enemy.hp < 0) {
    enemy.hp = 0;
    }
    lblEnemyHP.text = $"{enemy.hp} / {enemy.maxHp}";
    }

    }



    ボタンを押すとスライムにダメージが入る感じ。

    こんな感じにうごくよ。



    さて、これでスライムを攻撃するのはできたんですが、ここで問題がおきてます。

    元のデータ(ScriptableObject)を見ると、HPが0になってます。



    ベースとなるデータの値は変えたくないですよねー

    Startの中で「enemy = enemyData.enemyData[0];」これによってデータはコピーしてきたと思ってましたが、ただのシャローコピーのようです。
    シャローコピーとディープコピーについてはこことか見るといいかも?
    https://programming.pc-note.net/csharp/copy.html


    で、ディープコピーをする方法。
    いくつかやり方はあると思いますが、一番簡単な方法。

    EnemyDataにコピーのコードを追加します。
    [EnemyData.cs]

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

    [CreateAssetMenu(menuName = "MyScriptable/Create EnemyData")]
    public class EnemyData : ScriptableObject {

    public List enemyData = new List();

    [System.Serializable]
    public class EnemyParam {
    public string enemyName;
    public int maxHp;
    public int hp;
    public int atk;
    public int def;
    public int exp;
    public int gold;

    public void Deepcopy(EnemyParam source) {
    this.enemyName = source.enemyName;
    this.maxHp = source.maxHp;
    this.hp = source.hp;
    this.atk = source.atk;
    this.def = source.def;
    this.exp = source.exp;
    this.gold = source.gold;
    }

    }
    }


    コピーのメソッドを使用するように変更。
    [Blog20210510.cs]

    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20210510 : MonoBehaviour
    {
    [SerializeField] EnemyData enemyData;
    [SerializeField] Button btnAttack;
    [SerializeField] Text lblMessage;
    [SerializeField] Slider sldEnemyHP;
    [SerializeField] Text lblEnemyHP;

    EnemyData.EnemyParam enemy;
    int attackPower = 100;

    private void Start() {
    // とりあえず敵はスライム
    enemy = new EnemyData.EnemyParam();
    enemy.Deepcopy(enemyData.enemyData[0]);

    sldEnemyHP.maxValue = enemy.maxHp;
    sldEnemyHP.value = enemy.hp;
    lblEnemyHP.text = $"{enemy.hp} / {enemy.maxHp}";
    btnAttack.onClick.AddListener(AttackToEnemy);
    }





    これで、ディープコピー完了です。
    まぁDeepcopyというメソッドを用意しなくても、コンストラクタでやってもいいんですけどね。

    こうすることで、いくらスライムのHPを減らしてもScriptableObjectのベースのデータには反映されません。

    ということで、ディープコピーとシャローコピーの話でした。

    以上。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Debug.Logにcontextを指定してみる 

    こんにちは。
    大坂です。

    Debug.Logにcontextを指定してみるとどうなるというお話です。
    コードはあってもなくてもいいようなものですが…一応

    void Start()
    {
    Debug.Log("Test_3");
    Debug.Log("Test_3_context", this);
    }


    結果。


    contextを指定したほうは、指定したオブジェクトを選択してくれますね。
    なんとなく使える機能な感じもしますね~。
    何かの時に使ってみてください。

    それではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0