FacebookSDKの組み込みに苦労した

FacebookSDKの組み込みに苦労した。

Android版。

1. You don't have the Android SDK setup!というエラー

なぜかSDKのパスを認識していないらしい。

  1. Preferences>External Tools>Android SDK
  2. 設定済みのパスをコピーしてチェックを外す
  3. コピーしたパスを貼り付ける
  4. 再度チェックをいれる

でエラーがでなくなりました。

2.Your android debug keystore file is missing!というエラー

デバッグ用のkeystoreが無いよ。ということらしい。Macの場合、
/Users/ユーザー名/.android
以下にデバッグ用のkeystoreを作ってあげると解決する。
作るのがめんどくさいので、テキトーに空のプロジェクトを作ってAndroidビルドすると勝手にできる。


これらのエラー、Forum見ると数年直っていないっぽい。なんとかして欲しい。

C#では型でもswitch文で分岐できるらしい

最近、型でもswitch文で分岐できるということを知った。
例えば以下のような感じ。

using UnityEngine;

public interface TestInterface
{
}

public class TypeA : TestInterface
{
}

public class TypeB : TestInterface
{
}

public class TypeC : TestInterface
{
}

public class TestTypeSwitch : MonoBehaviour
{
    private TestInterface testType = new TypeC();
    
    void Start()
    {
        switch (testType)
        {
            case TypeA:
                print("This is Type A.");
                break;
            case TypeB:
                print("This is Type B.");
                break;
            case TypeC://testTypeはTypeC型なのでここを通る
                print("This is Type C.");
                break;
        }
    }
}

あまり使うシチュエーションは無い気がするけど。

リソース読み込み終わったらチョメチョメしたいをUniTaskとUniRxで

Unity開発者ギルドで、何か読むのにオススメのコードを募集したら、かめふぃさんのコードをご紹介いただきました。
github.com


色々と学ぶところが多かったのですが、今日はそのうちの1つを忘れないようにメモ。

リソース読み込み終わったらチョメチョメしたいっていうのをUniTaskとUniRxで良い感じに書かれていたので、自分も真似して書いてみました。

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;

//Icon名を渡すと、Resourcesから読み込んで非同期で返すクラス
public class IconProvider : IDisposable
{
    private Dictionary<string, Sprite> _cache = new Dictionary<string, Sprite>();
    
    public async UniTask<Sprite> GetIcon(string name)
    {
        //キャッシュにあったらキャッシュの方を使う
        if (_cache.ContainsKey(name))
        {
            return _cache[name];
        }

        _cache[name] = await Resources.LoadAsync<Sprite>("Sprites/Icons/" + name) as Sprite;
        Debug.Assert(_cache[name] != null);//nullは許さない

        return _cache[name];
    }

    public void Dispose()
    {
        _cache = null;
    }
}
using UniRx;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;

//アイコンを読み込んでImageに挿し込むテスト
public class IconProviderTest : MonoBehaviour
{
    [SerializeField] private string iconName;
    private readonly IconProvider _iconProvider = new IconProvider();
    private Image _image;

    void Start()
    {
        _image = GetComponent<Image>();

        LoadIcon();
    }

    [ContextMenu("LoadIcon")]
    void LoadIcon()
    {
        _iconProvider.GetIcon(iconName)
            .ToObservable()
            .Take(1)
            .Subscribe(sprite => { _image.sprite = sprite; });
    }
}

ポイントとしては、GetIconで返ってきたUniTaskをToObservableしているところ。
こんな事ができるんですね〜。
Subscribeすると、GetIconの処理が終わったタイミングで購読した処理を走らせてくれるみたいです。
すごい!

P.S
これだったら、ContinueWithで良いんじゃない?っていうご指摘を受けました。
たしかに...

 _iconProvider.GetIcon(iconName)
    .ContinueWith(sprite => { _image.sprite = sprite; });

これでいけますね。Observableを返せて嬉しいのは、もっと細かくタイミングを制御したいときですかね〜。

プロパティをSerializeFieldにしたい

Unityをやっているとこんなふうに書けたら良いのに...って思うことないですか?

[SerializeField]
public string Name { get; private set; }

要は、プロパティをSerializeFieldにしてInspector上に表示したり値を保存したりしたいのです。しかし、これはうまくいきません。

なので、しかたなく以下のように書いていました。

[SerializeField] private string name;
public string Name => name;

わざわざあたらしくnameというメンバ変数を書き足すのです。めんどくさいです。

しかし、これを解決する書き方を教わりました。

[field: SerializeField]
public string Name { get; private set; }

SerializeFieldの前にfield:をつけるんですね。なぜこれでうまくいきのでしょう?

そもそも、なぜ

public string Name { get; private set; }

このようにかけるかというと、これはC# 3.0 で導入された自動プロパティ(auto-property, auto-implemented property)という機能によるものです。

これは、プロパティのget/setの中身の省略できるしくみですが、内部的には、

private string __name;
public string Name
{
  get { return this.__name; }
  set { this.__name = value; }
}

というようなコードに相当するものが生成されています。 (__nameという変数にプログラマは直接アクセスできません。)

このコンパイラーによって生成されるフィールド(この例で言うと __name)は、バックフィールド(baking field: 後援フィールド)と呼ばれます。

先のコードでSerializeFieldの前に書いたfield:は、このバックフィールドを対象にしますよっという記述なのです。

なので、__nameがSerializeFieldになり、めでたくInspector上にも表示されるというわけです。

参考:

ufcpp.net

ufcpp.net


P.S
バックフィールドにSerializeField属性をつけるのは良くないという記事を見つけました。
色々理由は書かれていますが、自分としては、バッキングフィールドの命名が仕様化されていないという点が一番怖いかなと思いました。
ないとは思うけど、万一、命名規則が変わったりしたら...
qiita.com

今までSandboxで課金テスト出来ていたのが、突如レシートの検証が失敗するようになった。

今までSandboxで課金テスト出来ていたのが、iOSのみ突如レシートの検証が失敗するようになった。

購入処理はうまくいくのにレシート検証で失敗するようで以下のようなエラーが出た。

Validation failed:/Client/ValidateIOSReceipt:iTunes Sandbox validation result:21003
(AuthnticationFailed) from https://sandbox.itunes.apple.com/verifyReceipt

最近変えたところといえば、アプリ内課金にサブスクリプションを追加したこと。

しかし追加しようとしているSubscription以外の、ジェムの購入でもエラーが出るようになってしまった。

レシートの検証にはPlayFabを使っている。

はてっ???

いろいろ調べ、知人に相談し、ようやく解決。

結論としてはPlayFabでアプリ共有シークレット(App-Specific Shared Secret)を設定したら解決しました。

1.App Store Connect でApp-Specific Shared Secretを作る。
f:id:wkpn:20220306172655p:plain


2.上記で出来たキーをPlayFabで設定する。
f:id:wkpn:20220306172713p:plain

How to upload to Unityroom

Preparation

WebGL Build

Select WebGL in Build Settings.

f:id:wkpn:20220214224106p:plain

Select Gzip as a compression format in Player Settings.

f:id:wkpn:20220214224122p:plain

Twitter account

You need a Twitter account to log in to Unityroom.


Procedure

1. Log in to Unityroom

Access the Unityroom and press "New user registration / login" button on the upper right.

f:id:wkpn:20220214224329p:plain


Please read the terms of use and if you agree to them, please authenticate through the Twitter button.

f:id:wkpn:20220214225219p:plain

If you log in successfully, the header menu will change and you will see the Twitter icon.

f:id:wkpn:20220214225312p:plain


2. Create a new game

Header-> Register Game

f:id:wkpn:20220214225700p:plain

Enter the title, game ID and brief description, then press Register.

title

The title of the game.

Game ID
  • This is a string that will be used as part of the URL.
  • You are free to determine this.
  • Only alphanumeric characters, hyphens, and underscores can be used.

If the registration is successful, you will be taken to the basic information edit screen.

f:id:wkpn:20220214225935p:plain

Game setting items are lined up in the side menu.

It is not necessary to set everything in detail.
I will explain the only items which is essential here.

f:id:wkpn:20220214230022p:plain


3. Icon registration

Sidebar "Basic information" menu

f:id:wkpn:20220214230201p:plain

Select the icon to update. You can change the title and description as needed.


4. WebGL upload

Sidebar "WebGL settings" menu

f:id:wkpn:20220214230509p:plain

Select the Unity version here. Please fill in the screen size, how to play, and memory usage as you like.

Sidebar "WebGL upload" menu

f:id:wkpn:20220214230713p:plain

Upload the file output from Unity. Look carefully at the extension and make sure you select it correctly.

f:id:wkpn:20220214230756p:plain

If the upload is successful, the screen will be refreshed and the file size etc. will be displayed at the bottom of the page.

5. Live Policy

f:id:wkpn:20220215143916p:plain

6. Publishing settings

Sidebar "Publishing settings" menu

f:id:wkpn:20220214230915p:plain

If you have completed at least the icon and WebGL upload, you can publish it. Please select your preferred publishing setting.

気がつくとM-1 Max Macが異様に重くなる現象に悩まされた

M-1 MaxのMacを買ったのだけれど、1日使っていると1日の終わり頃にめちゃくちゃ重くなって困っていた。IMEの変換でしびれを切らすほど重かった。

なんでだろうと調べてみると、sshのプロセスが多数存在していた。どうもgitがsshを使ってそれが残り続けているっぽかった。調べても理由はよくわからなかったのだが、とりあえずsshタイムアウト時間を設定することで対応できた。

./ssh/configでホストごとの設定をしているところに

    ClientAliveInterval 3600

の行を追加して対処できました。