Hello! I have started making the second level for my game. However, the camera doesn’t follow the player like it does in the first level, even when I have the camera settings from my first level as a prefab. All of my codes worked for the first level, I just need to get the camera to follow the player again. Here is a picture that I hope will help better explain my problem. If you want to see any of my scripts, please let me know. I have the following scripts that could be useful in this situation: Camera Controller, Player Controller, Level Manager, and Level Loader. Thanks for your help!
I set the smoothing to 5, but the camera still drifts away once I enter Play Mode. The camera seems to focus on the player fine in Edit Mode, but not in Play Mode.
I’m not sure how to fix the red error: NullReferenceException: Object reference not set to an instance of an object, especially since everything works fine on Level 1, and I don’t want to risk changing the codes at all if I can.
I tried that, but it still won’t work. I deleted the suggestion (Thank you for trying), so here is my Player Controller script, and everything, including the camera, works perfectly fine in Level One. Please let me know if you want to see my Camera Controller Script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
private bool isTouchingGround;
private Animator playerAnimation;
public Vector3 respawnPoint;
public LevelManager gameLevelManager;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
playerAnimation = GetComponent<Animator>();
respawnPoint = transform.position;
gameLevelManager = FindObjectOfType<LevelManager>();
}
// Update is called once per frame
void Update()
{
isTouchingGround = Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, groundLayer);
movement = Input.GetAxis("Horizontal");
if (movement > 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = new Vector2(59.20651f, 59.20651f);
}
else if (movement < 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = new Vector2(-59.20651f, 59.20651f);
}
else
{
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump") && isTouchingGround)
{
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
}
playerAnimation.SetFloat("Speed", Mathf.Abs(rigidBody.velocity.x));
playerAnimation.SetBool("OnGround", isTouchingGround);
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.tag == "FallDetector") {
gameLevelManager.Respawn();
}
if(other.tag == "CheckPoint") {
respawnPoint = other.transform.position;
}
}
}
post Camera Controller script.
and did you tried to place this line in the camera controller script ?
And show what the error says (doubleclick on it)
Here is my Camera Controller Script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour {
public GameObject player;
public float offset;
private Vector3 playerPosition;
public float offsetSmoothing;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
playerPosition = new Vector3(player.transform.position.x, player.transform.position.y, transform.position.z);
if(player.transform.localScale.x > 0f) {
playerPosition = new Vector3(playerPosition.x + offset, playerPosition.y, playerPosition.z);
}
else{
playerPosition = new Vector3(playerPosition.x - offset, playerPosition.y, playerPosition.z);
}
transform.position = Vector3.Lerp(transform.position, playerPosition, offsetSmoothing * Time.deltaTime);
}
}
be sure that the player has tag Player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour {
public GameObject player;
public float offset;
private Vector3 playerPosition;
public float offsetSmoothing;
// Use this for initialization
void Start () {
//change players tag to Player
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
playerPosition = new Vector3(player.transform.position.x, player.transform.position.y, transform.position.z);
if(player.transform.localScale.x > 0f) {
playerPosition = new Vector3(playerPosition.x + offset, playerPosition.y, playerPosition.z);
}
else{
playerPosition = new Vector3(playerPosition.x - offset, playerPosition.y, playerPosition.z);
}
transform.position = Vector3.Lerp(transform.position, playerPosition, offsetSmoothing * Time.deltaTime);
}
}
That worked, thanks! But now I have another problem. When the player starts to move once spawned in Level 2, they shrink. Is there any way to fix that?
I now also get a “NullReferenceException: Object reference not set to an instance of an object” notification once I start the game, or at least the second level.
this can happen because the player isn’t in the scene.
try this for test: still you shouldn’t add the follow script to the camera in the levels without your player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour {
public GameObject player;
public float offset;
private Vector3 playerPosition;
public float offsetSmoothing;
// Use this for initialization
void Start () {
//change players tag to Player
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
if (player != null)
{
playerPosition = new Vector3(player.transform.position.x, player.transform.position.y, transform.position.z);
if(player.transform.localScale.x > 0f) {
playerPosition = new Vector3(playerPosition.x + offset, playerPosition.y, playerPosition.z);
}
else{
playerPosition = new Vector3(playerPosition.x - offset, playerPosition.y, playerPosition.z);
}
transform.position = Vector3.Lerp(transform.position, playerPosition, offsetSmoothing * Time.deltaTime);
}
}
}
I put in the null code that you put in above, but the player still shrunk.
if (player != null) this line should just prevent the NullReferenceException if the player was missed. It do nothing vs the players shrunk.
Is the player shrinks only in second level ?
Yes, the player only shrinks in the second level.
maybe because of this line: transform.localScale = new Vector2(59.20651f, 59.20651f);
try to save default value and use it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
private bool isTouchingGround;
private Animator playerAnimation;
public Vector3 respawnPoint;
public LevelManager gameLevelManager;
Vector2 tmpTransform;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
playerAnimation = GetComponent<Animator>();
respawnPoint = transform.position;
gameLevelManager = FindObjectOfType<LevelManager>();
tmpTransform = transform.localScale;
}
// Update is called once per frame
void Update()
{
isTouchingGround = Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, groundLayer);
movement = Input.GetAxis("Horizontal");
if (movement > 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = tmpTransform;
}
else if (movement < 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = new Vector2(-tmpTransform.x, tmpTransform.y);
}
else
{
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump") && isTouchingGround)
{
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
}
playerAnimation.SetFloat("Speed", Mathf.Abs(rigidBody.velocity.x));
playerAnimation.SetBool("OnGround", isTouchingGround);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "FallDetector")
{
gameLevelManager.Respawn();
}
if (other.tag == "CheckPoint")
{
respawnPoint = other.transform.position;
}
}
}
Do I put in tmpTransform where you have it written, or is there some other value I’m supposed to put in it’s place?
Because if I put in tmpTransform, I get a Compiler Error Must be Fixed message, and can’t enter play mode.
what should be fixed, which line is it ? Maybe it should be vector3 (or you have missed some lines: check 19, 29, 40, 46)
The only thing I changed in the code is the tmpTransform sections. If I put in my normal values from before tmpTransform, everything works fine.
ok, post the script with is giving the error
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
private bool isTouchingGround;
private Animator playerAnimation;
public Vector3 respawnPoint;
public LevelManager gameLevelManager;
public AudioClip Running;
private AudioSource Source;
public float volLowRange = .5f;
public float volHighRange = 1.0f;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
playerAnimation = GetComponent<Animator>();
respawnPoint = transform.position;
gameLevelManager = FindObjectOfType<LevelManager>();
Source = GetComponent<AudioSource>();
Vector2 (tmpTransform);
}
// Update is called once per frame
void Update()
{
isTouchingGround = Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, groundLayer);
movement = Input.GetAxis("Horizontal");
if (movement > 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = new Vector2 (tmpTransform);
Source.PlayOneShot(Running, 1F);
}
else if (movement < 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
transform.localScale = new Vector2(-tmpTransform.x, tmpTransform.y);
}
else
{
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump") && isTouchingGround)
{
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
}
playerAnimation.SetFloat("Speed", Mathf.Abs(rigidBody.velocity.x));
playerAnimation.SetBool("OnGround", isTouchingGround);
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.tag == "FallDetector")
{
Fall();
}
if (other.tag == "CheckPoint") {
respawnPoint = other.transform.position;
}
}
private void Fall()
{
gameLevelManager.Respawn();
}
}
you should declare tmpTransform for the class and not inside Start. Just look at the my script
there are lines: 19, 29, 40, 46