キューバに行ってみたい

ゲーム開発とかWeb開発とか

[Unity] n秒ごとにイベントを発火する script を書いてみる

Version unity 2020.3.27.f1 で動作検証を行っています。

特定の周期でテキストを点滅させたいなどあるかと思います。

今回はそのような n秒ごとに特定のイベントを実行したい時の実装例を紹介します。

0.5秒ごとにテキストを点滅させてみる

例ではテキスト (TextMeshPro) を 0.5秒ごとに点滅させます。

こんな感じです。

以下の script を text にアタッチします。

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


public class BlinkingTextController : MonoBehaviour
{
    private TextMeshProUGUI t;
    private float alpha = 1.0f;
    private float elapsedTime = 0f;

    private void Start()
    {
        this.t = this.gameObject.GetComponent<TextMeshProUGUI>();
    }

    private void Update()
    {
        Blink();
    }

    private void Blink()
    {

        this.elapsedTime += Time.deltaTime;
        if (this.elapsedTime > 0.5f)
        {
            this.alpha = this.alpha == 1.0f ? 0.0f : 1.0f;
            this.t.color = new Color(255, 255, 255, alpha);
            this.elapsedTime = 0.0f;
        }
    }
}

elapsedTime に Time.deltaTime を加算し前フレームからの経過時間を積み重ねます。

elapsedTime (経過時間) が 0.5f秒経過するごとに text の alpha値を変更して点滅させています。

今回はテキストを点滅させましたが、他の処理でも応用することができるかと思います。

簡単ですが以上です。

[Unity] OnCollisionStay2D を使って物体が接触していることを検知する

Version unity 2020.3.27.f1 で動作検証を行っています。

前回は物体が離れたことを検知する方法を紹介しました。

blog.bestinarix.studio

今回は物体が接触していることを検知する方法を紹介します。

実装方法

今回のサンプルは円が落下して四角形に接触するとテキストが off から on に変わるような script を書きます。

物体の衝突は OnCollisionEnter2D メソッド、離れたことは OnCollisionExit2D メソッドで検知すると以前記事に書きました。

接触状態は OnCollisionStay2D メソッドを使用します。

以下のような script を準備します。

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

public class StayController : MonoBehaviour
{
    [SerializeField] Text _text;
    private void OnCollisionStay2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "circle")
        {
            _text.text = "on";
        }
    }
}

この script を四角形にアタッチして、_text には off のテキストをアタッチしておきます。

離れた時と同様に円には circle の tag を設定して Rigidbody 2D もアタッチしておきます。

もちろんそれぞれのオブジェクトに collider を設定しておく必要もあります。

設定は以上でこれで動かしてみると以下のように期待通りの挙動が実現できます。

参考

docs.unity3d.com

[Unity] OnCollisionExit2D を使って物体が衝突から離れたことを検知する

Version unity 2020.3.27.f1 で動作検証を行っています。

以前物体の衝突の検知方法を紹介しました。

blog.bestinarix.studio

今回は物体が離れたこと検知する方法を紹介します。

では早速実装方法です。

実装方法

サンプルとして円が四角形から離れるとテキストが off から on に変わるような script を書きます。

物体の衝突は OnCollisionEnter2D メソッドで検知できましたが、離れたことは OnCollisionExit2D メソッドで検知することができます。
この他にも OnCollisionStay2D メソッドというのも存在し物体が接触していることを検知します。
これはまた別の機会で紹介したいと思います。

以下のような script を準備します。

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

public class ExitController : MonoBehaviour
{
    [SerializeField] Text _text;
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "circle")
        {
            _text.text = "on";
        }
    }
}

この script を四角形にアタッチして、_text には off のテキストをアタッチしておきます。

円には circle の tag を設定して Rigidbody 2D もアタッチしておきます。
これで円が重力によって落ちるようになります。

設定は以上でこれで動かしてみると以下のように期待通りの挙動が実現できます。

参考

docs.unity3d.com

[Unity] ボタンで Scene 変更を行える汎用的な script を作成する

Version unity 2020.3.27.f1 で動作検証を行っています。

カジュアルゲームなどでステージクリア後にボタンが表示されて次のステージに遷移するというような実装を行いたいことがあるかと思います。

毎回次のステージの Scene を指定してロードする為の script を用意するのは面倒なので、今回は汎用的な script を実装していきます。

実装方法

今回はサンプルの実装ということで、まず次のステージへのボタンを配置した Scene を準備して以下のような script を Button にアタッチします。

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

public class TransitionManager : MonoBehaviour
{
    [SerializeField] private string _loadScene;
    public void OnClick()
    {
        SceneManager.LoadScene(_loadScene);
    }
}

そして Button にアタッチした script の OnClick メソッドを event として登録しておきます。

また script の変数である _loadScene には次の Scene の Scene名を設定します。

全体としてはこんな感じです。

このように script の変数に次の Scene名を設定できるようにすることでステージごとに script を作成せずに1つの script を汎用的に使いまわすことができます。

また、検証していませんが Scene名を規則的にする、例えば Stage1Scene, Stage2Scene とすることで script で現在の Scene を取得してから正規表現で抜いて次の Scene を設定することでそもそも変数に設定すること自体不要にすることができそうです。

[Unity] script で TextMeshPro を扱う

Version unity 2020.3.27.f1 で動作検証を行っています。

ドットゲームの開発をしていて、ドット文字を表示させる際に TextMesh Pro を使用したので実装方法をまとめておきます。

そもそも TextMesh Pro とは?

TextMeshPro は、テキストのための究極のソリューションです。Unity の UI Text と古い Text Mesh の代わりに使用するのに最適です。

強力で使いやすい TextMeshPro (TMP) は、高度なテキストレンダリング技術と一式のカスタムシェーダーの使用によって、テキストのスタイリングとテクスチャリングに関して非常に高い柔軟性を提供しながら、視覚的な品質を大幅に向上させます。

TextMeshPro を使用すると、テキストのフォーマットとレイアウトに際してより高度な制御が可能になります。例えば、文字・行・段落の間隔調整や、カーニング、テキストの両端揃え、リンク、30 種類を超えるリッチテキストタグ、複数のフォントやスプライトのサポート、カスタムスタイルなどの機能を備えています。

TextMeshPro は素晴らしいパフォーマンスも備えています。TextMeshPro で作成されたジオメトリは、Unity のテキストコンポーネントと同様に 1 文字ごとに 2 つの三角形を使用するため、パフォーマンスの負荷を増加させることなくビジュアル品質と柔軟性を向上させることができます。

docs.unity3d.com

公式ドキュメントによると上記のように記載されています。 要約すると TextMesh, uGUI のハイブリッド版 のような component でテキストを綺麗に描画してコントロールしやすくなるコンポーネントのように見えました。

理解が間違っていましたらご指摘いただければ助かります。

実装方法

今回は PixelMplus を利用させていただきました。

itouhiro.hatenablog.com

テキストの import はこちらの記事が参考になります。

qiita.com

Hierarchy View から TextMesh Pro を追加します。

この時 PixelMplus10-Regular に設定します。

次に操作する script を用意します。
前回実装した Timer の script を流用します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class TimerManager : MonoBehaviour
{
    [SerializeField]
    private TextMeshProUGUI _timerText;

    private float _time = 60f;

    void Update()
    {
        _time -= Time.deltaTime;
        int seconds = (int)_time;
        _timerText.text = seconds.ToString();
    }
}

uGUI の利用との差分としては TMPro を using して、型を TextMeshProUGUI を使うようにします。

以上です。

[Unity] 制限時間の設定に使えるシンプルなタイマーを実装する

今回は制限時間などに使えるタイマーを実装してみましたので実装方法を紹介します。

実装方法

まず、Hierarchy ビューからタイマーを表示する Text を追加します。

次に時間をカウントダウンさせる script を以下のように実装します。

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

public class TimerManager : MonoBehaviour
{
    [SerializeField]
    private float _time;

    private Text _timerText;

    private void Start()
    {
        _timerText = gameObject.GetComponent<Text>();
        _timerText.text = _time.ToString();
    }

    void Update()
    {
        _time -= Time.deltaTime;
        int seconds = (int)_time;
        _timerText.text = seconds.ToString();
    }
}

_time 変数に制限時間を設定し、開始時に制限時間が描画されるようにします。

そして、Update 関数内で Time.deltaTime でフレームごとに制限時間を減算します。 減算した時間は float 型なので int 型にキャストしてテキストとして描画します。

以上がタイマーの実装方法です。

[Unity] script を使って n秒後にオブジェクトを削除する

球が壁に衝突して n秒後にその球を消したかったので、実装例について書きます。

実装方法

球の準備として Sprite Renderer で Circle を描画した GameObject を用意し、Rigidbody 2D, Circle Collider 2D の component を attach します。

次に衝突させる壁を用意します。
Sprite Renderer で Square を描画し、Box Collider 2D をアタッチして当たり判定できるようにします。

そして、以下の script を準備して Circle オブジェクトにアタッチします。

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

public class Collision : MonoBehaviour
{
    public void OnCollisionEnter2D(Collision2D collision)
    {
        Destroy(gameObject, 3.0f);
    }
}

ポイントとなるのが、Destroy() メソッドの第二引数です。
第二引数は対象のオブジェクトが削除されるまでの遅延時間を指定できます。 今回は 3.0f なので、衝突から3秒後にオブジェクトが削除されることになります。

docs.unity3d.com

以上になります。