Can attack is causing me lots of problems

It keeps returning heaps of Null Reference Exceptions and I don’t understand why

 public bool Interact_Combat()
        {
           RaycastHit[] All_Ray_Hits= Physics.RaycastAll(GetMouseRay());
        foreach(RaycastHit HitVar in All_Ray_Hits)
        {
            Combat_Target Hit_Target = HitVar.transform.GetComponent<Combat_Target>();
            if(Hit_Target==null)
            {
                continue;
            }
           if(!GetComponent<Fighter>().Can_Attack(Hit_Target.gameObject)){ continue;}
          if (Input.GetMouseButtonDown(0))
            { 
                GetComponent<Fighter>().Attack_Target(Hit_Target);
            }
        return true;
        }
        return false;
        }
public bool Can_Attack(GameObject AttackTarget)
{if (AttackTarget == null) { return false; }
    Health TestTarget = AttackTarget.GetComponent<Health>();
   
 return TestTarget != null && !TestTarget.IsReallyDead();
}

NullReferenceException: Object reference not set to an instance of an object
RPG.Control.Player_Controller.Interact_Combat () (at Assets/Script/Controller/Player_Controller.cs:36)
RPG.Control.Player_Controller.Update () (at Assets/Script/Controller/Player_Controller.cs:23)

Unfortunately, it’s hard to tell which line is 36… something is null, but only some things CAN be null in this script…
For example: You can be sure that all the HitVars are complete and true hits because you’re iterating over the result of a RaycastAll…
Hit_Target isn’t causing a null because you’re null checking it.

You must have a Fighter component attached… it was working before, right?

Let’s rewrite this method to make a few things clearer…

public bool Interact_Combat()
{
     Fighter fighter= GetComponent<Fighter>();
     if(fighter==null)
     {
          Debug.LogError($"Unable to find the Fighter component on {name}!");
          return false;
     }
     RaycastHit[] All_Ray_Hits = Physics.RaycastAll(GetMouseRay());
     foreach(RaycastHit HitVar in All_Ray_Hits)
     {
          if(HitVar.transform.TryGetComponent(out CombatTarget Hit_Target)
          {
               if(!fighter.Can_Attack(Hit_Target.gameObject)) continue;
               if(Input.GetMouseButtonDown(0))
               {
                     fighter.Attack_Target(Hit_Target);
               }
               return true;
           }
           return false;
     }
}

First we’re verifying the Fighter, and caching the reference… If the Fighter is missing, it will error out here.
Then we’re iterating over the Hits, but we’re taking advantage of a newer method TryGetComponent… if there is no HitTarget on the hit GameObject, then whats inside the block is never run.
Then we check the CanAttack, using the cached fighter, and attack using the cached fighter.

Run this, and if there is a null reference, let me know exactly which line the null reference was on (type the line out)

Yeah this was stupid.

I removed Fighter from a Nested Prefab but applied it to Character accidentally. So it removed it from Player as well and didnt notice. Thanks!

Been there, done that, got the T-Shirt. I suspected (by process of elimination in the code) that the Fighter component was missing, it’s just rare for it to not be there at this point in the lessons…
Often, this can be found by Logging out any missing components via Debug code.

1 Like

That would be extremely helpful to know. I assume thats what your above code is and there isnt an easy way to have Unity print “Fighter is missing”?

There is Debug.Assert Unity - Scripting API: Debug.Assert

So you might do something like

Debug.Assert(Fighter!=null, $"{name} is missing a Fighter component");
1 Like

Thank you!!! this is great

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms