TAKOYAKING’s blog 一覧

TAKOYAKING’s blog

たこ焼き系

unity: 円は9スライスできない

現象

攻撃範囲の円を表す時に9スライスでやれば良いかなと思ったのですが、9スライスは4角を使って拡大縮小するのでできません。
歪な形になってしまいます。

元は円の画像がこんな感じになります。↓
f:id:TAKOYAKING:20200830104539p:plain

解決策

How can I draw a circle in Unity3D? - Stack Overflow

解決策は3パターン?
1. LineRendererで円を描く
2. shaderで円を描く
3. 普通に画像で描き、拡大縮小を気にしない


今回は3の普通に画像で描きました。
拡大縮小しても何も気にならなかったので良しとします。
f:id:TAKOYAKING:20200831042840p:plain

Unity: Admob appIdはinspectorで設定できるようになっていた

久々にAdmobを触ることになりましたが、公式によると
スタートガイド  |  Unity  |  Google Developers

旧形式

MobileAds.Initialize(appId); 

新形式

MobileAds.Initialize(initStatus => { });

新形式はappIdを引数に取らなくなり、
[Assets] > [Google Mobile Ads ] > [Settings] からandroidiOSのappIdを入力するようになりました。

感想

多分だいぶ前から新形式になっていたのでしょうか?

Android バージョン 17.0.0 および iOS バージョン 7.42.0 向けの Google Mobile Ads SDK では、この手順は必須です。
AdMob アプリ ID を空のままにすると、クラッシュして「The Google Mobile Ads SDK was initialized incorrectly.」というメッセージが表示されますので、すぐにこの変更を加えてください。

と出ていたので、慌てて対応しました。

Unity: SpriteRendererのbounds.sizeとsizeの違い (備忘録)

SpriteRenderer.bounds.size

Unity - Scripting API: Bounds.size
SpriteRenderer.bounds.sizeは画像の大きさを取得できます。
普通の画像ならこっち使っておけばOK! (雑な説明)

SpriteRenderer.size

Unity - Scripting API: SpriteRenderer.size
SpriteRenderer.sizeはSpriteRendeerer.drawModeがSlicedになっている時にサイズを取得できます。

感想

ややこしい!

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
このバグに関係しているかもとのことでした。