【2021年】多摩動物園へ行ってきました

数年前から「12月に動物園へ行く」という謎のルーティンを自分に架しているのですが、去年はコロナの影響で行くことができず、2年ぶりに動物園へ行ってきました。

ライオン

多摩動物園は4年ぶりで、その時に工事をしていたライオン周りのエリアが完成していました。

f:id:albatrus:20211223100736j:plain
ライオン

本当はライオンバスに乗りたかったのですが、近くの小学生の子たちが占拠をしていたので諦めました。 ただ、寝ているライオンが多かったので思ったような写真とれなさそうでしたので無理に乗らなくて良かった気がしてます。

サーバル

けものフレンズで有名なサーバル。 毛づくろいをしていて、余り動いてなかったです。

f:id:albatrus:20211223101456j:plain
サーバルちゃん

アフリカゾウ

2頭外に出ていました。 前回来たときもいたのですが、どちらも見た目結構年をとっていそうでした。

f:id:albatrus:20211223102258j:plain
アフリカゾウ

チンパンジー

チンパンジーの子供。 親と思われる個体と鉢塚(人工)をなめてました。

f:id:albatrus:20211223103745j:plain
チンパンジー

1匹だけ群れと離れていたやつ。 結構ワイルドな見た目をしています。

f:id:albatrus:20211223103823j:plain
チンパンジー2

カンガルー

完全に日光浴びてくつろいでいる。

f:id:albatrus:20211223110022j:plain
カンガルー

トラ

2つの檻に1匹づついましたが、かなり大きく迫力ありました。 人間慣れしているのかすぐ近くまで来てくれて、周りの子供たちが騒いでました。

f:id:albatrus:20211223112147j:plain
トラ

ユキヒョウ

写真撮影をしている多摩動物園に詳しい人が勝手に解説をしていました。 ユキヒョウはローテーションで一頭づつ檻から出てくるシステムみたいです。

f:id:albatrus:20211223113047j:plain
檻から出てくるユキヒョウ

レッサーパンダ

日光の関係でリムライト風なレッサーパンダ。 寝ているやつが多くて、この個体だけ動いてました。

f:id:albatrus:20211223113414j:plain
リムライトなレッサーパンダ

サイ

サイのエリアが新しくなってました。 重厚な肌の質感がカメラ越しでもはっきり見えます。 サイだけではないのですが、巨大生物を見るととてもテンションが上りますね。

f:id:albatrus:20211223114949j:plain
サイ

最後に

以前に少し話題になっった女王アリが死んだコロニーはすでに撤収されていて見れなかったのが残念でした。 www.tokyo-zoo.net

新しいエリアが増えてきれいになっていました。それに伴い動物も見やすくなっている気がします。 ほとんどが家族(子供)連れでしたが、平日なので全然人がいなかったのでとても良かったです。

【Unity】TextMeshProに数字を設定する

メモ書きになります

数字を文字列変換

TextMeshProに表示するテキストは文字列でなければならないので、次のような記述をしていました。

text = x.ToString();

こちらの方法で変換はできるのですが、文字列に変換する家庭でメモリのアロケーションが起きるよと指摘をいただきました。

SetText

TextMeshProにはSetTextという関数があります。 これを使うとアロケーションなしに文字列を変換できます。

text.SetText("{0}",x};

tsubakit1.hateblo.jp

【Unity】ジェネリック型のCustomEditor

エディタ拡張を行っている時にあるジェネリクス型のクラスのInspectorを変更したい時がありその時の知見です。

対象のクラス

例えばベースクラスとして次のようなクラスを定義しました。

public class HogeBase<T> : MonoBehaviour
{
    [SerializeField]
    private T _value;
    
}

継承したクラスはこのような感じになります。

public class HogeChild : HogeBase<float>
{

}

f:id:albatrus:20211208150715p:plain
Inspector

こちらのInspectorを拡張したい場合。

[CustomEditor(typeof(HogeBase<>),true)]
public class HogeInspector : Editor
{
    private SerializedProperty _scriptProperty;
    private SerializedProperty _valueProperty;

    private void OnEnable()
    {
        _scriptProperty = serializedObject.FindProperty("m_Script");
        _valueProperty = serializedObject.FindProperty("_value");
    }

    public override void OnInspectorGUI()
    {
        using (new EditorGUI.DisabledScope(true))
        {
            EditorGUILayout.PropertyField(_scriptProperty);
        }

        EditorGUILayout.PropertyField(_valueProperty, new GUIContent("値 "));
        
        serializedObject.ApplyModifiedProperties();
    }
}

f:id:albatrus:20211208154918p:plain
CustomEditorでInspectorを編集

CustomEditor

ジェネリクスを指定する場合には次のように指定します。 また継承先のクラスのCustomEditorの対象にするためには、第2引数をtrueにしてあげます。

[CustomEditor(typeof(HogeBase<>),true)]

複数のジェネリクスを格納する場合

次のように2つのジェネリクスの型があった場合

public class HogeBase<T,TValue> : MonoBehaviour
{
    [SerializeField]
    private T _value;
    
    [SerializeField]
    private TValue _value2;
    
}

カンマを使って指定ができます。

[CustomEditor(typeof(HogeBase<,>),true)]

【Unity】TimelineのTrackの見た目を変える

TimelineのTrackの見た目を変える場合にはTrackEditorクラスを使います。

[CustomTimelineEditor(typeof(HogeTrack))]
public class HogeTrackEditor : TrackEditor
{
}

CustomTimelineEditor Attributeに指定したTrackが拡張されます。

TrackDrawOptions

TrackEditorにはTrackDrawOptionsを指定できます。 デフォルトでは次のように設定されています。

public virtual TrackDrawOptions GetTrackOptions(TrackAsset track, UnityEngine.Object binding)
{
    return new TrackDrawOptions()
    {
         errorText = GetErrorText(track, binding, TrackBindingErrors.All),
         minimumHeight = DefaultTrackHeight,
         trackColor = GetTrackColor(track),
         icon = null
     };
}
設定できる項目
  • エラーメッセージ
  • 高さの最小値
  • Trackの色
  • アイコン

f:id:albatrus:20210715155717p:plain:w350
アイコンを変更した場合

名前の変更

名前はTrack名を変更すると変わります。 次の例ではTrackEditorのOnCreateのタイミングで名前を変更しています。

public override void OnCreate(TrackAsset track, TrackAsset copiedFrom)
{
    track.name = "ほげとらっく";
    base.OnCreate(track, copiedFrom);
}

f:id:albatrus:20210715162157p:plain:w350
Trackの名前変更

なお、名前に関してはTrackが何かしらBindingをしていると表示から消えてしまいます。

f:id:albatrus:20210715162404p:plain:w350
名前が消えてしまう

その他

色々調べたのですが、現状それ以外の項目はカスタマイズできなさそうです。 Animation TrackとAudio Trackには別途ボタンが設定されているので、もしかすると何かしらのボタンはつけられるのかもしれません。

参考リンク

qiita.com

【Unity】TimelineのClipの見た目拡張

Timelineで利用するClipの拡張をする場合、ClipEditorクラスを継承をして実装を行います。

[CustomTimelineEditor(typeof(HogeClip))]
public class HogeClipEditor : ClipEditor
{

}

CustomTimelineEditor Attributeは拡張対象になるClipのクラスをしていします。

ClipDrawOptions

ClipEditorのGetClipOptionsを使えば簡単に色々な設定ができます。

ClipDrawOptionsで設定できるもの
  • エラー文言
  • Clip名の表示非表示
  • Tipsの文言
  • ハイライト色の指定
  • Icon

デフォルトでは次のように設定されています。

public virtual ClipDrawOptions GetClipOptions(TimelineClip clip)
{
    return new ClipDrawOptions()
    {
         errorText = GetErrorText(clip),
         tooltip = string.Empty,
         highlightColor = GetDefaultHighlightColor(clip),
         icons = System.Linq.Enumerable.Empty<Texture2D>()
     };
}

iconに関しては複数設定可能です。 見た目はこのような感じになります。

f:id:albatrus:20210715112035p:plain
ClipにIconを2個並べてみる

その他、拡張できるもの

その他拡張ができそうな項目

  • Clipの名前
  • 背景の拡張

Clipの名前の変更

ClipEditorにOnCreateメソッドがります。 これはClipを作成したときに呼び出されるのですが、次のようにdisplayNameを変更することができます。

public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom)
{
     var hogeClip = clip.asset as HogeClip;
     if (hogeClip == null)
     {
        return;
     }

     clip.displayName = "ほげくりっぷ";
}

f:id:albatrus:20210715114855p:plain
Clip名を変更してみる

背景の拡張 DrawBackground

DrawBackgroundメソッドをCLipが描画されるときに呼び出されます。 Clipの情報が引数で渡されるので、これを使って拡張ができます。

public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
{
    var bgSize = new Rect(region.position.x, region.position.y, region.position.width, region.position.height);
    EditorGUI.DrawRect(bgSize,Color.blue);
}

f:id:albatrus:20210715145730p:plain
Clip背景を青色にする

バックログを仕込んだらよく分かるのですが、呼び出される頻度がとても高いメソッドですので、ロジックを書く場合にはなるべく重い処理は避ける必要がありそうです。

小ネタ

ClipBackgroundRegionに渡されるposition.heightに関してはハイライト色を除いた高さが渡されている。 ですので少し調整が必要。 f:id:albatrus:20210715150722p:plain:w300

最後に

Clipに関してはある程度決まった箇所の変更はできそうです。 この辺りを使って使いやすいようにカスタマイズを行っていきましょう。

参考リンク

qiita.com

forum.unity.com

【Unity】TimelineのTrackAsset周りを調べてみる

TimelineのTrackを自作するときにTrackAssetクラスを使います。 このクラスでは何ができるのかを調べてみました。

f:id:albatrus:20210713111001p:plain:w300
TimelineのTrack

TrackAsset

自作のTrackを作る場合にはTrackAssetクラスを継承します。

public class TestTrack : TrackAsset
{
}

Clip指定する

Trackで指定できるClipをTrackClipType Attributeを使って指定します。

[TrackClipType(typeof(TestClip))]
public class TestTrack : TrackAsset
{
}

対象のオブジェクト指定する

Timelineでアニメーションを行うオブジェクトを指定する場合には、TrackBindingType Attributeを使います。

[TrackClipType(typeof(TestClip))]
[TrackBindingType(typeof(Image))]
public class TestTrack : TrackAsset
{
}

Trackの色を指定する

Trackの判別をするために色を付けることができます。 こちらはTrackColor Attributeを使って指定します。

[TrackClipType(typeof(TestClip))]
[TrackBindingType(typeof(Image))]
[TrackColor(255,0,0)]
public class TestTrack : TrackAsset
{
}

f:id:albatrus:20210713112733p:plain:w450
TrackとClipの色を変更

メソッド

TrackAssetで定義されているメソッドを調べてみました。

docs.unity3d.com

GetClips

Trackで設定されているClipを取得できます。

public IEnumerable<TimelineClip> GetClips()

CreateTrackMixer

このメソッドを継承することでClip同士のブレンド周りの処理を自作できます。

public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
    var mixer = ScriptPlayable<TestMixer>.Create(graph, inputCount);
    // 各mixerの処理
    return mixer;
}

GatherProperties

TimelineからTrackを削除したときに呼び出されます。 利用方法としては、Trackに設定されているobjectを元に戻すために利用することが多いみたいです。

public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
{

}
PlayableDirector

PlayableDirectorはTimelineを管理するコンポーネントです。

f:id:albatrus:20210713123240p:plain:w400
PlayableDirector コンポーネント

Trackに設定されているObjectを取得する場合GetGenericBindingを使います。 Imageの色を戻す場合は次のようにGatherPropertiesの記述ができそうです。

var bindingImage = director.GetGenericBinding(this) as Image;
if(bindingImage != null)
{
    // Bindingされたobjectがある場合、元に戻している
    driver.AddFromName<Text>(bindingImage.gameObject, "m_Color");
}

tsubakit1.hateblo.jp

【Unity】ExecuteAlwaysについて

Unityで使うc#のクラスでは色々なAttributeを定義することができます。 その中で「ExecuteAlways」というAttributeがあります。

docs.unity3d.com

ExecuteAlways

簡単な例は次のようになります。

[ExecuteAlways]
public class ExecuteAlwaysTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");
    }
}

通常、Unityを再生しないとStartは呼び出されませんが、ExecuteAlwaysの場合 Prafabモードに移行したときや、再生が終わった時などに呼び出されます。

OnValidate

MonoBehaviourには、Onvalidateというメソッドがあり、これを使うとInspectorの変更時の更新処理ができます。

#if UNITY_EDITOR
    private void OnValidate()
    {
        Debug.LogError("OnValidate:" + _value);
    }
#endif

今まではこちらを使っていたのですが、ExecuteAlwaysに関しても何かしらできそうだなと感じました。