首页 > 解决方案 > 重新开始新游戏时,我应该如何将整个世界的所有对象重置为原始状态?

问题描述

问题是当我保存游戏一次然后开始新游戏而不先退出游戏时它正在开始新游戏但是例如相机和玩家位置与第一次开始新游戏时不同。也许相机是相同的,但玩家的位置不是。

看起来在制作新游戏时在保存游戏后没有先退出游戏一次并没有重置所有内容。

我在层次结构主菜单和游戏中有两个场景。在游戏下我有所有的游戏对象。

在主菜单中,我有这个脚本,其中有两种方法,我从按钮 onclick 事件中调用一种方法,一种用于新游戏,一种用于加载:

public void ClickNewGameDialog(string ButtonType)
        {
            if (ButtonType == "Yes")
            {
                loading = false;
                newGameDialog.SetActive(false);
                StartCoroutine(sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, _newGameButtonLevel));
            }

            if (ButtonType == "No")
            {
                GoBackToMainMenu();
            }
        }

        public void ClickLoadGameDialog(string ButtonType)
        {
            if (ButtonType == "Yes")
            {
                loading = true;
                newGameDialog.SetActive(false);
                StartCoroutine(sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, _newGameButtonLevel));               
                
            }

            if (ButtonType == "No")
            {
                GoBackToMainMenu();
            }
        }

和 FadeAndLoadScene 方法:

public IEnumerator FadeAndLoadScene(FadeDirection fadeDirection, string sceneToLoad)
    {
        yield return Fade(fadeDirection);
        SceneManager.LoadScene(sceneToLoad);
    }

在新游戏上,加载“游戏”时字符串是相同的,因为我有一个游戏场景。

这是我做的一个类,只是为了能够轻松调用我的保存和加载方法:

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

public class SaveLoad : MonoBehaviour
{
    private static SaveGame saveGame;

    private void Awake()
    {
        // Create your temporary save game
        saveGame = new SaveGame();
        SaveMaster.SetSlot(0, true, saveGame);
    }

    public static void Save()
    {
        // Is it using a temporary slot?
        if (SaveMaster.GetActiveSlot() == 0)
        {
            if (SaveFileUtility.IsSlotUsed(1))
                SaveMaster.DeleteSave(1); // Removes the save game that was available.
            SaveMaster.SetSlot(1, false, saveGame); // Sets the slot to the first one, while keeping your save game.
        }

        SaveMaster.SyncSave();
        SaveMaster.WriteActiveSaveToDisk();
    }

    public static void Load()
    {
        SaveMaster.SetSlot(1, true);
    }
}

这是开始新游戏时的一个简短场景片段,我在这里进行保存和加载:

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

public class PlayingInGameScenesController : MonoBehaviour
{
    public CinemachineFreeLook[] freeLookCams;
    public CinemachineVirtualCamera[] virtualCams;
    public LockController lockController;
    public GameObject uiSceneText;
    public GameObject player;
    public float transitionSpeed = 5f;
    public float thresHold = 0.1f;
    public bool talkingProcess = true;
    public FadeInOutSaveGameText fadeInOutSaveGame;

    private bool newGame = true;

    private void Start()
    {
        
    }

    public void PlayingSceneInGame()
    {
        PlayingSceneStatesControls(true);
        StartCoroutine(ScenePlayingTime());
    }

    private void Update()
    {
        if (SceneManager.GetActiveScene().name != "Main Menu" && newGame == true && MenuController.loading == false)
        {
            PlayingSceneInGame();
            newGame = false;
        }

        if (SceneManager.GetActiveScene().name != "Main Menu" && MenuController.loading == true)
        {
            SaveLoad.Load();
        }
    }

    private void LateUpdate()
    {
       
    }

    private void PlayingSceneStatesControls(bool LockState)
    {
        lockController.LockControl(LockState);

        if (LockState == true)
        {
            uiSceneText.SetActive(true);
        }
        else
        {
            talkingProcess = false;
            uiSceneText.SetActive(false);
        }
    }

    IEnumerator ScenePlayingTime()
    {
        yield return new WaitForSeconds(10);

        PlayingSceneStatesControls(false);

        freeLookCams[0].enabled = false;
        freeLookCams[1].enabled = true;

        var brain = Camera.main.GetComponent<CinemachineBrain>().m_DefaultBlend.m_Time;

        StartCoroutine(SaveAfterSomeTime());
        
    }

    IEnumerator SaveAfterSomeTime()
    {
        yield return new WaitForSeconds(15f);

        SaveLoad.Save();

        StartCoroutine(fadeInOutSaveGame.OverAllTime(5f));
    }
}

游戏开始并在 25 秒后自动保存游戏。然后,当我加载游戏时,它会加载场景,然后加载保存的游戏并将玩家定位到保存的位置。

问题是当我制作加载游戏然后逃到主菜单然后制作新游戏然后新游戏从保存的游戏位置而不是原始位置的玩家开始。当开始一个新游戏时,我没有做任何加载:

这是一个新游戏:

if (SceneManager.GetActiveScene().name != "Main Menu" && newGame == true && MenuController.loading == false)
        {
            PlayingSceneInGame();
            newGame = false;
        }

这是用于加载:

if (SceneManager.GetActiveScene().name != "Main Menu" && MenuController.loading == true)
        {
            SaveLoad.Load();
        }

如果我将保存并加载游戏然后退出游戏再次运行a将首先制作一个新游戏它将以新的方式启动游戏。问题是在游戏中进行保存然后加载然后新游戏然后新游戏永远不会将玩家位置重置为原始位置。

每次制作新游戏时,我是否应该进行某种全局世界状态保存并加载状态?

现在我只保存 Player 状态:

玩家状态保存组件

我想当你开始一个新游戏加载游戏场景而不加载保存的游戏时,它应该从零开始游戏,一切都应该恢复到原来的状态。但它不会重置玩家位置和旋转。

如果我先退出游戏但不是在游戏仍在运行时退出游戏。

我试过了,但它还没有工作:

public CinemachineFreeLook[] freeLookCams;
    public CinemachineVirtualCamera[] virtualCams;
    public LockController lockController;
    public GameObject uiSceneText;
    public GameObject playerStart;
    public float transitionSpeed = 5f;
    public float thresHold = 0.1f;
    public bool talkingProcess = true;
    public FadeInOutSaveGameText fadeInOutSaveGame;

    private bool newGame = true;
    private Vector3 playerOriginalPosition;
    private Vector3 playerOriginalScale;
    private Quaternion playerOriginalRotation;

    private void Start()
    {
        playerOriginalPosition = playerStart.transform.position;
        playerOriginalScale = playerStart.transform.localScale;
        playerOriginalRotation = playerStart.transform.rotation;
    }

    public void PlayingSceneInGame()
    {
        PlayingSceneStatesControls(true);
        StartCoroutine(ScenePlayingTime());
    }

    private void Update()
    {
        if (SceneManager.GetActiveScene().name != "Main Menu" && newGame == true && MenuController.loading == false)
        {
            playerStart.transform.position = playerOriginalPosition;
            playerStart.transform.localScale = playerOriginalScale;
            playerStart.transform.rotation = playerOriginalRotation;

            PlayingSceneInGame();
            newGame = false;
        }

标签: c#unity3d

解决方案


我不确定播放器上的 Savable 组件是什么,但我假设它是一个自动保存和加载播放器状态的组件,它显然会在场景开始时覆盖播放器位置。

只需在场景中定义一个 Player_Start 变换(一个空的游戏对象)并添加一个简单的逻辑,如果游戏是 New_Game 则将玩家放置在 Player_Start。


推荐阅读