-1

Hello I am new to coding in unity and i was trying to make the health bar go down when the player hits an object. When i use a debug.log it prints what i want it to print when it collides with the object however when i try to make the health go down when it hits the object it gives me this error

NullReferenceException: 
Object reference not set to an instance of an object
DamagePlayer.OnCollisionEnter2D (UnityEngine.Collision2D collision)
(at Assets/Scripts/DamagePlayer.cs:30)

here is my code.

My Damage class

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

public class DamagePlayer : MonoBehaviour
{
    public BarScript bar;
    public int playerHealth = 100;
    int damage = 10;

    // Start is called before the first frame update
    void Start()
    {
        print(playerHealth);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collision2D collision)
    {

       if(collision.collider.tag =="enemy")
        {

            Debug.Log("enemy");
            bar.math(damage);
        }
    }
}

Health Bar class

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

public class BarScript : MonoBehaviour
{
    private float fillAmount;

    [SerializeField]
    private Image content;


    // Start is called before the first frame update
    void Start()
    {
        fillAmount = 1f;

    }

    // Update is called once per frame
    void Update()
    {

        content.fillAmount = fillAmount;
    }

    public float math(float value)
    {
        return fillAmount =(value / 100);
    }

}

My Player class

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

public class Player : MonoBehaviour
{
    private Rigidbody2D rb;

    [SerializeField]
    private float speed = 300f;
    private float jump = 400f;
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        Movement();
    }

    void Movement()
    {
        if (Input.GetKeyDown("d")){
            rb.velocity = new Vector2(speed * Time.fixedDeltaTime, rb.velocity.y);
        }else if (Input.GetKeyDown("a"))
        {
            rb.velocity = new Vector2(-speed * Time.fixedDeltaTime, rb.velocity.y);
        }else if (Input.GetKeyDown("space"))
        {
            rb.velocity = new Vector2(rb.velocity.x, jump * Time.fixedDeltaTime);
        }
    }

}
Joey
  • 1,436
  • 2
  • 19
  • 33
steve
  • 17
  • 1
  • 3

1 Answers1

2

You haven't create an instance of BarScript in DamagePlayer, that's why this is creating problem.

Without instance you can't access member method of a class, you can use static to make that accessible by anyone. If it is just for Player then you can do that (Single-player), But it won't be so nice.

If you it's multi-player or you want do the same for enemy, then create prefab with both script, then instantiate or use pooling. Finally use findGameobjectsWithTag (not findGameobjectWithTag) and access those scripts, members and use their member methods.

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
  • when i creat an instance of BarScript in DamagePlayer it gives me this error "You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all UnityEngine.MonoBehaviour:.ctor() BarScript:.ctor() DamagePlayer:.ctor() (at Assets/Scripts/DamagePlayer.cs:7)" – steve Apr 13 '19 at 02:10
  • Create a `prefab` then put both script there, then access it using `GetComponent()` – Maifee Ul Asad Apr 13 '19 at 02:14
  • Or, you can remove inheritance of `MonoBehaviour` from `BarScript` class & use that just to save damage amount, then update it from `HealthBar` script . – Maifee Ul Asad Apr 13 '19 at 02:16