Unity FPS Game Error [duplicate] - c#

This question already has answers here:
Bullet Prefab Script
(3 answers)
Closed 8 years ago.
I am getting an error in this script.
UnityEngine does not contain a definition for rigidbody (Lines: 22,24)
public class GunShoot : MonoBehaviour
{
public GameObject BulletPrefab;
public float BulletSpeed;
public int BulletsInClip;
public AudioClip GunshotSound;
void Update () {
if (Input.GetButtonDown("Shoot")){
Shoot();
}
}
void Shoot() {
var bullet = Instantiate(BulletPrefab, transform.Find("BulletSpawn").position, transform.Find("BulletSpawn").rotation);
bullet.rigidbody.AddForce(transform.forward * BulletSpeed);
audio.PlayOneShot(GunshotSound);
BulletsInClip--;
}
}
Please tell me what to edit instead of just editing the script.

Your call to Instantiate() doesn't result in a GameObject. It will return a plain Object. So subsequently you're trying to access the RigidBody - using bullet.rigidbody - which an Object has no knowledge about.
When instantiating therefore perform an explicit cast:
var bullet = (GameObject) Instantiate(BulletPrefab, transform.Find("BulletSpawn").position, transform.Find("BulletSpawn").rotation);
Or even explicitly write GameObject bullet = ... to avoid errors like this. If you do, the compiler will start to complain at the location of the true error if you forget the cast.

Related

How to Make Enemy Attack When In Range of The Player? [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
So my game is a 2D top down movement game and my script does make my enemy attack but it constantly loops the attack animation because I obviously don't know what EXACTLY to put code wise to make the enemy attack when in range of the player to do damage instead of letting him constantly loop. Also i seem to be getting an error when i get close to my enemy as of right now it says
NullReferenceException: Object reference not set to an instance of an object
EnemyCombat.Attack () (at Assets/EnemyCombat.cs:36)
EnemyCombat.Update () (at Assets/EnemyCombat.cs:25)
Also, Here is the EnemyCombat script
enemy attausing System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyCombat : MonoBehaviour
{
public Animator animator;
public Transform AttackPoint;
public float attackRange = 0.5f;
public LayerMask enemyLayers;
public int attackDamage = 5;
public float attackRate = 2f;
float nextAttackTime = 0f;
// Update is called once per frame
void Update()
{
if (Time.time >= nextAttackTime)
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
void Attack()
{
animator.SetTrigger("Attack");
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
foreach (Collider2D enemy in hitEnemies)
{
enemy.GetComponent<Enemy>().TakeDamage(attackDamage);
}
}
void OnDrawGizmosSelected()
{
if (AttackPoint == null)
return;
Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
}
}
To fix your endless attack loop:
// Update is called once per frame
void Update()
{
if (attackRate >= nextAttackTime) /* checks that nextAttackTime is less than or equal to the attackRate */
{
Attack();
nextAttackTime = Time.deltaTime * 5f; // adds 5 seconds to nextAttackTime
}
else
{
nextAttackTime -= Time.deltaTime; /* if nextAttackTime is greater than the attackRate, subtract one from nextAttackTime. this only happens once per second because you use Time.deltaTime */
}
}
From that NullReference Error it looks like the major problem you're having is that there is no actual point in the code or in the game hierarchy that you are telling your script which gameObject it is referring to.
Line 36 is trying to retrieve that information with .GetComponent<Enemy()>, so you need to provide that reference.
You could do this in the script fairly easily by creating a public variable that you can drag the enemy gameObject into in your hierarchy in Unity.
Try something like:
public GameObject enemyObject;
This will create a variable in the script visible in the hierarchy when you select the script which you can drag the appropriate gameObject into.
There might need to be some adjustments to it because I can't see the rest of your code, but this seems to be the issue.
Another option would be trying to manually adding it in:
void Start()
{
GameObject enemyObject = gameObject.GetComponent<Enemy>();
}
this is taken from Unity Scripting Documentation

How do i use a variable from another script [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 2 years ago.
Hi im having a problem with this i tried for 2 Days now but i don't know how to fix it. Im a beginner in C# and hope you can help me.
Im trying to use a variable from another script but the console keeps sending me an error:
NullReferenceException: Object reference not set to an instance of an object
PlayerCombat.OnCollisionEnter2D (UnityEngine.Collision2D collision) (at Assets/Scrips/PlayerCombat.cs:52)
public int attackDmg = 2; //Diffrent Script
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.tag == "Enemy")
{
PlayerTakeDamage(currentPlayerHp, GetComponent<Enemy>().attackDmg);
}
}
static void PlayerTakeDamage(int currentPlayerHp, int attackDmg)
{
currentPlayerHp -= attackDmg;
if (currentPlayerHp <= 0)
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
The
GetComponent<Enemy>()
is on another object, you can call it if you
1
Create a public variable and add the enemy object
public GameObject enemy;
And then after you dragged your enemy inside it in the inspector you can:
enemy.GetComponent<Enemy>()
Without problems
2
The second thing you can do is just declaring the enemy object
GameObject enemy;
And in the Start() you can
enemy = GameObject.FindGameObjectWithTag("Enemy");
But for this, you need to add a tag in the inspector for the enemy.
After this you can access the enemy as before.

Unity set UI text from other gameobject script C# [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
I have 3 different scripts.
GameController
PlayerController
DestroyOnContact
GameController
public class GameController : MonoBehaviour {
public static Text scoreText;
void Start()
{
StartCoroutine(SpawnWaves());
}
IEnumerator SpawnWaves()
{
yield return new WaitForSeconds(startWait);
while(true)
{
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazardSmall, spawnPosition, spawnRotation);
//SpawnHazard();
yield return new WaitForSeconds(spawnWait);
}
}
PlayerController
public static float score = 0;
DestoyOnContact
void OnTriggerEnter(Collider other)
{
if (other.tag == "PlayerBolt")
{
PlayerController.score++;
Debug.Log(PlayerController.score);
GameController.scoreText.text = "Score: " + PlayerController.score;
Debug.Log(GameController.scoreText.text);
}
Destroy(other.gameObject);
Destroy(gameObject);
Problem
When I run my game and shoot the object that uses the DestroyOnContact script, the PlayerController.score++ works and I have debugged it. But trying to set the scoreText in GameController does not work. This results in neither the player shot nor the object being shot destroy.
I get the exception:
NullReferenceException: Object reference not set to an instance of an object
I have tried using:
GameObject gogc = GameObject.Find("GameController");
GameController gc = (GameController)gogc.GetComponent(typeof(GameController));
Followed by:
gc.scoreText.text = "Score: " + PlayerController.score;
Which yields the same result. What am I missing?
Hierarchy:
I would recommend that you don't have the text as a static class as you then can't set it through the inspector.
Instead make a public static instance GameController.
Then in your Awake method of the GameController set instance = this;
You can then call that object by saying GameController.instance.ScoreText.text, remember that your ScoreText should NOT be static.
The reason i put it in the Awake method is to ensure it gets set early in the games lifecycle.
Feel free to ask questions.

interconnecting scripts in unity3D using the preprocessor [duplicate]

I've searched around and I just can't get this to work. I think I just don't know the proper syntax, or just doesn't quite grasp the context.
I have a BombDrop script that holds a public int. I got this to work with public static, but Someone said that that is a really bad programming habit and that I should learn encapsulation. Here is what I wrote:
BombDrop script:
<!-- language: c# -->
public class BombDrop : MonoBehaviour {
public GameObject BombPrefab;
//Bombs that the player can drop
public int maxBombs = 1;
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)){
if(maxBombs > 0){
DropBomb();
//telling in console current bombs
Debug.Log("maxBombs = " + maxBombs);
}
}
}
void DropBomb(){
// remove one bomb from the current maxBombs
maxBombs -= 1;
// spawn bomb prefab
Vector2 pos = transform.position;
pos.x = Mathf.Round(pos.x);
pos.y = Mathf.Round(pos.y);
Instantiate(BombPrefab, pos, Quaternion.identity);
}
}
So I want the Bomb script that's attached to the prefabgameobject Bombprefab to access the maxBombs integer in BombDrop, so that when the bomb is destroyed it adds + one to maxBombs in BombDrop.
And this is the Bomb script that needs the reference.
public class Bomb : MonoBehaviour {
// Time after which the bomb explodes
float time = 3.0f;
// Explosion Prefab
public GameObject explosion;
BoxCollider2D collider;
private BombDrop BombDropScript;
void Awake (){
BombDropScript = GetComponent<BombDrop> ();
}
void Start () {
collider = gameObject.GetComponent<BoxCollider2D> ();
// Call the Explode function after a few seconds
Invoke("Explode", time);
}
void OnTriggerExit2D(Collider2D other){
collider.isTrigger = false;
}
void Explode() {
// Remove Bomb from game
Destroy(gameObject);
// When bomb is destroyed add 1 to the max
// number of bombs you can drop simultaneously .
BombDropScript.maxBombs += 1;
// Spawn Explosion
Instantiate(explosion,
transform.position,
Quaternion.identity);
In the documentation it says that it should be something like
BombDropScript = otherGameObject.GetComponent<BombDrop>();
But that doesn't work. Maybe I just don't understand the syntax here. Is it suppose to say otherGameObject? Cause that doesn't do anything. I still get the error : "Object reference not set do an instance of an object" on my BombDropScript.maxBombs down in the explode()
You need to find the GameObject that contains the script Component that you plan to get a reference to. Make sure the GameObject is already in the scene, or Find will return null.
GameObject g = GameObject.Find("GameObject Name");
Then you can grab the script:
BombDrop bScript = g.GetComponent<BombDrop>();
Then you can access the variables and functions of the Script.
bScript.foo();
I just realized that I answered a very similar question the other day, check here:
Don't know how to get enemy's health
I'll expand a bit on your question since I already answered it.
What your code is doing is saying "Look within my GameObject for a BombDropScript, most of the time the script won't be attached to the same GameObject.
Also use a setter and getter for maxBombs.
public class BombDrop : MonoBehaviour
{
public void setMaxBombs(int amount)
{
maxBombs += amount;
}
public int getMaxBombs()
{
return maxBombs;
}
}
use it in start instead of awake and dont use Destroy(gameObject); you are destroying your game Object then you want something from it
void Start () {
BombDropScript =gameObject.GetComponent<BombDrop> ();
collider = gameObject.GetComponent<BoxCollider2D> ();
// Call the Explode function after a few seconds
Invoke("Explode", time);
}
void Explode() {
//..
//..
//at last
Destroy(gameObject);
}
if you want to access a script in another gameObject you should assign the game object via inspector and access it like that
public gameObject another;
void Start () {
BombDropScript =another.GetComponent<BombDrop> ();
}
Can Use this :
entBombDropScript.maxBombs += 1;
Before :
Destroy(gameObject);
I just want to say that you can increase the maxBombs value before Destroying the game object. it is necessary because, if you destroy game object first and then increases the value so at that time the reference of your script BombDropScript will be gone and you can not modify the value's in it.

Why am i Getting NullReferenceException when trying to create a HealthPack in Unity C#? [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
Ok guys and gals I'm having an issue again with some code. Basically once I start and it attempts to create a Health Pack it's throwing an error that:
NullReferenceException: Object reference not set to an instance of an object
HealthSpawnerScript.Update () (at Assets/Scripts/HealthSpawnerScript.cs:31)
below is the code i'm running. The gameobject PlayerController houses a method used to return Player Health named PlayerHealth(). In awake I set playerController to find the script and method I'm after. Then in update i'm trying to call the method and assign it to a variable for use in the script later. I know this should be simple but i'm having a brain fart guys.
public PlayerController playerController;
private int healthHolder;
void OnAwake()
{
playerController = GameObject.Find ("PlayerHealth").GetComponent<PlayerController> ();
}
// Use this for initialization
void Start ()
{
//set healthExist to false to indicate no health packs exist on game start
healthExist = false;
//playerController = GameObject.Find ("PlayerHealth").GetComponent<PlayerController> ();
}
// Update is called once per frame
void Update ()
{
healthHolder = playerController.PlayerHealth();
There is no Unity callback function named OnAwake. You are likely looking for the Awake function.
If that is fixed and your problem is still there, you have to seperate your code into pieces and find out what's failing.
playerController = GameObject.Find ("PlayerHealth").GetComponent<PlayerController> ();
should be changed to
void Awake()
{
GameObject obj = GameObject.Find("PlayerHealth");
if (obj == null)
{
Debug.Log("Failed to find PlayerHealth GameObject");
return;
}
playerController = obj.GetComponent<PlayerController>();
if (playerController == null)
{
Debug.Log("No PlayerController script is attached to obj");
}
}
So, if GameObject.Find("PlayerHealth") fails, that means there is no GameObject with that name in the scene. Please check the spellings.
If obj.GetComponent<PlayerController>(); fails, there is no script called PlayerController that is attached to the PlayerHealth GameObject. Simplify your problem!

Categories