2017-05-20 15 views
1

私が抱えている問題は、落としたアイテムに銃に弾薬を加えることです。FindObjectOfTypeがnullを返す

すべてのメソッドと変数でGunクラスを構築しました。 はライフルが、私は今、敵のx量はピックアップをドロップする「ピック」システムを追加してい完璧な問題なし

作品 銃クラスから派生ライフルクラスを内蔵します。

この

public class AddARAmmo : MonoBehaviour 
{ 
    private Rifle rifle; 
    private void Awake() 
    { 
     rifle = FindObjectOfType<Rifle>(); 
    } 
    private void OnTriggerEnter(Collider other) 
    { 
     if (other.tag == string.Format("Player")) 
     { 
      rifle.AddAmmo(30); 
      Destroy(gameObject); 
     } 

    } 
} 

をピックアップする項目のスクリプトライフル銃のスクリプトは一種の長いですが、ここでは関係のものがガンの基本クラスからでは、パブリック抽象クラスです..... 。

ライフルクラスで次に
public int bulletsInStock; 
public void AddAmmo(int ammoToAdd) 
{ 
    bulletsInStock += ammoToAdd; 
    UpdateAmmo();// updates on screen Ammo 
} 
...... 

public override void Modifiers() // This is where the guns starts are stored 
{ 
    bulletSpeed = 2777f; 
    bulletsInStock = 200; 
    bulletsInMag = 30; 
    bulletPoolSize = 40; 
    desiredRPS = 15; 
    muzzleFlashPoolSize = 10; 
} 

私は設定していないオブジェクト参照を取得していますインスタンスに

ライフルスクリプトはゲーム階層のライフルにあるので、それを見つけるはずです。 誰かが間違っていると思っていますか?

のは、スクリプト名を言ってみましょう:ここ

がフル銃スクリプト

public abstract class Gun : MonoBehaviour 
{ 
    [SerializeField] protected GameObject muzzleFlash;// spawns on barrelEnd 
    [SerializeField] protected Transform muzzleFlashFolder; 
    [SerializeField] protected Transform bulletFolder;// is the parent of bullets 
    [SerializeField] protected Transform barrelEnd;// Gameobject at the end of barrel 
    [SerializeField] protected Rigidbody bullet; // The bullet Prefab 
    [SerializeField] protected Text ammo; // OSD 
    [SerializeField] protected Text weaponType; // OSD 
    [HideInInspector] protected float bulletSpeed; 
    [HideInInspector] public int bulletsInStock; 
    [HideInInspector] protected int bulletsInMag; 
    [HideInInspector] protected float desiredRPS;// Rounds Per Second 
    [HideInInspector] protected List<Rigidbody> poolOfBullets; // Make pool for bullets 
    [HideInInspector] protected int bulletPoolSize; // The size off the buletpool 10 works really well 
    [HideInInspector] protected List<GameObject> muzzleFlashPool;// pool for muzzleflash 
    [HideInInspector] protected int muzzleFlashPoolSize; // size of the muzzle pool 
    [HideInInspector] protected int bulletsLeft; // In mag 
    [HideInInspector] protected bool isReloading = false; 
    [HideInInspector] protected float timeLeft;// for fire speed 
    [HideInInspector] protected float fireSpeedTimer; 
    [HideInInspector] protected Weapons weaponsScript; 
    [HideInInspector] protected PlayerController playerController; 
    protected void FixedUpdateStuff() 
    { 
     if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) > 0) 
     { 
      FireSpeedControl();// call the fire timer controller 
     } 
     if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) == 0) 
     { 
      timeLeft = 0f; 
     } 
     if (playerController.canMove && Input.GetKeyDown(KeyCode.R) && !isReloading) 
     { 
      Reload(); 
     } 
     UpdateAmmoOnInput(); 
    } 
    protected void UpdateStuff() 
    { 
     if (gameObject.activeInHierarchy)// when a gun become active it updates OSD 
     { 
      UpdateWeaponType();// With its Name 
     } 
    } 
    protected void RPSFinder()// finds the Rounds Per Second the gun will fire 
    { 
     fireSpeedTimer = (100/desiredRPS)/100; 
     timeLeft = fireSpeedTimer; 
    } 

    protected void Fire()// Instatiates a clone of the desired bullet and fires it at bulletSpeed 
    { 
     if (!Empty()) 
     { 
      Rigidbody bulletClones = GetPooledBullet(); 
      if (bulletClones != null) 
      { 

bulletClones.transform.SetPositionAndRotation(barrelEnd.position, barrelEnd.rotation); 
       bulletClones.gameObject.SetActive(true); 
      } 
      GameObject muzzleFlashClone = GetMuzzleFlash(); 
      if (muzzleFlashClone != null) 
      { 
       muzzleFlashClone.transform.position = barrelEnd.position; 
       muzzleFlashClone.gameObject.SetActive(true); 
      } 
      bulletClones.AddForce(-bulletClones.transform.up * bulletSpeed * .304f); //add the force in FPS * .304 = MPS 
      bulletsLeft--;// the holder to know how many bullets are left in the magazine 
      isReloading = false;// Gun cannot reload unless it has been fired 
      UpdateAmmo();// Updates the on screen ammo count and the stock usage 
      return; 
     } 
    } 

    protected void Reload() 
    {// this removes full magazine from the stock and the stock can still go negitive FIX FIX FIX FIX FIX FIX FIX 
     if (bulletsInStock > 0) 
     { 
      isReloading = true; 
      bulletsInStock -= bulletsInMag; 
      bulletsLeft = bulletsInMag; 
      UpdateAmmo(); 
     } 
    } 

    protected bool Empty()// Checks the magazine to see if there are bullets in it 
    { 
     if (bulletsLeft == 0) 
      return true; 
     else 
      return false; 
} 

    protected void FireSpeedControl()// controls the RPS fired by the gun Controled by Update() Input 
    { 
     if (timeLeft > 0f) 
     { 
      timeLeft -= Time.deltaTime; 
     } 
     else if (timeLeft <= 0f) 
     { 
      Fire(); 
      timeLeft = fireSpeedTimer; 
     } 
    } 

    protected Rigidbody GetPooledBullet()// retrieve a preInstatiated bullet from the pool to use when shooting 
    { 
     for (int i = 0; i < poolOfBullets.Count; i++) 
     { 
      if (!poolOfBullets[i].gameObject.activeInHierarchy) 
      { 
       return poolOfBullets[i]; 
      } 
     } 
     return null; 
    } 

    protected GameObject GetMuzzleFlash() 
    { 
     for (int i = 0; i < muzzleFlashPool.Count; i++) 
     { 
      if (!muzzleFlashPool[i].gameObject.activeInHierarchy) 
      { 
       return muzzleFlashPool[i]; 
      } 
     } 
     return null; 
    } 

    protected void UpdateAmmo()// Update the on screen ammo information 
    { 
     ammo.text = bulletsLeft + string.Format(" : ") + bulletsInStock; 
    } 

    protected abstract void UpdateWeaponType(); 

    protected void UpdateAmmoOnInput() 
    { 
     if (weaponsScript.updateAmmo) 
     { 
      UpdateAmmo(); 
      weaponsScript.updateAmmo = false; 
     } 
    } 


    public abstract void Modifiers(); 

    protected void StartStuff() 
    { 
     Modifiers();// Call first to store indvidual gun stats 
     playerController = FindObjectOfType<PlayerController>(); 
     weaponsScript = FindObjectOfType<Weapons>(); 
     poolOfBullets = new List<Rigidbody>(); 
     for (int i = 0; i < bulletPoolSize; i++) 
     { 
      Rigidbody bulletClone = (Rigidbody)Instantiate(bullet); 
      bulletClone.gameObject.SetActive(false);// Builds the Inspector list 
      poolOfBullets.Add(bulletClone); //and populates the elements with clones 
      bulletClone.transform.parent = bulletFolder.transform; 
     } 
     muzzleFlashPool = new List<GameObject>(); 
     for (int i = 0; i < muzzleFlashPoolSize; i++) 
     { 
      GameObject muzzleFlashClone = (GameObject)Instantiate(muzzleFlash); 
      muzzleFlashClone.gameObject.SetActive(false); 
      muzzleFlashPool.Add(muzzleFlashClone); 
      muzzleFlashClone.transform.parent = muzzleFlashFolder.transform; 
     } 
      bulletsLeft = bulletsInMag; 
      ammo.text = string.Format(" 0 : 0 "); 
      RPSFinder();// Run last to set the RPS of the gun 
     } 
     public void AddAmmo(int ammoToAdd) 
     { 
      bulletsInStock += ammoToAdd; 
      UpdateAmmo(); 
     } 

    } 
} 

、ここでは、完全なライフルスクリプト

public class Rifle : Gun 
{ 
    //All variables are stored in the "Gun" Script 
    //Copy this onto guns 

    void Start() 
    { 
     StartStuff(); 
    } 
    private void FixedUpdate() 
    { 
     FixedUpdateStuff(); 
    } 

    void Update() 
    { 
     UpdateStuff(); 
    } 

    public override void Modifiers() // This is where the guns starts are stored 
    { 
     bulletSpeed = 2777f; 
     bulletsInStock = 200; 
     bulletsInMag = 30; 
     bulletPoolSize = 40; 
     desiredRPS = 15; 
     muzzleFlashPoolSize = 10; 
    } 

    protected override void UpdateWeaponType() 
    { 
     weaponType.text = string.Format("Assault Rifle"); 
    } 


} 
+0

はあなたが私たちに 'Rifle'スクリプトを表示することができますか?役に立てば幸い – Programmer

+1

_例外はスローされますか? – Abion47

+0

rifle.AddAmmo(30); AddARAmmoスクリプト – Melsy

答えて

3

であるFindObjectOfTypeがnullを返す場合があります3つの理由があります。見つけられるのはRifle

そしてFindObjectOfType<Rifle>()nullです。

選択図ゲームオブジェクトRifleスクリプトがインアクティブであるために取り付けられています。 GameObjectがアクティブであることを確認する必要があります。 enter image description here

。ライフルはゲームオブジェクトには一切付属していません。 RifleスクリプトがGameObjectに添付されていることを確認してください。 enter image description here

スクリプトが有効か無効かは関係ありませんが、それが接続されているGameObjectがアクティブである限り、スクリプトが見つかるはずです。 #1を参照してください。新しいシーンをロード

.When:あなたは、このようなSceneManager.LoadSceneApplication.LoadLevelなどの機能をロードするシーンをトリガーすると

FindObjectOfTypeシーンはそれが行わロードまで、何かを見つけることができません。

シーンのロードが完了したときの確認方法は、hereを参照してください。


あなたはまだあなたが、単にゲームオブジェクトは、それからRifleコンポーネントを取得見つけてはならない問題がある場合。 GameObjectの名前が"ライフル"であると仮定します。

GameObject.Find("Rifle").GetComponent<Rifle>(); 
+0

シーンが読み込まれている間、ゲームオブジェクトはアクティブではありません。しかし、私が参照を呼び出すと、オブジェクトはアクティブまたは非アクティブになり、nullになります。しかし、私はこれを念頭に置いていくつかのテストを行うでしょう – Melsy

+0

私は銃が無効になった直前に銃を止めるセクションを持っていました。場合によっては、基本に戻る必要があります。 – Melsy

+0

ええ、インアクティブが起こった理由です。あなたが問題を発見してうれしい。 – Programmer

0

私は同様の問題を抱えている人にこれを解決する方法を考え出しました。 問題は、敵がアイテムを落としたときで、Awake()メソッドが実行されたときです。それが実行されたときに銃がシーン内で非アクティブだったので、FindObjectOfTypeは参照スクリプトを見つけられませんでした。なぜなら、上で述べたように、見つかるシーンでアクティブでなければならないからです。

私はEnemyDropsと呼ばれるホルダースクリプトを作成しました。このスクリプトはgunのfindobjectoftypesを呼び出します。そうすれば、最初の試合開始時にコールが行われます。

その後、ピックアップを変更してEnemyDropsスクリプト(空のゲームオブジェクトにあります)を見つけ、その呼び出しを送信します。

EnemyDropsスクリプト

private Handgun handgun; 

private void Awake() 
{ 
    handgun = FindObjectOfType<Handgun>(); 
} 

public void AddHandgunAmmo(int x) 
{ 
    handgun.AddAmmo(x); 
} 

と新しいピックアップスクリプトあなたがそれを見ることができるように

public class AddHandgunAmmo : MonoBehaviour 
{ 
    private EnemyDrops enemyDrops; 
    private void Awake() 
    { 
     enemyDrops = FindObjectOfType<EnemyDrops>(); 
    } 

    private void OnTriggerEnter(Collider other) 
    { 
     if (other.tag == string.Format("Player")) 
     { 
      enemyDrops.AddHandgunAmmo(50); 
      Destroy(gameObject); 
     } 
    } 
} 

まだ単なる中継するために、「仲介者」を持っていた方法を通過した値を扱うすべて情報。しかし、これはeveryonesのフィードバックのためにうまく

感謝を動作し、私はこれが誰か