0

I am really new to unity and i'm trying to make a PlayerController with different states in different files.

this is the code so far:

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

public class PlayerController : MonoBehaviour
{
private PlayerState currentState;

void Start()
{
    currentState = new PlayerIdle(this);
    Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
    currentState.OnStateUpdate();
}
public void ChangeState(PlayerState newState)
{
    currentState.OnStateExit();
    currentState = newState;
    newState.OnStateEnter();
}
}

how do i fix this?

edit: here is the PlayerIdle code which is supposed to give me the error.

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

public class PlayerIdle : PlayerState
{
public CharacterController controller;
public Transform cam;
public GameObject player = GameObject.Find("Player");

public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3;
public float rotationSpeed;

float x;
float z;

public Transform groundCheck = GameObject.Find("groundCheck").transform;
public float groundDistance = 0.4f;
public LayerMask groundMask;

[SerializeField] Vector3 velocity;
public bool isGrounded;

public float turnSmoothTime = 1f;
float turnSmoothVelocity;

public PlayerIdle(PlayerController playerController) : base(playerController)
{
    this.playerController = playerController;
}

public override void OnStateEnter()
{

}
public override void OnStateExit()
{

}


public override void OnStateUpdate()
{
    x = Input.GetAxisRaw("Horizontal");
    z = Input.GetAxis("Vertical");
    isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

    velocity = player.transform.TransformDirection(Vector3.forward) * speed * z + new Vector3(0f, velocity.y, 0f); ;

    if (Input.GetButtonDown("Jump") && isGrounded)
    {
        velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
    }

    if (isGrounded && velocity.y < 0)
    {
        velocity.y = -2f;
    }


    velocity.y += gravity * Time.deltaTime;

    player.transform.Rotate(new Vector3(0f, x * rotationSpeed, 0f));
    controller.Move(velocity * Time.deltaTime);
}

}

any help would be much appreciated :)

also, i found out this is called a statemachine if that helps.

  • 1
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – JohnG Jul 15 '22 at 21:44
  • probably, but the problem is i don't entirely understand the error. i would think that the "new" keyword creates a new instance of the object, and thus i don't understand why the reference isn't set to an instance of an object – August Broe Jul 15 '22 at 21:48
  • The error is on line 16 since that wasn't very clear in my post – August Broe Jul 15 '22 at 21:50
  • 1
    Well… this is a very common error and basically it is saying that the code is trying to call/use something that is `null`. What line in the code throws the error? It is unclear which line is 16 since there are not line numbers. Put a breakpoint on that line and run the code… then examine that line of code to see what is `null`. – JohnG Jul 15 '22 at 21:53
  • Line 16 is the line inside the update method – August Broe Jul 15 '22 at 22:53
  • Well… if the error is in the `Update` method… then that would indicate that `currentState` is probably `null`. Have you checked to make sure `currentState` is not `null` after calling `currentState = new PlayerIdle(this);` … ? … If it is not `null`… then something else must be setting it to `null` after … `currentState = new PlayerIdle(this);` code is called. – JohnG Jul 15 '22 at 23:09
  • Without seeing more code… it looks odd in a sense that `currentState` is defined as a `PlayerState` object … `private PlayerState currentState;` … however the code is initializing it with a `PlayerIdle` constructor?... `currentState = new PlayerIdle(this);` … ? … – JohnG Jul 15 '22 at 23:14

2 Answers2

0

The error says that something in that line is null. The only thing that can be null is the CurrentState variable. Probably when you assign it the value of new PlayerIdle (this) in the Start () method, that value is null. If you can figure out why it's null, you can fix it, but if you're still having trouble you can include the PlayerIdle () code. A suggestion may be to insert a print (currentState) at the end of Start () to understand if it is actually null. In addition, also insert a print (new PlayerIdel (this)) in the Update () method to understand if even during the update it continues to be null.

iFralex
  • 591
  • 1
  • 2
  • 9
0

it seems that the update method was being called before the start method (which i still don't understand), so the solution was just to add an if statement before currentState.OnStateUpdate(); saying "if (currentState != null)"