【自作ゲーム開発32】設置予定のオブジェクトが視覚的に分かるように【Unity】


注意
本記事で掲載されている動作の実装方法及びプログラムのソースコードは最適な方法ではない可能性があります。
今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。

はじめに

Unityによる自作ゲーム開発進捗その32になります!

今回はタワー設置時に設置物を薄く表示するようにしてみました。

既存のスクリプトを1つ更新します。

以下に動画でのコピー用にソースコードを掲載しています。

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

public class RangeSystem : MonoBehaviour {
    [SerializeField]
    private CinemachineVirtualCamera m_range_camera;

    [SerializeField]
    private ParticleSystem m_tower_effect;

    [SerializeField]
    private ParticleSystem m_explosion_effect;

    [SerializeField]
    private GameObject m_lockon_basic_tower;

    [SerializeField]
    private GameObject[] m_clear_object = new GameObject[1];

    private Vector3 m_vector3;
    private Vector3 m_center_position;
    private Rigidbody m_rigidbody;
    private CapsuleCollider m_hit_collider;

    private float m_range_area;
    private float m_move_speed = 0.1f;
    private float m_horizontal = 0.0f;
    private float m_vertical = 0.0f;

    private bool m_range_mode = false;
    private bool m_execution_play = false;

    private void Start() {
        m_rigidbody = GetComponent<Rigidbody>();
        m_hit_collider = GetComponent<CapsuleCollider>();
    }

    private void Update() {
        m_horizontal = Input.GetAxis("Horizontal"); // タスク2
        m_vertical = Input.GetAxis("Vertical"); // タスク2
    }

    private void FixedUpdate() {
        if ((m_range_mode) && (!m_execution_play)) {
            m_vector3.Set(m_horizontal, 0f, m_vertical);
            m_vector3.Normalize();

            if (Vector3.Distance(m_center_position, m_rigidbody.position + m_vector3 * m_move_speed) > m_range_area) {
                Vector3 l_position = m_rigidbody.transform.position + m_vector3 * m_move_speed - m_center_position;
                m_rigidbody.position = m_center_position + l_position.normalized * m_range_area;
            } else {
                m_rigidbody.MovePosition(m_rigidbody.position + m_vector3 * m_move_speed);
            }

            m_horizontal = m_vertical = 0.0f;
        }
    }

    public void ClearObjectState(int a_number, bool a_state) {
        m_clear_object[a_number].SetActive(a_state);
    }

    public bool RangeSetting(bool a_state, Vector3 a_center, float a_area) {
        if (m_execution_play) return false;

        m_range_mode = a_state;

        if (a_state) {
            m_center_position = this.transform.position = a_center;
            m_range_area = a_area;
            m_range_camera.Priority = 20;
        } else {
            m_range_camera.Priority = 0;
            this.gameObject.SetActive(false);
        }

        return true;
    }

    public void TowerCreate() { // タスク1
        if (!m_execution_play) {
            m_execution_play = true;
            StartCoroutine("RangePlay");
        }
    }

    IEnumerator RangePlay() {
        m_tower_effect.Play();
        var l_instance = Instantiate(m_lockon_basic_tower, m_rigidbody.position, Quaternion.Euler(0, 0, 0)); // タスク2
        yield return new WaitForSeconds(2.0f);
        m_execution_play = false;
    }

    public void FireCreate() {
        if (!m_execution_play) {
            m_execution_play = true;
            this.tag = "PlayerSkill3";
            m_explosion_effect.Play(); // タスク3
            StartCoroutine("FirePlay");
        }
    }

    IEnumerator FirePlay() {
        // タスク4
        yield return new WaitForSeconds(1.8f);
        m_hit_collider.enabled = true;
        yield return new WaitForSeconds(0.2f);
        m_hit_collider.enabled = false;
        yield return new WaitForSeconds(0.8f);
        m_explosion_effect.Stop();
        m_execution_play = false;
        this.tag = "Untagged";
        yield break;
    }
}

/*
    [規則]
    p_ 外部アクセス
    m_ メンバー変数
    l_ ローカル変数
    a_ 引数
    e_ 列挙型

    [説明]

    [バージョン]
    2021-04-23 移動制限とタワー設置機能
    2021-07-15 座標指定攻撃の追加
    2021-11-18 透明のオブジェクトの表示を切り替えれるように(未使用)

    [タスク]
    タスク1 引数の番号でタワーを選択出来るようにする
    タスク2 固定のタワーではなく指定されたタワーのオブジェクトとする
    タスク3 引数の番号で範囲攻撃を選択出来るようにする
    タスク4 固定の範囲攻撃ではなく範囲攻撃や秒数を指定出来るようにする
*/

設置準備中は半透明で表示

public void ClearObjectState(int a_number, bool a_state) {
    m_clear_object[a_number].SetActive(a_state);
}

上記関数を呼び出す事で半透明にし配列に格納しているオブジェクトを表示したり非表示に出来るようにしていますが、今回はタワー1つだけのため表示したままで次回以降に使用していく事になります。

半透明化はモデルとテクスチャーをコピーし、テクスチャを【Fade】に変更しアルファ値を下げています。

様々な半透明化の方法が存在しているかと思いますが、今回は上記方法を使用していきます。


動画


記事のリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です