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

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

ただいまの
回答率

87.77%

unity3D スクリプトのboolが全ての複数オブジェクトに反映されてしまう。

解決済

回答 1

投稿 編集

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

score 19

unity3dでの鬼ごっこゲームを作成しております。

プレイヤーと鬼を2対ずつ用意をしているのですが、鬼が1対のプレイヤーを捕まえた際にプレイヤーが二体とも捕まってしまうようになってしまいます。
プレイヤーごとにboolの判定を分けたい場合どのようにすれば良いかアドバイスをいただけますと幸いです。

下記にスクリプトを追加させていただきました。
PlayerController,OniControllerでの実装をしております。
鬼がプレイヤーに近付いたらそのプレイヤーが捕獲されるにしたいと考えております。(実際は他のプレイヤーも所定の場所に飛ばされてしまいます。)

PlayerScripts

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

public class PlayerController : MonoBehaviour
{
   [SerializeField] public OniController anotherScript1;

   void Start()
    {


        anotherScript = GetComponent<UnityStandardAssets.Characters.ThirdPerson.ThirdPersonCharacter>();

        GameObject anotherObject = GameObject.FindWithTag("Oni");
        anotherScript1 = anotherObject.GetComponent<OniController>();


    }

    void Update()
    {
        if (anotherScript1.isRouya == true)
        {
            float rouya_y = 1.5f;

            transform.position = new Vector3(65, rouya_y, 65);

        }
    }




}

OniController

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

public class OniController : MonoBehaviour
{
    //プレイヤーの取得
    List<GameObject> Players = new List<GameObject>();

    public bool isRouya;



    [SerializeField] private Oni.UnityStandardAssets.Characters.ThirdPerson.Oni_ThirdPersonCharacter anotherScript;



    void Start()
    {
        //プレイヤーの取得
        Players.AddRange(GameObject.FindGameObjectsWithTag("Player"));

        anotherScript = GetComponent<Oni.UnityStandardAssets.Characters.ThirdPerson.Oni_ThirdPersonCharacter>();




    }


    public void OnCollisionStay(Collision hit)
    {
        // 接触対象はPlayerタグですか?
        if (hit.gameObject.tag == "Player")
        {
            //Debug.Log("プレイヤーと接触している");

           OnButtonHokaku();

        }

    }

    public void OnButtonHokaku()
    {




        Invoke("Rouya", 0.7f);
        anotherScript.TouchStart();
        Invoke("OnTouchEnd", 0.5f);







    }
     public void Rouya()
    {


        isRouya = true;



    }
   //アニメーションです。
    public void OnTouchEnd()
    {
        anotherScript.TouchEnd();
    }




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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Yukirr4_

    2020/04/18 18:05 編集

    状況があまりわかんないのですが、つまり「捕まったプレイヤーは牢屋に移動され、他の逃げているプレイヤーが外からカギを開けてくれる」ということであってますか?そこで「内側のプレイヤーはそのカギをいじれない」ようにしたいんですよね?

    キャンセル

  • hikaaaaaaaa

    2020/04/18 19:24

    username様

    質問がわかりずらくて申し訳ございません。
    username様に記載していただいた内容で間違いございません。。

    キャンセル

  • Yukirr4_

    2020/04/18 19:49

    了解しました。こちらの理解力が乏しくてすみません…すぐに回答します。

    キャンセル

回答 1

checkベストアンサー

+1

まずプレイヤーのスクリプトに以下を加えます。
以下のスクリプトの名前を仮に「PlayerController」としておきます(自分で作った名前に置き換えてください)

bool isCaptured = false; //捕まっている状態なのか

//捕まったらこれを実行
void Captured()
{
    isCaptured = true;
}

牢屋の判定ボックスのスクリプト

void OnCollisionEnter(Collision collision){
    if(collision.gameObjrct.compareTag("Player"))
   if(collision.GetComponent<PlayerController>().isCaptured == false)
{
  //開放する処理
}
}

つまり、捕まったプレイヤーはisCapturedをtrueにされ、牢屋の検査で引っかかるようにしています。

わからないことがあれば返信ください。

コードが見づらくてすみません。今スマホで書いてるので整理することができません。

追加

複数のゲームオブジェクトを取得する場合、List<GameObject>もしくはGameObject[]を利用します。
これらはGameObjectの集合です。今回はList<>を使用します。

コードの関係があるところだけを書いています。関係のある個所を当てはめていってください。
GameObject Playerは削除しています。

    public class GameController : MonoBehaviour
    {
//プレイヤーオブジェクトの宣言&初期化
    List<GameObject> Players = new List<GameObject>();

    void Start()
    {
        //PlayersにPlayerタグが付いているオブジェクトをすべて入れる(FindGameObjectWithTagではないので注意)
        Players.AddRange(GameObject.FindGameObjectsWithTag("Player"));
    }

    public void OnButtonKaiho()
    {
        Rouya.SetActive(false);
        Debug.Log("牢屋消えた");

        //foreachによりPlayersに入っているオブジェクトの数だけ処理を実行
        foreach(GameObject player in Players)
        {
            player.GetComponent<PlayerController>().isCaptured = false;
            Debug.Log("プレイヤー捕まってない状態");
        }

        Rouya.GetComponent<RouyaScript>().ishelp = false;
        Debug.Log("助ける状態のリセット");
    }
}

複数のオブジェクトを管理する場合、このようにList<>、foreachなどを利用することが多いです。

追加2

鬼でPlayersリストを作成しておく必要はないです。
ただ触れた一つのPlayerオブジェクトを移動させるだけなのですから。

public class PlayerController : MonoBehaviour
{
    public bool isHokaku = false;

    //捕獲されたら呼び出す
    public void Hokaku()
    {
        isHokaku = true;

        /*牢屋に移動*/
    }
}
public class OniController : MonoBehaviour
{
    void OnCollisionEnter(Collision hit)
    {
        if (hit.gameObject.tag == "Player")
        {
            //Debug.Log("プレイヤーと接触している");

            //鬼コントローラーからPlayerのHokaku()を実行
           hit.gameObject.GetComponent<PlayerController>().Hokaku();


           OnButtonHokaku();


        }
    }
}

追記3

触れたときにボタンを表示し、離れたときにボタンを非表示にする。

//鬼コントローラ

//インスペクターから代入する
[SerializeField]
Button Botan;

void OnCollisionEnter(Collision hit)
{
    //表示
    Botan.gameObject.SetActive(true);
}

void OnCollisionExit(Collision hit)
{
    //非表示
    Botan.gameObject.SetActive(false);
}

ただしこれでは鬼が何百体もいたらいちいちボタンを設定することになるので、
それが面倒ならGameControllerからpublicなボタンを一回取得するやり方でいいと思います↓

//GameController.cs

public Button Botan;
//鬼コントローラー

Button Botan;
GameController gameController;
void Start()
{
    this.Botan = gameController.Botan;
}

もしくは検索させることで取得できます↓

//鬼コントローラ

Button Botan;

void Start()
{
    //Botanという名前のオブジェクトを取得し、その中のButtonコンポーネントを代入
    Botan = GameObject.Find("Botan").GetComponent<Button>();
}    

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/04/21 11:44 編集

    OniにisHokakuをつけるより、PlayerにisHokakuをつけたほうがいいと思います。
    そのプレイヤーがisHokakuなのかわかりづらいので。

    おそらく鬼にisHokakuがあるのでそれをtrueにしてしまったら全てのプレイヤーで実行されてしまいます。
    詳しくは回答を編集して書きます。追記2

    キャンセル

  • 2020/04/21 13:41

    ありがとうございます・・。こちらでプレイヤーを別で判定することができました。。

    ちなみに色々試したのですが、プレイヤーに鬼が当たった際に鬼の画面にボタンが出てきて鬼に当たったプレイヤーだけを所定の位置に飛ばすことはできるのでしょうか。。

    現在の場合ですと鬼がプレイヤーに当たった瞬間にプレイヤーが牢屋に転送されてしまうので鬼のボタンでそれを操作したいと考えているのですが、、

    キャンセル

  • 2020/04/21 14:52 編集

    当たった時にボタンを表示し、離れたときにボタンを非表示にすればできると思います。
    回答に追記します。追記3

    キャンセル

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

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

関連した質問

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