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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

999閲覧

1つのスクリプトで複数のオブジェクトを削除したい

Aya7

総合スコア14

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/07/12 06:43

前提・実現したいこと

3Dの的あてゲームを作ろうと思っています。その的を作っています。下から浮き上がって球を当てたらオブジェクトを消すというものです。一つのスクリプトにUnity上で設定できる値にして複数のオブジェクトに着けて動かすようにしたいです。

1つのオブジェクトに弾が当たるとほかのこのスクリプトがついているものオブジェクトまで消えてしまいます。Invoke()のほうでは別々に消えることを確認しています。

当たったときにその当たったオブジェクトを一つだけを消すことはできますか。

Unity初心者なのでコードが残念なことがたくさんあると思います。申し訳ない。

キューブの一つを撃つと両方消えてしまう。
イメージ説明

オブジェクトのソースコード

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Target : MonoBehaviour { Vector3 startPosition, targetPosition; private Vector3 velocity = Vector3.zero; public float time = 1F; public float X = 0; public float Y = 0; public float Z = 0; public GameObject target; public float DestroyTimer = 0f; GameObject Gun; void Start() { Gun = GameObject.Find("GunController"); Gun.GetComponent<FirstPersonGunController>(); targetPosition = new Vector3(X, Y, Z); } private void HIT() { //弾が当たるとtrueになる if (Gun.GetComponent<FirstPersonGunController>().H == true) { Destroy(target.gameObject); } else { Invoke("Destroy", DestroyTimer); } } public void Destroy() { Destroy(target.gameObject); } void Update() { transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, time); HIT(); } }

銃のソースコード:参考コード

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using KszUtil; public class FirstPersonGunController : MonoBehaviour { public enum ShootMode { AUTO, SEMIAUTO } public bool shootEnabled = true; [SerializeField] ShootMode shootMode = ShootMode.AUTO; [SerializeField] int maxAmmo = 100; [SerializeField] int maxSupplyValue = 100; [SerializeField] float shootInterval = 0.1f; [SerializeField] float shootRange = 50; [SerializeField] float supplyInterval = 0.1f; [SerializeField] Vector3 muzzleFlashScale; [SerializeField] GameObject muzzleFlashPrefab; [SerializeField] GameObject hitEffectPrefab; [SerializeField] Image ammoGauge; [SerializeField] Text ammoText; [SerializeField] Image supplyGauge; [SerializeField] private SmoothTransform aHandGun; [SerializeField] private SmoothTransform bHandGun; bool shooting = false; bool supplying = false; public bool H = false; int ammo = 0; int supplyValue = 0; GameObject muzzleFlash; GameObject hitEffect; public int Ammo { set { ammo = Mathf.Clamp(value, 0, maxAmmo); //UIの表示を操作 //テキスト ammoText.text = ammo.ToString("D3"); //ゲージ float scaleX = (float)ammo / maxAmmo; ammoGauge.rectTransform.localScale = new Vector3(scaleX, 1, 1); } get { return ammo; } } public int SupplyValue { set { supplyValue = Mathf.Clamp(value, 0, maxSupplyValue); if (SupplyValue >= maxSupplyValue) { Ammo = maxAmmo; supplyValue = 0; } float scaleX = (float)supplyValue / maxSupplyValue; supplyGauge.rectTransform.localScale = new Vector3(scaleX, 1, 1); } get { return supplyValue; } } void Start() { InitGun(); } void Update() { if (shootEnabled & ammo > 0 & GetInput()) { StartCoroutine(ShootTimer()); } if (shootEnabled) { StartCoroutine(SupplyTimer()); } ADS(); } public void InitGun() { Ammo = maxAmmo; SupplyValue = 0; } bool GetInput() { switch (shootMode) { case ShootMode.AUTO: return Input.GetMouseButton(0); case ShootMode.SEMIAUTO: return Input.GetMouseButtonDown(0); } return false; } IEnumerator ShootTimer() { if (!shooting) { shooting = true; //マズルフラッシュON if (muzzleFlashPrefab != null) { if (muzzleFlash != null) { muzzleFlash.SetActive(true); } else { muzzleFlash = Instantiate(muzzleFlashPrefab, transform.position, transform.rotation); muzzleFlash.transform.SetParent(gameObject.transform); muzzleFlash.transform.localScale = muzzleFlashScale; } } Shoot(); yield return new WaitForSeconds(shootInterval); //マズルフラッシュOFF if (muzzleFlash != null) { muzzleFlash.SetActive(false); } //ヒットエフェクトOFF if (hitEffect != null) { if (hitEffect.activeSelf) { hitEffect.SetActive(false); } } shooting = false; } else { yield return null; } } public void Shoot() { Ray ray = new Ray(transform.position, transform.forward); RaycastHit hit; //レイを飛ばして、ヒットしたオブジェクトの情報を得る if (Physics.Raycast(ray, out hit, shootRange)) { //ヒットエフェクトON if (hitEffectPrefab != null) { if (hitEffect != null) { hitEffect.transform.position = hit.point; hitEffect.transform.rotation = Quaternion.FromToRotation(Vector3.forward, hit.normal); hitEffect.SetActive(true); } else { hitEffect = Instantiate(hitEffectPrefab, hit.point, Quaternion.identity); } } string tagName = hit.collider.gameObject.tag; if (tagName == "Enemy") { EnemyController enemy = hit.collider.gameObject.GetComponent<EnemyController>(); HIT(); } } Ammo--; } IEnumerator SupplyTimer() { if (!supplying) { supplying = true; SupplyValue++; yield return new WaitForSeconds(supplyInterval); supplying = false; } } void ADS() { if (Input.GetMouseButtonDown(1)) { //transform.positionではなく、TargetPositionに var aPos = aHandGun.TargetPosition; var bPos = bHandGun.TargetPosition; bHandGun.TargetPosition = aPos; aHandGun.TargetPosition = bPos; } else if(Input.GetMouseButtonUp(1)) { var aPos = aHandGun.TargetPosition; var bPos = bHandGun.TargetPosition; bHandGun.TargetPosition = aPos; aHandGun.TargetPosition = bPos; } } void HIT() { H = true; } }

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

Unity 2020.3.4f1

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

銃とターゲットの関係性を見直すと良いでしょう。
流れを考えると、銃→ターゲットの関係性になるべきですが。現状は銃←ターゲットになっています。

なぜかというと、ターゲット側が銃側のステータスを読みにいっていますよね。
銃側のHtrueなら自分をDestroyしてしまいます。
しかし、この条件って自分に当たったかどうかまではチェックしてないです。
なので銃側でHtrueになった瞬間、すべてのターゲットはDestroyされます。

cs

1private void HIT() 2 { 3 //弾が当たるとtrueになる 4 if (Gun.GetComponent<FirstPersonGunController>().H == true) 5 { 6 Destroy(target.gameObject); 7 } 8 else 9 { 10 Invoke("Destroy", DestroyTimer); 11 } 12 }

設計にもよりますが、まずはシンプルに考えて整理してみるのも良いかもしれません

【銃】    ターゲットにヒットするなら、ターゲットに「お前当たったよ」と教えてあげる
【ターゲット】ヒットしたら自分はどうするべきかの振る舞いを行う

・銃のRaycast側
適宜調整してほしいですが、EnemyタグであればTargetコンポーネントの取得を行います。
そしてコンポーネントが見つかればHitメソッドを呼んで「お前当たった」と教えてあげます

cs

1 if (tagName == "Enemy") 2 { 3 var _target = hit.collider.gameObject.GetComponent<Target>(); 4 if(_target != null)_target.HIT(); 5 }

・ターゲット側
当たったかどうかは銃側が教えてくれるので、HITメソッドでは単純に自分をDestroyする処理だけを書いています。

cs

1 public void HIT() 2 { 3 Destroy(gameObject); 4 }

投稿2021/07/13 02:29

編集2021/07/13 02:30
hogefugapiyo

総合スコア3302

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Aya7

2021/07/13 12:34

本当にありがとうございます。うまく動かすことが出来ました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問