0
\$\begingroup\$

I have a bit of a problem with transferring my Game/Health Manager across scenes. My current Health Manager is set up so when the player gets hit, they flash, which is controlled by activating and de-activating the player's renderer. Everything transfers across using a Singleton and DontDestroyOnLoad, except the player's renderer in the Inspector box. I don't really know how I can make a reference to it so it's stored via script, or is added to the object box between scenes. I've tried making a reference via a GameObject, but it doesn't work as a Renderer isn't a GameObject.

Any ideas on what I can do? I've tried asking on the Unity forum, but I've had no reply. :(

Okay, here's my HealthManager, which originally had a reference to the player's renderer. I've commented it out as I'm currently trying to see if I can just add it to my player's PlayerController and then access it via the HealthManager as a static, but I'm not having any luck.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class HealthManager : MonoBehaviour
{
    //The counters will count down and will keep counting down based on the length variables
    public int maxHealth;
    public static int currentHealth;
    public float invincibilityLength;
    //public Renderer playerRenderer;
    public float flashLength;
    public float respawnLength;
    public GameObject deathEffect;
    public Image blackScreen;
    public float fadeSpeed;
    public float waitForFade;
    public Image flame1;
    public Image flame2;
    public Image flame3;
    public Sprite fullFlame;
    //public Sprite threeQuarterFlame;
    public Sprite halfFlame;
    //public Sprite quarterFlame;
    public Sprite EmptyFlame;
    public GameObject playerPrefab;

    private float invincibilityCounter;
    private float flashCounter;
    private bool isRespawning;
    private Vector3 respawnPoint;
    private bool isFadeToBlack;
    private bool isFadeFromBlack;
    private PlayerController thePlayer;
    private Quaternion startPosition;

    void Start()
    {
        thePlayer = playerPrefab.GetComponent<PlayerController>();
        currentHealth = maxHealth;
        respawnPoint = playerPrefab.transform.position;
        startPosition = playerPrefab.transform.rotation;
    }

    void Update()
    {
        //These functions are checked every frame until the player takes damage
        if(invincibilityCounter > 0)
        {
            invincibilityCounter -= Time.deltaTime;
            flashCounter -= Time.deltaTime;
            if(flashCounter <= 0)
            //The Flash Counter is currently set at 0.1 and will be within the 0 region as it counts down. During this period, the playerRenderer will alternate between on and off
            {
                PlayerController.playerRenderer.enabled = !PlayerController.playerRenderer.enabled;
                //The Flash Counter will keep counting down and reloop depending on the Flash Length time
                flashCounter = flashLength;
            }
            //This makes sure after the flashing and invincibility has worn off that the player renderer is always turned back on so you can see the player
            if(invincibilityCounter <= 0)
            {
                PlayerController.playerRenderer.enabled = true;
            }
        }
        if (isFadeToBlack)
        {
            blackScreen.color = new Color(blackScreen.color.r, blackScreen.color.g, blackScreen.color.b, Mathf.MoveTowards(blackScreen.color.a, 1f, fadeSpeed * Time.deltaTime));
            if (blackScreen.color.a == 1f)
            {
                isFadeToBlack = false;
            }
        }
        if (isFadeFromBlack)
        {
            blackScreen.color = new Color(blackScreen.color.r, blackScreen.color.g, blackScreen.color.b, Mathf.MoveTowards(blackScreen.color.a, 0f, fadeSpeed * Time.deltaTime));
            if (blackScreen.color.a == 0f)
            {
                isFadeFromBlack = false;
            }
        }
    }

    public void HurtPlayer(int damage, Vector3 direction)
    {
        //If the invincibility countdown reaches zero it stops, making you no longer invincible and prone to taking damage again
        if (invincibilityCounter <= 0)
        {
            currentHealth -= damage;
            FlameMetre();
            if (currentHealth <= 0)
            {
                Respawn();
            }
            else
            {
                thePlayer.Knockback(direction);
                invincibilityCounter = invincibilityLength;
                PlayerController.playerRenderer.enabled = false;
                flashCounter = flashLength;
            }
        }
    }

    public void Respawn()
    {
        //A StartCoroutine must be set up before the IEnumerator can begin
        if (!isRespawning)
        {

            StartCoroutine("RespawnCo");
        }
    }

    //IEnumerators or Coroutines will execute the code separately at specified times while the rest of the code in a codeblock will carry on executing as normal
    public IEnumerator RespawnCo()
    {
        if (!Checkpoint.checkpointActive)
        {
            isRespawning = true;
            thePlayer.gameObject.SetActive(false);
            Instantiate(deathEffect, thePlayer.transform.position, thePlayer.transform.rotation);
            yield return new WaitForSeconds(respawnLength);
            isFadeToBlack = true;
            yield return new WaitForSeconds(waitForFade);
            isFadeFromBlack = true;
            isRespawning = false;
            thePlayer.gameObject.SetActive(true);
            currentHealth = maxHealth;
            FlameMetre();
            invincibilityCounter = invincibilityLength;
            PlayerController.playerRenderer.enabled = false;
            flashCounter = flashLength;
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);
            GameManager.currentEmbers = 0;
        }

        else if (Checkpoint.checkpointActive)
        {
            isRespawning = true;
            thePlayer.gameObject.SetActive(false);
            Instantiate(deathEffect, thePlayer.transform.position, thePlayer.transform.rotation);
            yield return new WaitForSeconds(respawnLength);
            isFadeToBlack = true;
            yield return new WaitForSeconds(waitForFade);
            isFadeFromBlack = true;
            isRespawning = false;
            thePlayer.gameObject.SetActive(true);
            thePlayer.transform.position = respawnPoint;
            thePlayer.transform.rotation = startPosition;
            currentHealth = maxHealth;
            FlameMetre();
            invincibilityCounter = invincibilityLength;
            PlayerController.playerRenderer.enabled = false;
            flashCounter = flashLength;
        }
    }

    public void FlameMetre()
    {
        switch (currentHealth)
        {
            case 30:
                flame1.sprite = fullFlame;
                flame2.sprite = fullFlame;
                flame3.sprite = fullFlame;
                return;
            case 25:
                flame1.sprite = fullFlame;
                flame2.sprite = fullFlame;
                flame3.sprite = halfFlame;
                return;
            case 20:
                flame1.sprite = fullFlame;
                flame2.sprite = fullFlame;
                flame3.sprite = EmptyFlame;
                return;
            case 15:
                flame1.sprite = fullFlame;
                flame2.sprite = halfFlame;
                flame3.sprite = EmptyFlame;
                return;
            case 10:
                flame1.sprite = fullFlame;
                flame2.sprite = EmptyFlame;
                flame3.sprite = EmptyFlame;
                return;
            case 5:
                flame1.sprite = halfFlame;
                flame2.sprite = EmptyFlame;
                flame3.sprite = EmptyFlame;
                return;
            case 0:
                flame1.sprite = EmptyFlame;
                flame2.sprite = EmptyFlame;
                flame3.sprite = EmptyFlame;
                return;

            default:
                flame1.sprite = EmptyFlame;
                flame2.sprite = EmptyFlame;
                flame3.sprite = EmptyFlame;
                return;
        }
    }

    /*public void HealPlayer(int healAmount)
    {
        currentHealth += healAmount;
        if(currentHealth > maxHealth)
        {
            currentHealth = maxHealth;
        }
    }*/

    public void SetSpawnPoint(Vector3 newPosition)
    {
        respawnPoint = newPosition;
    }
}

And then my PlayerController:

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 allowInteract = false;
    public float gravityScale;
    public float knockBackForce;
    public float knockBackTime;
    //public Material textureChange;
    //public Material textureDefault;
    public bool allowCombat;
    public bool allowJump;
    public static bool canMove;
    public ChestTrigger chest;
    //public GameObject projectilePrefab;
    //public GameObject spawnPoint;
    public static Renderer playerRenderer;

    private Vector2 moveDirection;
    private Vector2 moveHorizontal;
    private float knockBackCounter;
    private CharacterController controller;
    private Quaternion targetRot;
    private bool headingLeft = false;
    private Pickup pickupWeapon;

    void Awake()
    {
        controller = GetComponent<CharacterController>();
        anim = GetComponent<Animator>();
    }

    void Start()
    {
        Cursor.visible = false;
        pickupWeapon = FindObjectOfType<Pickup>();
        canMove = true;
        targetRot = transform.rotation;
        if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("start_area"))
        {
            allowCombat = false;
            allowJump = true;
        }
        if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("hut_interior"))
        {
            allowCombat = false;
            allowJump = false;
        }
        if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("start_area 2"))
        {
            allowCombat = false;
            allowJump = true;
        }
        if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("level 1, room 1"))
        {
            allowCombat = true;
            allowJump = true;
        }
        if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("level 1, room 2"))
        {
            allowCombat = true;
            allowJump = true;
        }
    }

    void Update()
    {
        //To avoid any control or animation issues, each code block must be within this code block
        if (knockBackCounter <= 0 && canMove)
        {
            moveHorizontal.x = Input.GetAxis("Horizontal");
            //moveVertical.y = Input.GetAxis("Vertical");
            moveDirection = new Vector2(moveHorizontal.x * moveSpeed, moveDirection.y);
            controller.Move(moveDirection * Time.deltaTime);

            //Adds character rotation when changing direction horizontally
            if ((moveHorizontal.x < 0f && !headingLeft) || (moveHorizontal.x > 0f && headingLeft))
            {
                if (moveHorizontal.x < 0f) targetRot = Quaternion.Euler(0, 270, 0);
                if (moveHorizontal.x > 0f) targetRot = Quaternion.Euler(0, 90, 0);
                headingLeft = !headingLeft;
            }
            transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, Time.deltaTime * 20f);

            //Adds character rotation when changing direction vertically
            /*if(moveVertical.y < 0f && lookingUp || (moveVertical.y > 0f && !lookingUp))
            {
                if (moveVertical.y > 0f) targetrot = Quaternion.Euler(0, 0, 0);
                if (moveVertical.y < 0f) targetrot = Quaternion.Euler(0, 180, 0);
                lookingUp = !lookingUp;
            }*/

            if (SceneManagement.insideHut && canMove)
            {
                float moveHorizontalSnap = Input.GetAxis("Horizontal");
                float moveVerticalSnap = Input.GetAxis("Vertical");

                //Adds character rotation when changing direction horizontally, but snaps instead of fully rotating
                if (moveHorizontalSnap > 0)
                {
                    transform.eulerAngles = new Vector2(0, 90);
                }
                else if (moveHorizontalSnap < 0)
                {
                    transform.eulerAngles = new Vector2(0, -90);
                }

                //To possibly prevent diagonal movement with some control setups, try adding 'else if'
                //Adds character rotation when changing direction vertically, but snaps instead of fully rotating
                else if (moveVerticalSnap > 0)
                {
                    transform.eulerAngles = new Vector2(0, 0);
                }

                //Use this to make the character face towards the camera.
                /*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))
                    {
                        moveDirection.y = jumpForce;
                        jumped = true;
                    }
                    else if (!Input.GetKeyDown(KeyCode.KeypadPlus))
                    {
                        jumped = false;
                    }
                    if (SceneManagement.xbox360Controller == 1)
                    {
                        if (Input.GetKeyDown("joystick button 0"))
                        {
                            moveDirection.y = jumpForce;
                            jumped = true;
                        }
                        else if (!Input.GetKeyDown("joystick button 0"))
                        {
                            jumped = false;
                        }
                    }
                    else if (SceneManagement.ps4Controller == 1)
                    {
                        if (Input.GetKeyDown("joystick button 1"))
                        {
                            moveDirection.y = jumpForce;
                            jumped = true;
                        }
                        else if (!Input.GetKeyDown("joystick button 1"))
                        {
                            jumped = false;
                        }
                    }
                }
            }
            if (allowCombat)
            {
                if (Input.GetKeyDown(KeyCode.Space))
                {
                    anim.SetTrigger("Attack");
                    //GameObject projectileObject = Instantiate(projectilePrefab);
                    //projectilePrefab.transform.position = spawnPoint.transform.position + spawnPoint.transform.forward;
                }
                else if (SceneManagement.xbox360Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 1"))
                    {
                        anim.SetTrigger("Attack");
                    }
                }
                else if (SceneManagement.ps4Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 2"))
                    {
                        anim.SetTrigger("Attack");
                    }
                }
            }
            if (allowInteract)
            {
                if (SceneManagement.xbox360Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 2"))
                    {
                        anim.SetBool("Interact", controller.isGrounded);
                        pickupWeapon.ObjectActivation();
                        allowInteract = false;
                    }
                }
                else if (SceneManagement.ps4Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 0"))
                    {
                        anim.SetBool("Interact", controller.isGrounded);
                        pickupWeapon.ObjectActivation();
                        allowInteract = false;
                    }
                }
                else
                {
                    if (Input.GetKeyDown(KeyCode.Return))
                    {
                        anim.SetBool("Interact", controller.isGrounded);
                        pickupWeapon.ObjectActivation();
                        allowInteract = false;
                    }
                }
            }
            if (ChestTrigger.allowOpen)
            {
                if (Input.GetKeyDown(KeyCode.Return))
                {
                    anim.SetBool("Interact", controller.isGrounded);
                    chest.ChestOpen();
                }
                else if (Input.GetKeyDown(KeyCode.Return) && !ChestTrigger.allowOpen)
                {
                    anim.SetBool("Interact", false);
                }
                else if (SceneManagement.xbox360Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 2"))
                    {
                        anim.SetBool("Interact", controller.isGrounded);
                        chest.ChestOpen();
                    }
                    else if (Input.GetKeyDown("joystick button 2") && !ChestTrigger.allowOpen)
                    {
                        anim.SetBool("Interact", false);
                    }
                }
                else if (SceneManagement.ps4Controller == 1)
                {
                    if (Input.GetKeyDown("joystick button 0"))
                    {
                        anim.SetBool("Interact", controller.isGrounded);
                        chest.ChestOpen();
                    }
                    else if (Input.GetKeyDown("joystick button 0") && !ChestTrigger.allowOpen)
                    {
                        anim.SetBool("Interact", false);
                    }
                }
            }
        }
        else
        {
            knockBackCounter -= Time.deltaTime;
        }
        moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);

        anim.SetBool("isGrounded", controller.isGrounded);
        //If the character can't move, then the Speed is set to 0. Otherwise it'll use the horizontal input value.
        anim.SetFloat("Speed",
            !canMove
            ? 0f
            : Mathf.Abs(Input.GetAxis("Horizontal")));

        //anim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));
    }

    public void Knockback(Vector3 direction)
    {
        knockBackCounter = knockBackTime;

        moveDirection = direction * knockBackForce;
        moveDirection.y = knockBackForce;
    }
}

\$\endgroup\$
4
  • \$\begingroup\$ Please include the code you're using currently to flash the player's renderer, so answers can aim for compatibility with the strategy you're using (or recommend appropriate alternatives) \$\endgroup\$ Commented Jul 4, 2019 at 21:59
  • \$\begingroup\$ Updated the original post \$\endgroup\$ Commented Jul 4, 2019 at 22:03
  • \$\begingroup\$ Not sure I understand your question fully but, it sounds like you want to get the Renderer component on the player, why does "player.GetComponent<Renderer>()" not work for you? \$\endgroup\$ Commented Jul 5, 2019 at 19:19
  • \$\begingroup\$ not quite. with a tutorial I followed, the health manager that was set up references the player's renderer so it activates/deactivates to give a flashing effect when the player takes damage. My health and game manager scripts have been added to a GameObject called Game Manager, which I want to carry over between scenes, and for the player's health and pickups to stay the same. everything carries over as I put the Game Manager within a Canvas that has all the UI elements. The renderer is the one thing that doesn't and I can't seem to get it to. not sure of an alternative either. :-\ \$\endgroup\$ Commented Jul 5, 2019 at 20:36

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.