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

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

ただいまの
回答率

88.05%

時間制限をつけたいのですが、

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 7,367

score 29

C#スクリプトを使って、3Dのゲーム制作をしています。この数字画像を使って15:00という文字を表示しつつ15:00~00:00となっていくようにして、00:00となったら「タイムアップ!」という文字を出力できるようにしたいのですが、Unity使ってまだ間もないのでまったくもって分からないです・・・。ですので、それができるようなプログラムを押し教えていただけると嬉しいです。
イメージ説明
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Yasha_Wedyue

    2015/05/14 17:38

    問題はなんでしょうか?

    キャンセル

  • Anet

    2015/05/14 17:43

    制限時間を作ろうにもまず、時間をどうやって作るのかがわからず、さらに画像を使って作れと言われているので、それが全く分からないんです・・・。

    キャンセル

回答 5

checkベストアンサー

+1

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

public class TimeCounter : MonoBehaviour {
     
    [SerializeField]
    Image[] images = new Image[4];

    [SerializeField]
    Sprite[] numberSprites = new Sprite[10];
    
    public float timeCount { get; private set; }

    void Start()
    {
        SetTime(900);
    }

    public void SetTime(float time)
    {
        timeCount = time;
        StartCoroutine(TimerStart());
    }

    void SetNumbers(int sec, int val1, int val2)
    {
        string str = String.Format("{0:00}", sec);
        images[val1].sprite = numberSprites[Convert.ToInt32(str.Substring(0,1))];
        images[val2].sprite = numberSprites[Convert.ToInt32(str.Substring(1,1))];
    }

    IEnumerator TimerStart()
    {
        while (timeCount >= 0) {
            int sec = Mathf.FloorToInt(timeCount % 60);
            SetNumbers(sec, 2, 3);
            int minu = Mathf.FloorToInt((timeCount - sec)/ 60);
            SetNumbers(minu, 0, 1);
            yield return new WaitForSeconds(1.0f);
            timeCount -= 1.0f;
        }
        TimeOver();
    }

    void TimeOver()
    {
        TextMesh text = new GameObject().AddComponent<TextMesh>();
        text.text = "Time Over!";        
    }
}


今回はUnityらしい?方法で。
まず、Canvasを使用しています。

CanvasにPanelを1枚、ここに上記のスクリプトを追加。
その子要素としてImageを4枚、Panelに並べて下さい。

インスペクターにImagesとNumberSpritesの配列ができますので、
Imagesを4に子要素として置いたものを左から0,1,2,3に入れて下さい。
NumberSpritesは10、そのまま0~9にそのまま数字を当てはめて下さい。

なんとなく分かるかと思いますが、画像も添付いたします。

![イメージ説明説明][WIDTH:600](8dce8f616b0b15f84088923091746985.png)][WIDTH:600](9b7271c6d2e5ff0de9def76d17d8dc84.png)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/06/15 09:45

    理解力低いせいか、画像通りにどうしても行かないです・・・。

    大変失礼ながら、一から手順を教えていただけるとすごく助かります・・・。

    キャンセル

  • 2015/06/15 09:57

    正確にいうとImage4つをCanvasに入れることができたのですが、そのつぎの10枚の画像を入れるということができないです。

    キャンセル

+1

まず、CanvasにTimeCounterというPanelを用意してます。(名前は別になんでもかまいません)
Penelを出せば、CanvasとPanel、EventSystemが勝手にできます。
で、
そのPanelの子オブジェクトにImageを4枚入れます。
ここまでは大丈夫ですよね?

で、上記スクリプトをTimeCounterにいれます。
そうすると、TimeCounterの中に
ImagesとNumberSpritesという配列ができます。
左についている矢印をおせばサイズを変更する画面が開きます。
そのNumberSpritesの中に数字の画像を入れていけばよいです。

画像が入れれない、という事ですので多分Textureを入れようとしているのだと思います。

画像はSpriteにしてください。
画像ファイルを選ぶと、
Texture Typeという項目があります。
まずこれをSprite(2D and UI)に変更します。
この状態でApplyすると、Textureの子にSpriteができます。
それを入れればよいです。

画像がぼやけていたりすると思いますが、
FilterModeをPointにしてやればぼやけはなくなります。

多分これが原因っぽいですね。




投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/06/15 14:02

    できました!

    あと・・・、まだあるのかよ・・・って感じに質問があるのですが・・・、

    タイマーをキーを押したら増減できるようにしたいのですが・・・、
    そのばあいはどのようにプログラムを変更すればいいですか?
    増やしたい場合のパターンを教えてください・・・。

    キャンセル

  • 2015/06/15 14:12

    あ、すいません・・・、Update作ってif文作ったらできました・・・。

    キャンセル

0

Time.deltaTimeを使うパターンと、
コルーチンを使うパターンが考えられますが、今回の場合はTime.deltaTimeがいいかもしれません。
簡単で初心者向けです。

Time.deltaTimeは前フレームから何秒かかったかを取得できるものです。(単位は秒)
public float timer = 0; 

void Update () {
    timer += Time.deltaTime;
}
こうする事で、timerがストップウオッチのように数字が大きくなっていきます。

質問者さんのやりたい事は、
画像を1秒毎に変更させなければいけないので、
Time.deltaTimeを使って変数[timer]が1.0以上になったら画像を変更させるのがいいでしょう。
この時注意しなければいけないのは、timerは約0.016秒づつ増えていくので(FPSにもよりますが)、ピッタリ1秒になることはありません。
なので
if(timer == 1f)
ではなく、
if(timer >= 1f)
としてください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/06/01 18:00

    15分でやるのでこの場合は合計900フレームで終了するようにすればいいんですかね?

    であと気になったのですがif(timer>=1f)とありますが、このタイマーは毎回0を代入した方がいいですか?

    キャンセル

  • 2015/06/02 09:38

    フレーム数ではなく900秒(1秒×900カウント)ですね。
    timerは毎回0にした方がいいです。

    public float timer = 0;
    private int count = 0;
    void Update () {
    timer += Time.deltaTime;
    if(timer >= 1f && count < 900){
    count++;
    // ここで、countに合わせた画像に張り替え
    timer = 0; // 初期化
    }
    if(count >= 900){
    // タイムアップ処理
    }
    }

    テストしてないので動くかわかりませんが、こんな感じになると思います。

    キャンセル

  • 2015/06/03 14:49

    一応画像処理を抜きにしてこのプログラムを打ったら予定通り

    シーン遷移できました。

    ただ、これを使って画像を使おうとするときまずもって

    どういうプログラムで画像を描画しつつ変換画像をチェンジするようにすればいいですか・・・?

    ヒント一つでもあると大変助かります・・・。

    キャンセル

0

for文に4というマジックナンバーがある事から分かるように、
かなり適当に組みましたので実用性はないですが、

using UnityEngine;
using System.Collections;

// 小数点第三位の四捨五入と文字列のint型変換に使っています。(MathとConvert)
using System;

public class TimeConut : MonoBehaviour {

    Sprite[] sprites;
    GameObject[] number = new GameObject[4];
    float timer = 15;  // 15秒
    bool timeOver = false;

    void Start()
    {

        // 分割したスプライトを読み込んでいます。
        sprites = Resources.LoadAll<Sprite>("Sprites/Number");
        CreateSprites();  
    }

    void Update()
    {
        timer = timer - Time.deltaTime > 0 ? timer - Time.deltaTime : 0;
        if (timer == 0) {
            TimeOver();
            return;
        }

        // timerの値を四捨五入して、文字列に変換しています。
        string t = Math.Round(timer, 2).ToString();
        if (timer < 10) t = "0" + t;

        // 小数点が邪魔なので消します。
        string timeStr = t.Replace(".","");
        for (int i= 0 ; i < timeStr.Length; i++) {

            // 1文字とりだしてint型に変換しています。
            int num = Convert.ToInt32(timeStr.Substring(i, 1));

            // 取り出した数字に画像を変更しています。
            number[i].GetComponent<SpriteRenderer>().sprite = sprites[num];
        }
    }

    void CreateSprites()
    {
        for (int i=0 ; i < 4 ; i++) {
            number[i] = new GameObject();
            number[i].AddComponent<SpriteRenderer>();
            number[i].transform.position = new Vector3(i, 0, 0);
        }
    }

    void TimeOver()
    {
        for (int i =0 ; i < 4 ; i++)
            number[i].GetComponent<SpriteRenderer>().sprite = null;
        if (timeOver) return;
        GameObject obj = new GameObject();
        obj.AddComponent<TextMesh>().text = "Time Over!!";
        timeOver = true;
    }
}

条件と違う事は、数字を1枚にまとめた画像ファイル、それをunityの機能のmaltipleで分割して、
配列の数字と同じになるようにした事ぐらいです。
配列の番号通りに数字の画像を代入しても当然同じ意味になります。画像以外はスクリプトから生成していますので、カメラにでものっければそれだけで画面中央にタイマーっぽいものが動作するはずです。

最初に申し上げた通りかなり適当です。方法論の一つとして提示いたします。どのように画像を変更しているか?はわかるかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/06/10 16:07

    あ、書いてないのであとで訂正します・・・。
    15:00というのは15秒じゃなくて15分なんです・・・。
    その点で修正する場合ってフロート型のタイマーを900にすればいいんですかね?

    キャンセル

0

そうですね。15分にしたいのであれば900にすれば900秒、すなわち15分にはなります。時間は...

ただ、このソースのままで、そのようにするには当然、

秒を分に変換する
表示は秒単位なので、表示も変換する作業が当然必要になります。
また、適当なので3ケタの表示にも対応していませんで、その改造も必要になります。


どのように画像を表示させるか、とタイマーの方法の一つとしての説明させていただいたものです。

そもそも、Unityは関係なく完全にc#のお話なのです。
c#についてある程度理解があれば、好みの問題でかなりのパターンが存在するかと思います。全く違う方法で実装する事も普通に可能です。

15秒についてはテストするのに楽だったので、あえてその方法をとりました。

このままでは何ができないか、どうすれば思ったとおりにできるか?を考える事も重要なんです。
という事は言っておきたいです。


説教っぽくなってるのが嫌なので、近いうちにここで上記画像を使用して15分のタイマーを表示する方法を回答しますね。

ただ、どんな事をしているのか?というのはソースを見て考えてほしいと思います。
そして、他にもいくらでも方法がある、という事も分かって下さい。すぐには理解できなくても、いつの間にか分かるようになってますから、続けていれば。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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