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

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

ただいまの
回答率

90.32%

  • C#

    7714questions

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

  • Unity

    4432questions

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

raycast unity color

解決済

回答 2

投稿 編集

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

BitCoin

score 45

raycastを飛ばして
当たったオブジェクトの色を変え、2秒程度したら元の色に戻すという処理を実装したいのですが2秒とどめてまたもとに戻すという処理がどのように書けばいいかわかりません。
解決策などあるでしょうか?

public void OnColliderTouchedtouch(){


        if (Input.GetMouseButtonDown(0)){
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    
            RaycastHit hit;

            try{


            if (Physics.Raycast (ray, out hit, Mathf.Infinity, mask)) {


                switch (hit.collider.name) {

                case "actionButton0":

                    hit.collider.GetComponent<MeshRenderer> ().material.color = Color.yellow;



                    gamemadefaultMaterial[0] =  hit.collider.gameObject ;


                    break;

                case "actionButton1":

                    hit.collider.GetComponent<MeshRenderer> ().material.color = Color.blue;
                    gamemadefaultMaterial[1] =  hit.collider.gameObject ;
                    break;

                case "actionButton2":

                    hit.collider.GetComponent<MeshRenderer> ().material.color = Color.yellow;
                    gamemadefaultMaterial[2] =  hit.collider.gameObject ;

                    break;
                }


            } 
            }catch(NullReferenceException e){

            }

        }else {

            try{

            gamemadefaultMaterial[0].GetComponent<MeshRenderer> ().material.color = Color.blue;
            gamemadefaultMaterial[1].GetComponent<MeshRenderer> ().material.color = Color.blue;
            gamemadefaultMaterial[2].GetComponent<MeshRenderer> ().material.color = Color.blue;

            }catch(NullReferenceException ex){

            }
        }

    }


変更後

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class vbScript : MonoBehaviour{

    GameObject[] virtualButtonObject = new GameObject[3];
    GameObject[] _3Dtext = new GameObject[3];
    public TextMesh[] _3DtextInstance = new TextMesh[3];
    Renderer[] virtualButtonMaterial = new Renderer[3];
    int mask = 1 << 8;
    public sample sampleClass;
    GameObject[] gamemadefaultMaterial = new GameObject[3];
    public static int timeSchedulleCount =1 ;
    int colorFlag ;
    void Start () {

        _3DtextInstance [0].text = "1";
        StartCoroutine ("colorWait");
    }

    // Update is called once per frame
    void Update () {

        OnColliderTouchedtouch ();

    }

    public IEnumerator colorWait(){
        yield return new WaitForSeconds (2.0f);
        try{
        switch (colorFlag){
        case 0:

            gamemadefaultMaterial [0].GetComponent<MeshRenderer> ().material.color = Color.blue;

                break;
        case 1 :

            gamemadefaultMaterial[1].GetComponent<MeshRenderer> ().material.color = Color.blue;

                break;

        case 2 :
    gamemadefaultMaterial[2].GetComponent<MeshRenderer> ().material.color = Color.blue;
            break ;

        }

        }catch(NullReferenceException ex){
        }
    }
    public void OnColliderTouchedtouch(){
        if (Input.GetMouseButtonDown(0)){
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    
            RaycastHit hit;

            try{

            if (Physics.Raycast (ray, out hit, Mathf.Infinity, mask)) {


                switch (hit.collider.name) {

                case "actionButton0":

                    hit.collider.GetComponent<MeshRenderer> ().material.color = Color.yellow;

                    if (timeSchedulleCount < 6)
                        timeSchedulleCount++;

                    _3DtextInstance [0].text = timeSchedulleCount + "";

                    gamemadefaultMaterial[0] =  hit.collider.gameObject ;

                    colorFlag =0 ;

                        colorWait() ;

                    break;

                case "actionButton1":

                        hit.collider.GetComponent<MeshRenderer> ().material.color = Color.yellow ;
                    gamemadefaultMaterial[1] =  hit.collider.gameObject ;
                        colorFlag =1 ;

                        colorWait();
                    break;

                case "actionButton2":

                    hit.collider.GetComponent<MeshRenderer> ().material.color = Color.yellow;
                    gamemadefaultMaterial[2] =  hit.collider.gameObject ;
                    if (timeSchedulleCount > 1)
                        timeSchedulleCount--;

                    _3DtextInstance [0].text = timeSchedulleCount + "";

                    colorFlag =2 ;

                        colorWait();
                    break;
                }
            } 
            }catch(NullReferenceException e){

            }

        }else {

            try{

            }catch(NullReferenceException ex){

            }
        }

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

※変更後のソースに対して回答します。

void Start内でStartCoroutineし、その後何もしていない(colorWait()ではコルーチンを呼べない)ので、
「プレイ開始後2秒以内にボタンをタッチすれば色が変わる」というスクリプトになっています。

Startメソッド内のStartCoroutineを削除し、
OnColliderTouchedtouchメソッド内のswitch文内の各colorWait()StartCoroutine ("colorWait");に書き換えてください。

これだけでもボタン1つでなら動作しますが、
「ボタン1を押す(ボタン1が黄色になる)→2秒経つ前にボタン2を押す(ボタン2が黄色になる)→ボタン1を押してから2秒経過→ボタン2が青になる」
という挙動になります。
これはcolorWaitメソッド内で「(2秒経過時点での)colorFlagの状態により色を変える」としている為、最後に押したボタンの色が変わる形となります。

なのでコルーチンにどのボタンかを示す値を直接渡してあげた方がいいです。
(コルーチンはStartCoroutineを実行する度に新しく生成される為、これで正常に動作します)

public IEnumerator colorWait(int buttonId){
    yield return new WaitForSeconds (2.0f);
    try{
    switch (buttonId){
    case 0:
        gamemadefaultMaterial [0].GetComponent<MeshRenderer> ().material.color = Color.blue;
        break;
    //省略
    }

    }catch(NullReferenceException ex){
    }
}


呼び出し側はStartCoroutine ("colorWait", colorFlag);またはStartCoroutine (colorWait(colorFlag));
colorFlagを他で使わないならStartCoroutine ("colorWait", 0);と値を直接渡してももちろん構いません。

(ちなみにこれだけの処理だったら「色が変わっているかどうか」を確認する処理は特に必要無いです。
ただ、毎回GetComponent<MeshRenderer> ()を行うのはあまりスマートでない(負荷がかかる)ので、GameObject[] gamemadefaultMaterialMeshRenderer[] gamemadefaultMaterialにして事前にインスペクターでセットしておけばもっとシンプルになるのではないかと思います。クリティカルな負荷ではないと思うので問題無いと言えば無いですが)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/07 12:51

    おおお!できました!
    ありがとうございます!
    原因はコルーチンを一回のみしか呼び出していなかったからなんですね・・・
    負荷について毎回思っていたのですが
    Update内で毎回GetComponentを呼び出すのはかなり負担になるのでしょうか?

    キャンセル

  • 2017/11/07 13:15

    今回の場合、ボタンが3つだけ、かつタッチされた時だけGetComponentするのでそのままでも大きな問題にはならないと思います。
    (これが毎フレームGetComponentするような形ならやめるべきです)

    ただ、減らせる負荷は減らした方が良いので(チリも積もれば……で後から問題化するケースもあるので)、直せるなら直した方がいいとは思います。

    キャンセル

  • 2017/11/07 14:08

    なるほど。ありがとうございます。

    キャンセル

0

まずどこかに元の色を確保しておきます。

2秒後をどうするかについてですが、
Invoke、Coroutine、Time.deltaTime
これらのどれかを使えば何秒後に関数を使うってことが実現できると思います

強いて言うならCoroutineが関数をそのまま引数で入れてあげられるのでオススメです

Coroutine(関数名);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

IEnumlator 関数名()
{
    yield return new WaitForSeconds(2.0f);//2秒待つ
    色を戻す関数();
}

 

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/06 11:05

    Unity C#ではコルーチンの呼び出しは
    StartCoroutine("関数名"); または StartCoroutine(関数名()); です。
    参考 https://cfm-art.sakura.ne.jp/sys/archives/419

    キャンセル

  • 2017/11/06 14:10 編集

    回答ありがとうございます。
    コルーチンを使い
    colorWait関数を毎回呼び出そうとするのですが
    レイキャストが当たった最初の一回のみ思うような動作をし2回目から2秒まって色を変えるという動作をしなくなってしまいました。
    なぜでしょうか・・

    キャンセル

  • 2017/11/06 16:02 編集

    ```でリンクを囲ってもらえるとソースが読みやすくなるのでありがたいです
    また、使ってない変数や余計な空白も省いてもらえるとありがたいかと

    キャンセル

  • 2017/11/06 16:06

    色を変化させたオブジェクトが色が変わっているかどうかをbool型で管理したほうがわかりやすくなりませんか?

    キャンセル

  • 2017/11/07 00:39

    返信ありがとうございます。
    どうやら返信ではマークダウン機能が使えないみたいで
    質問にコードを追加しました。
    コルーチンが一回しか呼び出せていないのが原因でしょうか?
    bool型で管理するのはよくわかりません。すいません

    キャンセル

  • 2017/11/07 09:34

    ありがとうございます!

    色が変わるオブジェクト自体に、色が変わる関数を入れておいて、レイが当たったら関数を発動する
    それと同時に色が変わってるフラグを立てて、2秒後に元に戻す
    といった具合です

    キャンセル

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

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

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

  • C#

    7714questions

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

  • Unity

    4432questions

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