Help, I cannot get the grab right on my character.

I’m having a lot of trouble performing a grab similar to the game Tomba. I have two different types of grabs on my character; one standing, and the other when jumping. I keep getting "NullReferenceException: Object reference not set to an instance of an object located at PlayerGrabTrigger.TopGrab () (at Assets/Scripts/PlayerGrabTrigger.cs:44) ". When top grab is removed. The normal grab works perfectly. Please help.

void StandGrab( )
    {
        if(Input.GetKeyDown(KeyCode.E) && !topGrab) {                                                                                                           // TODO: There will be a bug here that will need to be fixed later.

            if(!standGrab) {
                Physics2D.queriesStartInColliders = false;
                hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance);

                if(hit.collider != null && hit.collider.tag == "Grabbed") {
                    standGrab = true;

                }
            }
            else if(!Physics2D.OverlapPoint(grabPoint.position, notGrabbed)) {
                standGrab = false;
                if(hit.collider.gameObject.GetComponent<Rigidbody2D>() != null) {
                    hit.collider.gameObject.transform.GetComponent<Rigidbody2D>().simulated = true;
                    hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x, 5) * standThrowForce;  //<-- This controls the throw force and direction. Add force should be replaced
                }
            }
        }
        if(standGrab) {
            topGrab = false;
            hit.collider.gameObject.transform.position = grabPoint.position;
            hit.collider.gameObject.transform.GetComponent<Rigidbody2D>().simulated = false;
            hit.collider.gameObject.transform.GetComponent<Transform>().localRotation = Quaternion.identity;
        }

    }

    public void TopGrab( )                                                                                                           // Motion is called when the enemy is in a stunned stated and the player is landing on the enemy from the top.
    {

        if(!topGrab) {
            Physics2D.queriesStartInColliders = false;
            hit = Physics2D.Raycast(transform.position * 1, transform.position + -transform.up, downwardDistance);
            if(hit.collider != null && hit.collider.tag == "Grabbed" && isConnected) {
                topGrab = true;

            }

            else if(!Physics2D.OverlapPoint(topGrabPoint.position, notGrabbed)) {
                topGrab = false;
                if(hit.collider.gameObject.GetComponent<Rigidbody2D>() != null && playerFeet.IsTouchingLayers(enemyMask)) {
                    hit.collider.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x, 5) * topThrowForce;  //<-- This controls the throw force and direction. Add force should be replaced
                }
            }
        }
        if (topGrab && isConnected) {
            standGrab = false;
            hit.collider.gameObject.transform.position = topGrabPoint.position;
            hit.collider.gameObject.gameObject.transform.GetComponent<Transform>().localRotation = Quaternion.identity;
        }
    }
   



    void ConnectFromTop( )
    {
        if(playerBox.IsTouchingLayers(enemyMask) && controller.playerRigidBody.velocity.y > 0 || playerFeet.IsTouchingLayers(enemyMask) && controller.playerRigidBody.velocity.y > 0) {
            isConnected = true;
            //hit.collider.gameObject.transform.GetComponent<Rigidbody2D>().simulated = false;
            playerRig.transform.position = hit.collider.gameObject.transform.position;
            // playerRig.velocity += new Vector2(0, playerRig.velocity.y * topThrowForce);
        }
        if(!playerBox.IsTouchingLayers(enemyMask)) {
            isConnected = false;
        }
        //else if(!controller.IsPlayerJumping) {
        //    isTryingToConnect = false;
        //}
    }

The logic in lines 37 and 44 is the problem. If hit.collider is null (i.e. your raycast doesn’t hit anything), and there’s no overlap on line 42, then hit.collider will still be null on line 44, causing the NRE.

Sorry I am pretty new with this can you elaborate a little more.

Ok, line 36 does a raycast and fills the ‘hit’ variable. The raycast might not hit something, in which case hit.collider will be null. Focus on this case. hit.collider is null, so the ‘if’ on line 37 sees this and does not execute because of the first condition (hit.collider != null is False). So, the else statement on 42 executes, checking for an overlap. If there is no overlap, the if executes.
So, we are in the case where hit.collider is null, and there is no overlap for line 42. Line 43 is a simple assignment, so no problem, but then we get to line 44. We know that hit.collider is null, but the first thing this line does is try to access hit.collider.gameObject (to the call GetComponent, but we don’t get there). Collider was null, so try to access the gameObject throws an exception.

1 Like

Ah! I see hold on I am going to try to work on this.

Sorry for the late reply. Thannk you I will try something different to get it to located the players rigidbody when it is in use.