オブジェクトの画像張り替えスクリプトについて

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,077

Dawei

score 8

前提・実現したいこと

メインカメラにアタッチするスクリプトで、ボタンを押したらx座標が更新されてx座標が300を超えたら0に戻り、0に戻った時に対象のオブジェクト(今回は球体)の画像を張り替えるスクリプトを組もうと思っているのですが、とりあえずで組んだswitch文すら動かなくて困っています。↓の二つのエラーを検索してみてもいまいちよくわからず…
それと張り替える画像が数百枚単位になってしまうためいちいちcase1、case2と書いていくのはかなり手間がかかりそうなのですが何かいい方法はないでしょうか?

参考にしたサイトです
http://qiita.com/ntkgcj/items/61faa07e5a24c59fa950

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

FindGameObjectsWithTag can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
UnityEngine.GameObject:FindGameObjectsWithTag(String)
mvcam:.ctor()

ArgumentException: FindGameObjectsWithTag can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
mvcam..ctor ()

該当のソースコード

using UnityEngine;
using System.Collections;

public class mvcam : MonoBehaviour
{
    public Vector3 pos = new Vector3(-11, 0, 0);
    const string BASE_TEXTURE = "Textures/gazou";

    //テクスチャを貼りたいゲームオブジェクトの配列生成(タグ名は「SphereObject」)
    GameObject[] spriteObjects = GameObject.FindGameObjectsWithTag("SphereObject");

    //スプライト画像の配列生成(テクスチャ画像の読み込み)
    Sprite[] sprites = Resources.LoadAll<Sprite>(BASE_TEXTURE);

    // Use this for initialization 
    void Start()
    {
        pos = transform.position;  //位置保持 

    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && pos.x < 300)
        { //spaceキーの入力があり、かつx座標が300以下の場合にという条件文
            pos.x += 30; //x座標を+30する(移動する)
            transform.position = pos;  //位置更新
            print(transform.position.x); //コンソールを開くと座標が今どこにいるのかわかるのか書いてくれる
        }
        else if (Input.GetKeyDown(KeyCode.Space) && pos.x >= 300)
        {
            pos.x = 0;
            transform.position = pos;
            print(transform.position.x);

            foreach (GameObject sp in spriteObjects)
            {
                //ゲームオブジェクトのスプライトレンダラ設定を取得
                SpriteRenderer spObRender = sp.GetComponent<SpriteRenderer>();

                //別スクリプトの変数を取得
                //(スクリプト名は「SpriteObjectNumber」、変数名は「spObNum」)
                int textureUniqueNumber = sp.GetComponent<SpriteObjectNumber>().spObNum;

                //switch文で、textureUniqueNumber の数字によって処理(貼るテクスチャ)を変える
                switch (textureUniqueNumber)
                {
                    case 1:
                        spObRender.sprite = sprites[0];
                        break;
                    case 2:
                        spObRender.sprite = sprites[1];
                        break;
                }
            }
        }
    }
}

張り替える対象オブジェクトに付けるスクリプト↓
using UnityEngine;
using System.Collections;

public class SpriteObjectNumber : MonoBehaviour
{

    public int spObNum;

    public void Start()
    {
    }

}

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

C#です。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

Switch文の簡略化の方は、見た限り連番っぽい?ので

spObRender.sprite = sprites[textureUniqueNumber-1];


とかにすればいけるのではないでしょうか?

後、
GameObject[] spriteObjects = GameObject.FindGameObjectsWithTag("SphereObject");
Sprite[] sprites = Resources.LoadAll<Sprite>(BASE_TEXTURE);
これらはできません。初期化はStart関数の中に移してください。
(プログラムを実際に動かすまで結果がわからない処理はメンバ変数の初期化には使えない)

GameObject[] spriteObjects;
Sprite[] sprites;
void Start()
{
    spriteObjects = GameObject.FindGameObjectsWithTag("SphereObject");
    sprites = Resources.LoadAll<Sprite>(BASE_TEXTURE);
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/11 16:06

    今度は別のエラーが出ました…

    MissingComponentException: There is no 'SpriteRenderer' attached to the "Sphere100" game object, but a script is trying to access it.
    You probably need to add a SpriteRenderer to the game object "Sphere100". Or your script needs to check if the component is attached before using it.
    UnityEngine.SpriteRenderer.set_sprite (UnityEngine.Sprite value) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/SpritesBindings.gen.cs:238)
    mvcam.Update () (at Assets/Script/mvcam.cs:54)

    該当箇所は
    spObRender.sprite = sprites[0];
    です。

    キャンセル

  • 2016/10/11 16:27

    SphereObjectのTagが付いたコンポーネントの設定がどうなっているかわからないので、ちょっとアドバイスしにくいです。
    当初とは大分問題の内容も変わってきたので、ここいらで一旦打ち切って新しく質問を投げるとよいと思います。
    その際はSphereObjectのTagが付いたコンポーネントの設定(インスペクタの画面)を画像として添付すると良い回答が得られると思います。(見つけたら私の方も回答してみます)

    キャンセル

  • 2016/10/11 16:30

    わかりました。いろいろ付き合っていただきありがとうございました。

    キャンセル

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

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