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

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

ただいまの
回答率

88.62%

撃つ弾の切り替えを行いたい

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,786

 前提・実現したいこと

今、unityで横スクロールシューティングゲームを作っています。敵の攻撃手段として、ミサイルと通常弾を発射して攻撃するのですが、振り分けているキーを押すと弾が出るようにしているため、この二つの弾が同時に出てしまいます。通常弾をセットしているときはミサイルが撃てない、といった事をする方法が調べてもよくわかりませんでした。この方法を教えていただきたいです。

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

攻撃手段であるミサイルと通常弾が同時に発射される

 該当のソースコード

ソースコード


Playerにアタッチしているscript
using UnityEngine;
using System.Collections;

public class PlayerScript : MonoBehaviour
{

public float speed = 4f;
public float jumpPower = 700;
public LayerMask groundLayer;
public GameObject mainCamera;
public GameObject bullet;

private Rigidbody2D rigidbody2D;
private Animator anim;
private bool isGrounded;

private Renderer renderer;

void Start()
{
anim = GetComponent<Animator>();
rigidbody2D = GetComponent<Rigidbody2D>();

renderer = GetComponent<Renderer>();
}

void Update()
{
isGrounded = Physics2D.Linecast(
transform.position + transform.up * 1,
transform.position - transform.up * 0.05f,
groundLayer);
if (Input.GetKeyDown("left shift"))
{
if (isGrounded)
{
anim.SetBool("Dash", false);
anim.SetTrigger("Jump");
isGrounded = false;
rigidbody2D.AddForce(Vector2.up * jumpPower);
}
}
float velY = rigidbody2D.velocity.y;
bool isJumping = velY > 0.1f ? true : false;
bool isFalling = velY < -0.1f ? true : false;
anim.SetBool("isJumping", isJumping);
anim.SetBool("isFalling", isFalling);

if (Input.GetKeyDown("space"))
{
anim.SetTrigger("Shot");
Instantiate(bullet, transform.position + new Vector3(0.4f, 1.2f, 0f), transform.rotation);
// ショット音を鳴らす
GetComponent<AudioSource>().Play();
}
}

void FixedUpdate()
{
float x = Input.GetAxisRaw("Horizontal");
if (x != 0)
{
rigidbody2D.velocity = new Vector2(x * speed, rigidbody2D.velocity.y);
Vector2 temp = transform.localScale;
temp.x = x;
transform.localScale = temp;
anim.SetBool("Dash", true);
if (transform.position.x > mainCamera.transform.position.x - 4)
{
Vector3 cameraPos = mainCamera.transform.position;
cameraPos.x = transform.position.x + 4;
mainCamera.transform.position = cameraPos;
}
Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1));
Vector2 pos = transform.position;
pos.x = Mathf.Clamp(pos.x, min.x + 0.5f, max.x);
transform.position = pos;
}
else
{
rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
anim.SetBool("Dash", false);
}
}
void OnCollisionEnter2D(Collision2D col)
{
//Enemyとぶつかった時にコルーチンを実行
if (col.gameObject.tag == "Enemy")
{
StartCoroutine("Damage");
}
}

IEnumerator Damage()
{
//レイヤーをPlayerDamageに変更
gameObject.layer = LayerMask.NameToLayer("PlayerDamage");
//while文を10回ループ
int count = 10;
while (count > 0)
{
//透明にする
renderer.material.color = new Color(1, 1, 1, 0);
//0.05秒待つ
yield return new WaitForSeconds(0.05f);
//元に戻す
renderer.material.color = new Color(1, 1, 1, 1);
//0.05秒待つ
yield return new WaitForSeconds(0.05f);
count--;
}
//レイヤーをPlayerに戻す
gameObject.layer = LayerMask.NameToLayer("Player");
}

}
Playerから出るミサイルのscript
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class PlayerMissile : MonoBehaviour
{

public LayerMask groundLayer;
public GameObject Missile;
public int shotCount;
public Text shellLabel;

private Rigidbody2D rigidbody2D;
private Animator anim;
private bool isGrounded;

void Start()
{
anim = GetComponent<Animator>();
rigidbody2D = GetComponent<Rigidbody2D>();
shellLabel.text = "Missile:" + shotCount;
}

void Update()
{
if (Input.GetKeyDown("e"))
{
if (shotCount < 1)
return;
// ★追加 shotCountの数値を1ずつ減らす。
shotCount -= 1;
// ★追加
shellLabel.text = "Missile:" + shotCount;

anim.SetTrigger("Shot");
Instantiate(Missile, transform.position + new Vector3(0.4f, 1.2f, 0f), transform.rotation);
// ショット音を鳴らす
//GetComponent<AudioSource>().Play();

}

}
public void AddShell(int amount)
{
shotCount += amount;
shellLabel.text = "Missile:" + shotCount;
}
}

 試したこと

武器の切り替えについて調べた。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Gurz1019_MP

    2018/11/26 23:12

    確認なのですが、現状では「Space」を押すと通常弾、「e」を押すとミサイルが発射される、ということであっていますでしょうか? またこれを「e」を押すと武装の切り替え、「Space」で通常弾またはミサイルの発射という形にしたい、ということでしょうか?

    キャンセル

  • Kamizaki_H_ARIA

    2018/11/27 00:27

    はい、どこかのキーを取得し、武器の切り替えを行いたいと考えてます

    キャンセル

回答 2

+2

私が思いついた方法を書きます。なお、PlayerMissileはPlayerScriptと同じGameObjectにアタッチされているものと考えています。

  1. ミサイルと同じように、通常弾を表すコンポーネント(PlayerBullet等)を作る。
    ミサイルと通常弾を同じ”武器”として扱いたいので、ミサイルがコンポーネントとしてPlayerScriptから分離されているなら、通常弾も同じように作ります。StartやUpdateで何もやることがなければ書かなくても構いません。
  2. 武器を表すインターフェイス(IWeapon等)を作り、これに発射を表すメソッド(Fire等)を定義する。
    これらの武器を同じように扱えるようインターフェイスを定義します。これらの武器は”撃つ”ことができるので、この操作をメソッドとして定義します。引数などは必要に応じて定義してください。
  3. PlayerBulletおよびPlayerMissileにIWeaponインターフェイスを実装する。
    ここが重要です。PlayerBulletとPlayerMissileにIWeaponインターフェイスを実装し、それぞれのFireメソッドに、PlayerScriptの通常弾とPlayerMissileのミサイルの発射処理周り(Instantiate周辺)を移動します。キーの判定は不要です。PlayerMissileのUpdateは何もしなくなります。
  4. PlayerScriptに現在装備中の武器を表す変数(currentWeapon等)を定義する。
    PlayerScriptにIWeapon型の変数を定義します。先程作った2つの武器は両方このインターフェイスを実装しているので、この変数には両方のコンポーネントを入れることができます。同時にはどちらか一つしか入りません。
  5. PlayerScriptにプレイヤーが装備可能な武器の一覧を表す変数(Weapons等)を定義する。
    PlayerScriptのStart等で、PlayerBulletコンポーネントとPlayerMissileコンポーネントを取得しておきます。anim等と同じ要領で良いです。型はIWeaponでもPlayerBulletなどでも良いですが、前者であればコレクションが使えます。
  6. 各種初期化
    PlayerScriptのStart等で初期のcurrentWeaponをWaponsから設定します。
  7. 武器を変更
    適当なキーを押したタイミングで、currentWeaponにWeaponsのどれかを代入します。
  8. 撃つ
    適当なキーを押したタイミングで「currentWeapon.Fire()」で撃てます。

こんな感じでしょうか。これで上手く動けば、武器を増やすことも簡単にできます。動作確認ができていないので、不備や不都合があれば返信してください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/27 17:05

    回答ありがとうございます。最近unityとプログラミングを始めたばかりなので、少しずつ調べてやってみます。ありがとうございました。

    キャンセル

checkベストアンサー

0

色々直した方が良い点はありますが多く指摘しても大変そうなので質問だけに答えると、
bool変数でも用意して「どこかのキーを取得」で切り替えて特定の弾しか出せないようにしてしまえば良いかと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/27 16:39

    回答ありがとうございます、他にどのような訂正箇所があるか教えて欲しいです。まだunityを始めたばかりで、サイトを参考に作っていて、どこが変更した方が良いかが分かりません。

    キャンセル

  • 2018/11/27 17:19 編集

    Gurz1019_MPさんが書いている様にクラス設計を見直して可読性と拡張性を改善するのが将来的には大切ですが、個人的にはソースコードをcodeブロックで囲んで投稿してくれれば十分です。

    キャンセル

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

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

関連した質問

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