質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

UnityUIのtextの変更するスクリプトについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 298

Erbin

score 9

前提・実現したいこと

その1 画面右下に残弾を表示させ、リロード(Rボタン)をすると指定した時間後までに1ずつ数字が増え、最大装弾数になるということをしたいです。

その2 数字ではなく円ゲージでも打ったら少しずつ減りn秒後に最大になるようにしたいです。

発生している問題・エラーメッセージ

打って弾が減ると残弾数が表示されるようにはでき、n秒後に最大になるのはできたのですが、1ずつ増やすができないです。(その2を試したらこれすらもできなくなりました)
スクリプトはかけたのですが(絶対動くとは言ってない)、どこに配置するかという基本的なことがわからないです。

NullReferenceException: Object reference not set to an instance of an object
GunController+<ReloadTimer>d__26.MoveNext () (at Assets/Scripts/GunController.cs:91)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
GunController:Update() (at Assets/Scripts/GunController.cs:54)

NullReferenceException: Object reference not set to an instance of an object
GunController+<ReloadTimer>d__26.MoveNext () (at Assets/Scripts/GunController.cs:91)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
GunController:Update() (at Assets/Scripts/GunController.cs:54)

該当のソースコード

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

public class GunController : MonoBehaviour
{
    public enum ShootMode { AUTO, SEMIAUTO }

    public bool shootEnabled = true;

    public ShootMode shootMode = ShootMode.SEMIAUTO;
    public int maxAmmo = 30;
    public int damage = 1;
    public float shootInterval = 0.1f;
    public float shootRange = 50;

    public int ModechangeTime = 1;
    public int reloadTime = 2;
    public AmmoGaugeChanger ReloadUIchange;

    public Vector3 muzzleFlashScale;
    public GameObject muzzleFlashPrefab;
    public GameObject hitEffectPrefab;
    public Text trionText;

    public AudioClip FireSound;

    bool shooting = false;
    int ammo = 0;

    GameObject muzzleFlash;
    GameObject hitEffect;

    void Start()
    {
        InitGun();
    }

    void Update()
    {
        trionText.text = Ammo.ToString();
        if (shootEnabled & ammo > 0 & GetInput())
        {
            StartCoroutine(ShootTimer());
        }

        if (Input.GetKey(KeyCode.B))
        {
            StartCoroutine(ChangeShootMode());
        }
        if (Input.GetKey(KeyCode.R))
        {
            StartCoroutine(ReloadTimer());
        }
    }

    public int Ammo
    {
        set
        {
            ammo = Mathf.Clamp(value, 0, maxAmmo);
        }
        get
        {
            return ammo;
        }
    }

    void InitGun()
    {
        Ammo = maxAmmo;
    }

    bool GetInput()
    {
        switch (shootMode)
        {
            case ShootMode.AUTO:
                return Input.GetMouseButton(0);

            case ShootMode.SEMIAUTO:
                return Input.GetMouseButtonDown(0);
        }
        return false;
    }

    IEnumerator ReloadTimer()
    {
        ReloadUIchange.roop = true;

        float NowAmmo = Ammo;
        float OnePlusTime = reloadTime / (float)(maxAmmo - Ammo);

        while(NowAmmo <= Ammo)
        {
            yield return new WaitForSeconds(OnePlusTime);
            NowAmmo += OnePlusTime;
            trionText.text = NowAmmo.ToString();
        }
    }
    IEnumerator ChangeShootMode()
    {
        yield return new WaitForSeconds(ModechangeTime);

        if (shootMode == ShootMode.AUTO)
        {
            shootMode = ShootMode.SEMIAUTO;
        }
        else
        {
            shootMode = ShootMode.AUTO;
        }
    }

    IEnumerator ShootTimer()
    {
        if (!shooting)
        {
            shooting = true;
            if (muzzleFlashPrefab != null)
            {
                if (muzzleFlash != null)
                {
                    muzzleFlash.SetActive(true);
                }
                else
                {
                    muzzleFlash = Instantiate(muzzleFlashPrefab, transform.position, transform.rotation);
                    muzzleFlash.transform.SetParent(gameObject.transform);
                    muzzleFlash.transform.localScale = muzzleFlashScale;
                }
            }
            Shoot();
            yield return new WaitForSeconds(shootInterval);
            if (muzzleFlash != null)
            {
                muzzleFlash.SetActive(false);
            }
            if (hitEffect != null)
            {
                if (hitEffect.activeSelf)
                {
                    hitEffect.SetActive(false);
                }
            }
            shooting = false;
        }
        else
        {
            yield return null;
        }
    }

    void Shoot()
    {
        Ray ray = new Ray(transform.position, transform.forward);
        RaycastHit hit;

        AudioSource fireSE = gameObject.GetComponent<AudioSource>();
        fireSE.clip = FireSound;
        fireSE.Play();

        if (Physics.Raycast(ray, out hit, shootRange))
        {
            if (hitEffectPrefab != null)
            {
                if (hitEffect != null)
                {
                    hitEffect.transform.position = hit.point;
                    hitEffect.transform.rotation = Quaternion.FromToRotation(Vector3.forward, hit.normal);
                    hitEffect.SetActive(true);
                }
                else
                {
                    hitEffect = Instantiate(hitEffectPrefab, hit.point, Quaternion.identity);
                }
            }
        }
        Ammo--;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class AmmoGaugeChanger : MonoBehaviour
{
    public GunController GunCOntroller;
    public Image uiobj;
    public bool roop = false;

    private float reloadtim;
    void Start()
    {
        reloadtim = GunCOntroller.reloadTime;
        uiobj.fillAmount = 0;
    }

    void Update()
    {
        if (roop)
        {
            uiobj.fillAmount -= 1.0f / reloadtim * Time.deltaTime;
        }
    }
}

試したこと

最初OnePlusTimeをintにしていたのですが、DivideByZeroExceptionのエラーを吐いたのでfloatにしてみました、がエラーが出ないだけで動きませんでした。

円のやつを変えるのは下のサイトを参考にしました。
https://clrmemory.com/programming/unity/circle-gauge-meter-p1/#Scene

補足情報(FW/ツールのバージョンなど)

円UIを変えるスクリプトはGunControllerと同じところに入ってます。

↓画面
イメージ説明
↓環境
Unity 2019 2.11f1
Visual Studio 2017 community

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

float OnePlusTime = reloadTime / (float)(maxAmmo - Ammo);は1以上になる時も
ある訳ですから、OnePlusTimeを足すのではなく単にnowAmmoをインクリメントすればどうですか?

while(NowAmmo <= Ammo)
{
       yield return new WaitForSeconds(OnePlusTime);

       NowAmmo++;
       trionText.text = NowAmmo.ToString();
}

2の方は、360度をmax - 残弾数で割った角度に、チャージ分の弾の割合分を足した
(120度が空白で、1発ずつチャージするなら40度)円弧をupdate()で描画するようにしたら良いのではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

check解決した方法

0

インスタンス化していないという初歩的なミスをしていたためできていなかった。円ゲージは数字がぎゅいんってなったらいらなく感じたのでサクジョ。ただ一回しかぎゅいんができないのでこれからなおす。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる