TAKOYAKING’s blog 一覧

TAKOYAKING’s blog

たこ焼き系

The same field name is serialized multiple times in the class or its parent class

The same field name is serialized multiple times in the class or its parent class. This is not supported: Base(WeaponBlockVars) <ObjType>k__BackingField

Unityのエラー「The same field name is serialized multiple times in the class or its parent class.」について - Qiita
この記事によると「継承元と継承先のクラスの同名Private変数をSerializeできないため」と書いてあったのですが、interfaceを継承した基底クラスのフィールドをoverrideした時にもなぜか発生するようです。

ただ、SerializeFieldとして出現するわけではないのに、このメッセージが出るのは気持ち悪いので、いろいろ検索してみました。
↓バグではないか?という記事
The same field name is serialized multiple times in the class or its parent class. This is not supported · Issue #1032 · accord-net/framework · GitHub
↑の記事によると一旦リネームして、もとに戻せば直るよということでしたが、直りませんでした。

環境

  • Unity 2020.1.1f

再現手順

1. Addressablesのnew buildを行う
2. 再生ボタンを押す

とエラーが出力されます。

問題のコード(原因)

interfaceとMonoBehaviourを継承したBaseクラス。
そのBaseクラスを継承した派生クラス。
その派生クラスではBaseクラスのinterfaceメソッドをoverrideする。

public interface ISample {
    int Takoyaki { get; set;}
}

public class Base : MonoBehaviour, ISample {
    public virtual int Takoyaki { get; set;} = 1;
}

public class Derived: Base {
    public override int Takoyaki { get; set;} = 777; //←これがダメらしい・・・
}

解決策

不明。上記のコードで再現するけどいろいろゴニョゴニョやっている内に上記のコードはエラーが出なくなってしまった。

感想

モヤッとする・・・

Unity: OnCollisionXXXとOnTriggerXXXの実行順序

OnCollisionXXXとOnTriggerXXXの実行順序は以下のドキュメントによると
イベント関数の実行順序 - Unity マニュアル
1. OnTriggerXXX
2. OnCollisionXXX
となるようです。

どういう時に役に立つか?

ブロックを破壊した時に「跳ね返って欲しくない場合と跳ね返って欲しい場合」を作る場合、この実行順序の挙動を使って切り分けることができます。

跳ね返って欲しい時はOnCollisionEnter内でGameObjectを破壊すれば、跳ね返りますし、跳ね返って欲しくない場合はOnTriggerEnter内でGameObjectを破壊する処理をすれば、OnCollisionEnterの前に破壊できてしまうので、跳ね返らなくなります。

参考動画 (こんな感じになります)
f:id:TAKOYAKING:20200819032700g:plain

やり方サンプル

GameObject

1. 弾丸に2つのColliderをつけて、片方にはisTriggerにチェックを入れた状態にします。
2. ブロックにColliderをつけます。

スクリプト

OnTriggerEnterに破壊処理を書けばOKです。

  • 跳ね返って欲しい時はOnCollisionEnter
  • 跳ね返って欲しくない時はOnTriggerEnter
void OnTriggerEnter2D(Collider2D collision) {
    Destroy(collision.gameObject); // 跳ね返って欲しくない時
}

// void OnCollisionEnter2D(Collision2D collision) {
// 何も書かない
// }

感想

ブロック貫通して破壊する処理を実装したかったので、お手軽に実装できてよかった!

Rust: RefCellで囲んだFnMutはDerefMutが実装されていない

現象

f: RefCell<dyn FnMut()>>

とした時に

f.borrow_mut()() // この形式では呼べない

とは呼べず、

(&mut *f.borrow_mut())();

と呼ばなくてはいけない

調査

rust - why DerefMut is not implemented for `std::cell::RefMut<'_, [..]>` which wraps FnMut? - Stack Overflow
この記事によると上記のf.borrow_mut()()では呼べないとありました。
Cannot borrow as mutable despite DerefMut · Issue #51886 · rust-lang/rust · GitHub
このバグに関係しているかもとのことでした。

「SOUNDPEATS TrueAir ワイヤレス イヤホン」 エントリーモデルとしてはコスパ良好

SOUNDPEATS TrueAir ワイヤレス イヤホンを購入しました。
カナル型(耳に突っ込まないタイプ)でなく、耳に引っ掛けるものを探していた時に、この製品がコスパが良いらしいので買ってみました。
カナル型は耳に合わないことが多いし、耳が痛くなるので、耳に引っ掛けるタイプを探していました。
※使用状況は2週間ちょいです。

https://images-na.ssl-images-amazon.com/images/I/51UU3K500DL._AC_SX679_.jpg

環境

接続のしやすさ

接続してしまえばとても安定します。
ふたを開けるだけで接続されるのでとても使いやすいです。

ただ接続されるまでAndroidは難しかったです。何回試みても、接続してくれなかったので、諦めようかと思ったのですが、モバレジェ(ゲーム)を開いた瞬間繋がりました!(理由はわかりません・・・)


iMacは昔に持ってたワイヤレスイヤホンはキーボードとトラックパッドに干渉されてうまくいかなかったけど、これはそんなことは無くとても快適です。
以前のワイヤレスイヤホンは↓で格闘済み
iMac 2019 bluetoothイヤホンが接続されない時の苦肉の対処法 - TAKOYAKING’s blog

価格

安いです。
クーポンとかセールのタイミングで買えば4000円前後で買えるのではないでしょうか。正規料金は5000円くらいです。

こもった感じです。
iPhoneについているイヤホンみたいな音でクリアな音質ではないのは確かです。
でも耳に引っ掛けるタイプのワイヤレスイヤホンはどれもこんな音になっているような気がします。
逆に、カナル型だとクリアな音質になる傾向がある気がします。

音量操作

どこをタップしたらいいかわからないので、使いづらいと思います。
上の丸い部分をタップすると音量調整ができます。
慣れがかなり必要です。

付属の充電ケーブル

ものすごく短いのが付いてくるので、別のを用意した方がいいかもしれません。
iMacだと裏からつなぐので全然足りないです。

接続の安定具合

めちゃくちゃ良好
今のところぷつっと切れたことは無いです。

以前のワイヤレスイヤホン だとちょくちょく切れていたので、それと比べると遥かに良いです。

衛生面

カナル型(耳栓みたいなイヤホン)と比べると遥かに綺麗さを維持できます。
今のところ汚れる気配がないです。

電池の残量表示

電池の残量は減ったら赤ランプが点灯します。
見辛いですが安かったので妥協できる範囲です。

ただ充電する時、充電が完了しているか確認する方法がないので不便です。

電池のもち具合

体感的には仕様通りの時間だと思います。あんまり充電してなくても、ずっと使えているので、ここら辺は優秀だと思います。

見た目

AppleAir Podsに酷似しています。
気になる方はやめておいた方が良いかもです。

まとめ

デザインの見た目を気にしなくて、耳にひっかけるタイプで格安のものを探しているならとても良い製品です。結構満足しています。

Unity: Addressablesでフォルダはネストできない

環境

  • Addressables 1.8.4

現象

ざっくりフォルダごとにAddressablesで管理したい場合に、入れ子になったフォルダではできないようです。
ネストした状態でもUnity Editor上なら再生でき、ネストも一見できてるように見えるのですが、Androidビルドする時に以下のエラーが出るようです。

ArgumentException: An item with the same key has already been added.

以下のような構成にしてそれぞれのフォルダに対してAddressablesのチェックをonにしました。

- Prefabs (Addressablesのチェック)
  - 何かのspriteたち
  - Takoyakis (Addressablesのチェック) 
    - 何かのspriteたち


こういう構成だと、AddressablesのwindowではPrefabsとTakoyakisは別のGroupとして設定でき、別のラベルを設定できるのですが、いざビルドすると重複キーがあると怒られてしまいます。

対策

ざっくりチェックは諦めて、以下のようなツールを使って管理するのが良いかもです。
【Unity】【Addressable】Unity Addressable Importerでアドレスの設定を自動化する - LIGHT11

Unity: 落下の自前計算 (簡易版)

Cheap gravity script - Unity Answers

厳密には違いますが、簡易版で同じような動きになります。

そこまで正確に動きを計算する必要がないのでこれでいいならこれを使いたいです。

簡易重力を自前で計算した時の鉄球の動き↓
f:id:TAKOYAKING:20200808195703g:plain

float velocity = 0;
void FixedUpdate() {
      var pos = transform.position;
      velocity += Physics2D.gravity.y * Time.fixedDeltaTime;
      pos.y += velocity * Time.fixedDeltaTime;
      transform.position = pos;
}

Unity: UniRxのUpdateAsObservable

UpdateAsObservable

Updateを実行することができる

使い方

using UniRx;
using UniRx.Triggers;

void Start() {
    this.UpdateAsObservable()
            .Subscribe(UpdateRx);
}

void UpdateRx(Unit unit) {
    Debug.Log("updating");
}

this.UpdateAsObservable()をSubscribeしてあげることで、Updateされ続けます。
そして、subscribeしたものはobject破棄のタイミングで消滅します。

便利だと思ったこと

Updateは別のscriptから初期化処理を呼び出してから呼びたい場合、

using UniRx;
using UniRx.Triggers;

public void Init() { // publicで他scriptからinit
    this.UpdateAsObservable()
            .Subscribe(UpdateRx);
}

void UpdateRx(Unit unit) {
    Debug.Log("updating");
}

こういう感じで書けるので、
Init
UpdateRx
の順番が保証できるので便利だな思いました。