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

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

ただいまの
回答率

90.47%

  • C#

    9246questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    5661questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1860questions

    Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

【Unity】変数が瞬間的に大きな負の値になってしまう。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 870
退会済みユーザー

退会済みユーザー

Substring関数を使ったところ、Cannot be negativeというエラーが出てしまい、Substring関数に用いている引数を調べたところ、瞬間的に非常に大きな負の値になってそのあとは普通の挙動をしているのがわかりました。
ですが、なぜ、どこの問題でこの値になっているかが分かりません。
問題の変数は int displayCharacterCountです。イメージ説明

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

public class UIControl : MonoBehaviour {
    public Text uiText;    //Textへの参照.
    private GameObject panel;    //Panaelを格納.
    public Button speakbutton;    //話すボタンを参照.
    private bool friend_finEvent,x_finEvent,player1_finEvent;    //初回のイベントが終わったか.
    public string[] strArray_ff;    //セリフを格納.
    public string[] strArray_fs;
    public string[] strArray_xf;
    public string[] strArray_xs;
    public string[] strArray_pf;
    public string[] strArray_ps;
    private PlayerControl pc;
    [SerializeField][Range(0.001f,0.3f)]
    float intervalForCharacterDisplay = 0.05f;    //1文字の表示にかかる時間.

    private enum STEP    //会話時のステータス.
    {
        NONE = -1,
        FriendFirst = 0,
        FriendSecond,
        XFirst,
        XSecond,
        Player1First,
        Player1Second,
        NUM,
    };
    STEP now_step;

    private int currentLine = 0;    //現在の行数.
    private string currentText = string.Empty;    //現在の文字列.
    private float timeUntilDisplay = 0;    //表示にかかる時間.
    private float timeElapsed = 1;    //文字列の表示を開始した時間.
    private int lastUpdateCharacter = -1;    //表示中の文字数.

    // Use this for initialization
    void Start () {
        panel = GameObject.FindGameObjectWithTag ("Panel");    //panelを取得.
        close_display();
        pc = GameObject.FindGameObjectWithTag ("Player").GetComponent<PlayerControl> ();
    }

    // Update is called once per frame
    void Update () {
        if (IsCompleteDisplayText) {
            switch (now_step) {    //ボタンが押されたら次のセリフ。最後のセリフがおわったらパネルを閉じる.
            case STEP.NONE:
                break;
            case STEP.FriendFirst:
                if (currentLine < strArray_ff.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_ff [currentLine]);
                } else if (currentLine == strArray_ff.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            case STEP.FriendSecond:
                if (currentLine < strArray_fs.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_fs [currentLine]);
                } else if (currentLine == strArray_fs.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            case STEP.XFirst:
                if (currentLine < strArray_xf.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_xf [currentLine]);
                } else if (currentLine == strArray_xf.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            case STEP.XSecond:
                if (currentLine < strArray_xs.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_xs [currentLine]);
                } else if (currentLine == strArray_xs.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            case STEP.Player1First:
                if (currentLine < strArray_pf.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_pf [currentLine]);
                } else if (currentLine == strArray_pf.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            case STEP.Player1Second:
                if (currentLine < strArray_ps.Length && Input.GetMouseButtonDown (0)) {
                    setString (strArray_ps [currentLine]);
                } else if (currentLine == strArray_ps.Length && Input.GetMouseButtonDown (0)) {
                    close_display ();
                }
                break;
            }
        } else {
            if (Input.GetMouseButtonDown (0))
                timeUntilDisplay = 0;
        }

        int displayCharacterCount =
            (int)(Mathf.Clamp01 ((Time.time - timeElapsed) / timeUntilDisplay) *
            currentText.Length);    //経過時間の%分の文字数.
        Debug.Log(displayCharacterCount);

        if (displayCharacterCount != lastUpdateCharacter) {    //文字数が更新されてたら.
            uiText.text = currentText.Substring (0, displayCharacterCount);//表示文字数を更新.
            lastUpdateCharacter = displayCharacterCount;    //現在の文字数を保管.
        }
    }

    void set_display(){    //パネルを表示.
        panel.gameObject.SetActive (true);
        speakbutton.interactable = false;
    }

    void setString(string str){    //セリフを次に変更.
        currentText = str;
        currentLine++;

        timeUntilDisplay = currentText.Length * intervalForCharacterDisplay;//文字列の表示にかかる時間を保管.
        timeElapsed = Time.time;    //現在の時間を保管.

        lastUpdateCharacter = -1;
    }

    void close_display(){    //パネルを非表示.
        panel.gameObject.SetActive (false);
        speakbutton.interactable = true;
    }

    public void On_Speak_Button(){    //話すボタンが押されたら、
        Debug.Log("正常動作1");
        switch (pc.closest) {    //近くの人が誰か,初回かどうかによってイベントを発生させる.
        case PlayerControl.CLOSEST.NONE:
            break;
        case PlayerControl.CLOSEST.FRIEND:
            Debug.Log ("正常動作2");
            if (!friend_finEvent) {
                friendFirstEvent ();
                friend_finEvent = true;
            } else {
                friendSecondEvent ();
            }
            break;
        case PlayerControl.CLOSEST.X:
            if (!x_finEvent) {
                xFirstEvent ();
                x_finEvent = true;
            } else {
                xSecondEvent ();
            }
            break;
        case PlayerControl.CLOSEST.PLAYER1:
            if (!player1_finEvent) {
                player1FirstEvent ();
                player1_finEvent = true;
            } else {
                player1SecondEvent ();
            }
            break;
        }
    }

    void friendFirstEvent(){    //友達の初回イベント発生.
        set_display ();    //パネル表示.
        now_step = STEP.FriendFirst;    //現在の状態を保管.
        currentLine = 0;
        setString (strArray_ff [currentLine]);    //文字列を表示.
    }

    void friendSecondEvent(){
        set_display ();
        now_step = STEP.FriendSecond;
        currentLine = 0;
        setString (strArray_fs [currentLine]);
    }

    void xFirstEvent(){
        set_display ();
        now_step = STEP.XFirst;
        currentLine = 0;
        setString (strArray_xf [currentLine]);
    }

    void xSecondEvent(){
        set_display ();
        now_step = STEP.XFirst;
        currentLine = 0;
        setString (strArray_xs [currentLine]);
    }

    void player1FirstEvent(){
        set_display ();
        now_step = STEP.Player1First;
        currentLine = 0;
        setString (strArray_pf [currentLine]);
    }

    void player1SecondEvent(){
        set_display ();
        now_step = STEP.Player1Second;
        currentLine = 0;
        setString (strArray_ps [currentLine]);
    }

    bool IsCompleteDisplayText{    //全ての文字を表示したかどうか.
        get{ return Time.time > timeElapsed + timeUntilDisplay; }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

int displayCharacterCount

を計算している所でマイナスの値が入っているだけだと思いますが、
そもそも計算に使っている値で計算した場合にマイナスにならない保証があるのでしょうか?

単純に if(displayCharacterCount > 0) という条件式を加えてもいい気がしますが。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/06 01:06

    おそらくcurrentTextの初期値のstringEmptyにより極小の値を取っていると思われると結論づけました。おっしゃる通り、if文で分岐させてしまおうと思います。ありがとうございました。

    キャンセル

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

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

同じタグがついた質問を見る

  • C#

    9246questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    5661questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1860questions

    Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。