0
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ This question seems to have been asked and answered in the past. Please take a look at it, and if it does not apply, please edit your question and add more details to it. \$\endgroup\$
    – Vaillancourt
    Commented May 10, 2019 at 14:09
  • \$\begingroup\$ I'm afraid the suggestions are just making me more and more lost and confused. :( \$\endgroup\$ Commented May 10, 2019 at 21:26
  • \$\begingroup\$ I'm not familiar with Unity, and so the first thing I'd try would be to add a couple of 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\$
    – Vaillancourt
    Commented May 11, 2019 at 0:48
  • \$\begingroup\$ You might also want to take a peak at this tutorial that explains a bit how to have your game manager persist through your scene. You can then put variables in there to carry them over scenes. \$\endgroup\$
    – Vaillancourt
    Commented May 11, 2019 at 1:07
  • \$\begingroup\$ Thanks for the suggestion. You make it sound so easy though lol. I’ve only played with statics a bit, so I can’t even process how I could achieve that to get the desired results. I’ll check out the video when I can. I have come across a tutorial series for a 2D RPG that covers this issue, which seems ideal and easy. :) I’ll still look into doing it with statics as well. \$\endgroup\$ Commented May 11, 2019 at 8:35

0

Browse other questions tagged .