I'm having a hell of a time trying to get this bug fixed and I'm completely lost; I've tried loads of ways, but I just don't get it. :(
Basically, when I enter a hut in my scene, it loads up the next level. However, once I leave that scene, I want to go back to the previous scene and for the character to be in the same place he was before entering. I've tried using Don'tDestroyOnLoad, but the problem with that, is that the character model in the second scene is different from the first - it's bigger as the camera and scene are set up differently, nor is the start position the same as where the character entered. I've tried using SceneManager.LoadScene, but that destroys everything and resets the scene and puts the player back at the start. I've tried using a Coroutine like I have in a previous project, where when the player dies they respawn at a checkpoint. In this case though, the player doesn't die, but it doesn't appear to be calling my IEnumerator as it keeps giving me an 'object reference is not set to an instance of an object' error. I'm not sure if what I've done has even been set up correctly anyway, or if such a thing will work when loading/switching between scenes.
These are the scripts I have at the moment:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public PlayerController thePlayer;
public float reloadLength;
private Vector3 respawnPoint;
private bool playerReloading;
void Start()
{
respawnPoint = thePlayer.transform.position;
/*Player player = new Player();
player.SetPosition(new Vector3(0, 0, 0));
player.SetRotation(new Vector3(0, 0, 0));
player.SetControl(true);*/
}
void Update()
{
}
public void PlayerReload()
{
if (playerReloading)
{
StartCoroutine("ReloadingCo");
}
}
public IEnumerator ReloadingCo()
{
Instantiate(thePlayer, thePlayer.transform.position, thePlayer.transform.rotation);
yield return new WaitForSeconds(reloadLength);
playerReloading = false;
thePlayer.transform.position = respawnPoint;
Debug.Log("Player respawned");
}
public void SetSpawnPoint(Vector3 newPosition)
{
respawnPoint = newPosition;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ExitTrigger : MonoBehaviour
{
public GameObject[] buttonPrompts;
public bool exitVicinity;
public GameObject thePlayer;
public GameObject entranceObject;
private int xbox360Controller = 0;
private int ps4Controller = 0;
private bool insideHut;
private EntranceTrigger entranceTrigger;
private GameManager theGameManager;
//private EntranceTrigger entranceTrigger;
void Start()
{
theGameManager = FindObjectOfType<GameManager>();
entranceTrigger = GetComponent<EntranceTrigger>();
if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
{
insideHut = true;
exitVicinity = true;
}
}
public void OnTriggerEnter(Collider other)
{
if (insideHut)
{
if (other.gameObject.CompareTag("Player"))
{
exitVicinity = true;
ControllerDetection();
if (exitVicinity && ps4Controller == 1)
{
PS4Prompts();
}
else if (exitVicinity && xbox360Controller == 1)
{
Xbox360Prompts();
}
else
{
PCPrompts();
}
}
}
}
public void OnTriggerExit(Collider other)
{
exitVicinity = false;
}
public void Update()
{
if (exitVicinity)
{
if (xbox360Controller == 1)
{
if (Input.GetKeyDown("joystick button 2"))
{
SceneManager.LoadScene("start_area");
}
}
else if (ps4Controller == 1)
{
if (Input.GetKeyDown("joystick button 0"))
{
SceneManager.LoadScene("start_area");
}
}
else
{
if (Input.GetKeyDown(KeyCode.Return))
{
SceneManager.LoadScene("start_area");
theGameManager.PlayerReload();
}
}
}
}
public void Hide()
{
buttonPrompts[0].SetActive(false);
buttonPrompts[1].SetActive(false);
buttonPrompts[2].SetActive(false);
}
public void Xbox360Prompts()
{
buttonPrompts[1].SetActive(true);
Invoke("Hide", 3f);
}
public void PS4Prompts()
{
buttonPrompts[2].SetActive(true);
Invoke("Hide", 3f);
}
public void PCPrompts()
{
buttonPrompts[0].SetActive(true);
Invoke("Hide", 3f);
}
public void ControllerDetection()
{
string[] names = Input.GetJoystickNames();
for (int x = 0; x < names.Length; x++)
{
//print(names[x].Length);
if (names[x].Length == 19)
{
//print("PS4 CONTROLLER IS CONNECTED");
ps4Controller = 1;
xbox360Controller = 0;
if (ps4Controller == 1)
{
Debug.Log("PS4 controller detected");
}
}
else if (names[x].Length == 33)
{
//print("XBOX 360 CONTROLLER IS CONNECTED");
ps4Controller = 0;
xbox360Controller = 1;
if (xbox360Controller == 1)
{
Debug.Log("Xbox 360 controller detected");
}
}
else
{
ps4Controller = 0;
xbox360Controller = 0;
}
if (xbox360Controller == 0 && ps4Controller == 0)
{
Debug.Log("No controllers detected");
}
/*if (!string.IsNullOrEmpty(names[x]))
{
xbox360Controller = 1;
ps4Controller = 1;
}
else if(string.IsNullOrEmpty(names[x]))
{
xbox360Controller = 0;
ps4Controller = 0;
Debug.Log("Controllers not detected");
}*/
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerController : MonoBehaviour
{
public Animator anim;
public float moveSpeed;
public float jumpForce;
public bool jumped;
public bool attack;
public bool interact;
public float gravityScale;
public float knockBackForce;
public float knockBackTime;
public float invincibilityLength;
public Renderer playerRenderer;
public Material textureChange;
public Material textureDefault;
public bool allowCombat = false;
public bool allowJump;
public bool allowInteract;
private Vector3 moveDirection;
private Vector3 extraDirections;
private float knockBackCounter;
private float invincibilityCounter;
private CharacterController controller;
void Start()
{
Cursor.visible = false;
controller = GetComponent<CharacterController>();
if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("level 1"))
{
allowCombat = true;
allowJump = true;
}
else if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("start_area"))
{
allowCombat = false;
allowJump = true;
}
else if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
{
allowCombat = false;
allowJump = false;
}
}
void Update()
{
if (knockBackCounter <= 0)
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
moveDirection = new Vector3(moveHorizontal * moveSpeed, moveDirection.y);
extraDirections = new Vector3(moveVertical * moveSpeed, extraDirections.y);
if (moveHorizontal > 0)
{
transform.eulerAngles = new Vector3(0, 90);
}
else if (moveHorizontal < 0)
{
transform.eulerAngles = new Vector3(0, -90);
}
if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
{
if (moveVertical > 0)
{
transform.eulerAngles = new Vector3(0, 0);
}
else if (moveVertical < 0)
{
transform.eulerAngles = new Vector3(0, 180);
}
}
if (controller.isGrounded)
{
if (allowJump)
{
moveDirection.y = -1f;
//GetKeyDown will require the player to press the button each time they want to jump. GetKey will allow the player to spam the jump button if they keep pressing it down.
if (Input.GetKeyDown(KeyCode.KeypadPlus) || Input.GetKeyDown("joystick button 1"))
{
moveDirection.y = jumpForce;
jumped = true;
}
else if (!Input.GetKeyDown(KeyCode.KeypadPlus) || !Input.GetKeyDown("joystick button 1"))
{
jumped = false;
}
}
else
{
allowJump = false;
}
if (allowCombat)
{
if (Input.GetKey(KeyCode.Space) || Input.GetKey("joystick button 7"))
{
attack = true;
playerRenderer.material = textureChange;
}
else if (!Input.GetKey(KeyCode.Space) || !Input.GetKey("joystick button 7"))
{
attack = false;
playerRenderer.material = textureDefault;
}
}
else if (!allowCombat)
{
attack = false;
playerRenderer.material = textureDefault;
}
if (allowInteract)
{
if (Input.GetKeyDown(KeyCode.Return))
{
interact = true;
}
}
}
}
else
{
knockBackCounter -= Time.deltaTime;
}
moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);
controller.Move(moveDirection * Time.deltaTime);
anim.SetBool("isGrounded", controller.isGrounded);
anim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));
if (attack)
{
anim.SetTrigger("Attack");
}
if (interact)
{
anim.SetBool("keyPressed", controller.isGrounded);
}
}
public void Knockback(Vector3 direction)
{
knockBackCounter = knockBackTime;
moveDirection = direction * knockBackForce;
moveDirection.y = knockBackForce;
}
public void Pickup()
{
if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
{
if(gameObject.name == "Pickup Trigger")
{
interact = true;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class EntranceTrigger : MonoBehaviour
{
public GameObject[] buttonPrompts;
public GameManager gameManager;
//public HealthManager theHealthManager;
public bool entranceVicinity;
//public PlayerController thePlayer;
//public float reloadLength;
//public bool exitVicinity;
//public bool allowInteraction = false;
private int xbox360Controller = 0;
private int ps4Controller = 0;
private bool outsideHut;
//private Vector3 respawnPoint;
//private bool playerReloading;
void Start()
{
gameManager = FindObjectOfType<GameManager>();
//theHealthManager = FindObjectOfType<HealthManager>();
if(SceneManager.GetActiveScene() == SceneManager.GetSceneByName("start_area"))
{
outsideHut = true;
}
/*else if(SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
{
insideHut = true;
outsideHut = false;
}*/
}
public void OnTriggerEnter(Collider other)
{
if (outsideHut)
{
gameManager.SetSpawnPoint(transform.position);
//respawnPoint = thePlayer.transform.position;
if (other.gameObject.CompareTag("Player"))
{
entranceVicinity = true;
//exitVicinity = false;
ControllerDetection();
if (entranceVicinity && ps4Controller == 1)
{
PS4Prompts();
}
else if (entranceVicinity && xbox360Controller == 1)
{
Xbox360Prompts();
}
else
{
PCPrompts();
}
}
}
}
public void OnTriggerExit(Collider other)
{
entranceVicinity = false;
//exitVicinity = false;
}
public void Update()
{
if (entranceVicinity)
{
if (xbox360Controller == 1)
{
if (Input.GetKeyDown("joystick button 2"))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 2);
}
}
else if (ps4Controller == 1)
{
if (Input.GetKeyDown("joystick button 0"))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 2);
}
}
else
{
if (Input.GetKeyDown(KeyCode.Return))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 2);
}
}
}
}
/*public void PlayerReload()
{
if (playerReloading)
{
StartCoroutine("ReloadingCo");
}
}
public IEnumerator ReloadingCo()
{
Instantiate(thePlayer, thePlayer.transform.position, thePlayer.transform.rotation);
yield return new WaitForSeconds(reloadLength);
playerReloading = false;
thePlayer.transform.position = respawnPoint;
}
public void SetSpawnPoint(Vector3 newPosition)
{
respawnPoint = newPosition;
}*/
public void Hide()
{
buttonPrompts[0].SetActive(false);
buttonPrompts[1].SetActive(false);
buttonPrompts[2].SetActive(false);
}
public void Xbox360Prompts()
{
buttonPrompts[1].SetActive(true);
Invoke("Hide", 3f);
}
public void PS4Prompts()
{
buttonPrompts[2].SetActive(true);
Invoke("Hide", 3f);
}
public void PCPrompts()
{
buttonPrompts[0].SetActive(true);
Invoke("Hide", 3f);
}
public void ControllerDetection()
{
string[] names = Input.GetJoystickNames();
for (int x = 0; x < names.Length; x++)
{
//print(names[x].Length);
if (names[x].Length == 19)
{
//print("PS4 CONTROLLER IS CONNECTED");
ps4Controller = 1;
xbox360Controller = 0;
if (ps4Controller == 1)
{
Debug.Log("PS4 controller detected");
}
}
else if (names[x].Length == 33)
{
//print("XBOX 360 CONTROLLER IS CONNECTED");
ps4Controller = 0;
xbox360Controller = 1;
if (xbox360Controller == 1)
{
Debug.Log("Xbox 360 controller detected");
}
}
else
{
ps4Controller = 0;
xbox360Controller = 0;
}
if(xbox360Controller == 0 && ps4Controller == 0)
{
Debug.Log("No controllers detected");
}
/*if (!string.IsNullOrEmpty(names[x]))
{
xbox360Controller = 1;
ps4Controller = 1;
}
else if(string.IsNullOrEmpty(names[x]))
{
xbox360Controller = 0;
ps4Controller = 0;
Debug.Log("Controllers not detected");
}*/
}
}
}
I'm totally stuck on how to fix this, so any help would be greatly appreciated. Also, if anyone has any suggestions, treat me like I'm thick lol. A lot of explanations go over my head and I struggle to process a lot of the concepts and ways of doing things.
I'm afraid the suggestions given to me are just confusing me no end and I've no idea which would be appropriate or how I'd even go about using/starting any of them. They're all things I've not come across before or tried.
static
variables to your game manager; once you are about to leave the scene, you store the position and orientation of the player in those variables. Once you come back to that scene, if you have not changed these values, they should have remained the same. You use them to re-position your player where he left. \$\endgroup\$