0
\$\begingroup\$

I have a child object for my player called Light. The light color changes when the player touches balls of different colors.

When I respawn at a checkpoint, the light is getting reset to the default color instead of the most recent color.

Checkpoint script:

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

public class checkpoint : MonoBehaviour
{
    private GameMaster gm;
    private GameObject player;
    private CapsuleCollision coll;
    private Light playercolor;

    void Start()
    {
        gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
        player = GameObject.FindGameObjectWithTag("Player");
        coll = GameObject.FindGameObjectWithTag("Player").GetComponent<CapsuleCollision>();
        playercolor = player.transform.GetChild(1).GetComponent<Light>();
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
            {
            gm.checkPoint = transform.position;
            playercolor.color = coll.lightcolor();
        }
    }
}

Player Collision Script

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

public class CapsuleCollision : MonoBehaviour
{
    public GameObject player;
    private new Light light;
    public GameObject enemy;
    private Light enemyLight;
    public GameObject door;
    public Renderer doorColor;
    public BoxCollider2D doorOff;
    public Material doorColor2;
    private bool doorON;
    public GameObject dieExplode;
    public GameObject LevelCompeteUI;
    public GameObject LevelRetryUI;
    public GameObject PauseButton;
    public GameObject WinExplode;
    public Transform timer;
    public GameObject TimerUI;
    public LevelSelector levelSelector;
    public int levelreached;
    public Light newplayercolor;    

    Timer time;

    void Start()
    {
        levelreached = PlayerPrefs.GetInt("OneDoor");
        Debug.Log(levelreached);
        time = timer.GetComponent<Timer>();
        time.StartTimer();
    }

    private IEnumerator waitForSec2(float sec)
    {
        yield return new WaitForSeconds(sec);
        LevelCompeteUI.SetActive(true);
        PauseButton.SetActive(false);
    }


    private IEnumerator GameOver()
    {
        yield return new WaitForSeconds(2f);
        LevelRetryUI.SetActive(true);
        PauseButton.SetActive(false);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Ball")
        {
            Debug.Log("Balls :"+collision.gameObject.name);
            light = gameObject.transform.GetChild(1).GetComponent<Light>();
            enemy = collision.gameObject.gameObject;
            enemyLight = enemy.transform.GetChild(0).GetComponent<Light>();
            light.color = enemyLight.color;
        }
        if (collision.gameObject.tag == "Door")
        {
            Debug.Log("Door :" + collision.gameObject.name);

            door = collision.gameObject.gameObject;
            doorColor = door.GetComponent<Renderer>();
            doorColor2 = doorColor.material;
            light = gameObject.transform.GetChild(1).GetComponent<Light>();
            doorOn();
            Debug.Log("Door :" + doorColor2.color);

        }
        if(collision.gameObject.tag == "Enemy")
        {
            gameObject.SetActive(false);
            Instantiate(dieExplode,transform.position,Quaternion.identity);
            Debug.Log("GAme Ober");
            LevelRetryUI.SetActive(true);
            PauseButton.SetActive(false);

            time.StopTimer();
            TimerUI.SetActive(false);
        }
        if(collision.gameObject.tag == "EndGame")
        {
            WinExplode.SetActive(true);
            Instantiate(WinExplode, WinExplode.transform.position, Quaternion.identity);
            StartCoroutine(waitForSec2(2f));
            levelreached = levelreached + 1;
            PlayerPrefs.SetInt("OneDoor",levelreached);
            Debug.Log(levelreached);
            time.StopTimer();
            TimerUI.SetActive(false);

        }
    }

    private IEnumerator waitForSec(float sec)
    {
        yield return new WaitForSeconds(sec);
        doorOff = door.GetComponent<BoxCollider2D>();
        doorOff.enabled = true;
    } 
    void doorOn()
    {
        doorOff = door.GetComponent<BoxCollider2D>();
        doorOff.enabled = true;
        if (light.color != doorColor2.color)
        {
            doorOff.enabled = false;
            StartCoroutine(waitForSec(.1f));
        }
        else if(light.color == doorColor2.color)
        {
            doorOff.enabled = true;

        }
    }

    void Update()
    {
        Debug.Log(levelreached);
        newplayercolor.color = light.color;
        Debug.Log(newplayercolor.color);
    }

    public Color lightcolor()
    {
        Debug.Log(light.color);
        return light.color;
    }
}

Player Pos Script

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

public class PlayerPos : MonoBehaviour
{
    private GameMaster gm;
    private GameObject player;
    private CapsuleCollision coll;
    private Light playercolor;

    void Start()
    {
        gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();       
        transform.position = gm.checkPoint;
        player = GameObject.FindGameObjectWithTag("Player");
        coll = GameObject.FindGameObjectWithTag("Player").GetComponent<CapsuleCollision>();
        playercolor = player.transform.GetChild(1).GetComponent<Light>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.C))
        {
            gameObject.SetActive(true);                
        }
    }
}

Game Master Script

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

public class GameMaster : MonoBehaviour
{
    private static GameMaster instance;
    public Vector2 checkPoint;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(instance);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}   

its the code I am calling replay and restart from replay function `using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;

public class PauseButton : MonoBehaviour { public GameObject PauseMenuUI;

public void Pause()
{
    PauseMenuUI.SetActive(true);
    Time.timeScale = 0f;
}

public void Resume()
{
    PauseMenuUI.SetActive(false);
    Time.timeScale = 1f;
}

public void Replay()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}

public void MainMenu()
{
    SceneManager.LoadScene("MainMenu");
    Time.timeScale = 1f;
}
// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{

}

} `

\$\endgroup\$
  • \$\begingroup\$ 1) Where is the respawn logic I asked you to show us? 2) Please don't make other users clean up your code every time. Use the preview to double-check that your code is formatted correctly before posting, and consult the help center if you need guidance in getting the formatting you expect. \$\endgroup\$ – DMGregory May 2 at 12:13
  • \$\begingroup\$ This is all I got. this code is working after restarting and player respawns at the checkpoint but not with the color you expect. \$\endgroup\$ – mr.GON96 May 2 at 12:25
0
\$\begingroup\$

I have to guess at what you're doing here because you still haven't shown us your code for failing/restarting.

From context, it looks like the way you're respawning is you're either destroying the old player object and spawning a new one, or re-loading the whole scene with a new player object in it. You're using the PlayerPos script's Start method to position it at the position of the last checkpoint, as rememebered by the GameMaster script which doesn't get destroyed on scene load.

void Start()
{
    gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
    transform.position = gm.checkPoint;
    ...

(Hint: you can write that first line shorter as gm = GameObject.FindObjectOfType<GameMaster>(), or since you're using a Singleton pattern, just use GameMaster.instance instead of keeping a local gm variable at all)

This would be a reasonable place to also restore a light colour remembered in the GameMaster the same way. First, add a color field:

public class GameMaster : MonoBehaviour
{
    private static GameMaster instance;
    public Vector2 checkPoint;
    public Color32 color;
    ...

Then restore it at the same time you restore the checkpoint position:

void Start()
{    
    transform.position = GameMaster.instance.checkPoint;
    player = GameObject.FindGameObjectWithTag("Player");
    coll = player.GetComponent<CapsuleCollision>();
    playercolor = player.transform.GetChild(1).GetComponent<Light>();

    playercolor.color = GameMaster.instance.color;
}

Depending on your game logic, you might want to set gm.instance.color when the player touches a checkpoint, or just before they fail/restart - depending on whether you want the colour rewound to the most recent checkpoint or not.

If you want to go further you could create a CheckpointPersistent type to hold position, colour, and any other data that you want to restore at a checkpoint, then give it some Record() and Restore() methods to update its data from the player state or apply the saved data to the player's state respectively. This helps with encapsulation, so not every script in the chain needs to know the details of what gets restored at checkpoints - they can just ask the script with that job to do its thing when the need arises.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.