Первый скриншот моей Иерархии:
Все внутри одной сцены Название:
Игра запускается, когда основная игра отключена. Внутри основной игры сидят все игровые объекты. Главное меню и Диспетчер игр включены.
При первом запуске игры, при запуске игры короткая анимация игрока на 5 секунд. Игрок начинает с нескольких вращающихся градусов по Z. Z = 50, когда x и y оба равны 0. Затем игрок медленно поворачивается по Z к 0.
Это похоже на то, что игрок спит и просыпается. Я использую стек постобработки на единицу.
И вот первая проблема. Пока игрок вращается по оси Z и эффект пост-обработки работает, если я нажимаю клавишу Escape, он возвращает меня в главное меню, но затем, если я снова нажимаю клавишу Escape, он начинает игру заново с самого начала.
Но если я жду в своей игре, чтобы игрок закончил вращение по Z, и эффект постобработки закончился, а затем нажав Escape, то откроется главное меню, и второй раз возобновит игру изта же точка.
Я не могу понять, почему, когда игрок вращается и пост-процесс работает, клавиша escape заставляет его начать игру заново с существа?
![Hierarchy](https://i.stack.imgur.com/Da0tV.jpg)
Это скриншот игры при запуске и после завершения вращения и стека процессов:
![On the left when the game start cutscene on the right starting a conversation](https://i.stack.imgur.com/oOCxN.jpg)
Еще одна проблема, которую я заметил сейчас. После начала игры с использованием пост-процесса и завершения вращения игрока, если я нажму Escape, он перейдет в главное меню и снова выйдет из игры, но вернется в игру, но, например, на втором скриншоте разговор не будет продолжен. Он вернется к тому же моменту в игре, но, похоже, все не будет продолжаться, как разговор.
К объекту «Вернуться к главному меню» мне прикреплен скрипт:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BackToMainMenu : MonoBehaviour
{
private bool _isInMainMenu = false;
public GameObject mainGame;
public GameObject mainMenu;
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!_isInMainMenu)
{
// -- Code to freeze the game
mainGame.SetActive(false);
mainMenu.SetActive(true);
}
else
{
// -- Code to unfreeze the game
mainGame.SetActive(true);
mainMenu.SetActive(false);
}
_isInMainMenu = !_isInMainMenu;
}
}
}
К объекту главного меню в главном меню я прикрепил этот скрипт:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour
{
public GameObject mainGame;
public GameObject mainMenu;
public void PlayGame()
{
mainGame.SetActive(true);
mainMenu.SetActive(false);
}
public void QuitGame()
{
Application.Quit();
}
}
На кнопке PLAY я использую этот метод сценария PlayGame из сценария MainMenu.
В основной игреобъект на объекте Player, прикрепленный к W Player У меня есть несколько сценариев контроллера:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 10.0f;
// Update is called once per frame
void Update()
{
float translatioin = Input.GetAxis("Vertical") * speed;
float straffe = Input.GetAxis("Horizontal") * speed;
translatioin *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translatioin);
}
}
Диспетчер блокировки игрока:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerLockManager : MonoBehaviour
{
public PlayerCameraMouseLook playerCameraMouseLook;
public PlayerController playerController;
// Start is called before the first frame update
public void PlayerLockState(bool LockPlayer, bool LockPlayerCamera)
{
if (LockPlayer == true)
{
playerController.enabled = false;
}
else
{
playerController.enabled = true;
}
if (LockPlayerCamera == true)
{
playerCameraMouseLook.enabled = false;
}
else
{
playerCameraMouseLook.enabled = true;
}
}
}
И состояние блокировки мыши:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLockState : MonoBehaviour
{
public bool lockState = true;
private void Start()
{
LockState(lockState);
}
private void Update()
{
}
public void LockState(bool lockState)
{
if (lockState == false)
{
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
else
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
}
}
Под Player в качестве дочернего объекта у меня есть объект Player Camera и к нему также прикреплены некоторые сценарии:
Look Player Player Mouse Mouse:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCameraMouseLook : MonoBehaviour
{
public float sensitivity = 5.0f;
public float smoothing = 2.0f;
private GameObject player;
private Vector2 mouseLook;
private Vector2 smoothV;
// Use this for initialization
void Start()
{
player = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update()
{
var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);
transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
player.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, Vector3.up);
}
}
И сценарий глубины резкости:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.PostProcessing;
public class DepthOfField : MonoBehaviour
{
public GameObject player;
public PostProcessingProfile postProcessingProfile;
public bool dephOfFieldFinished = false;
public PlayerLockManager playerLockManager;
private Animator playerAnimator;
private float clipLength;
// Start is called before the first frame update
void Start()
{
playerAnimator = player.GetComponent<Animator>();
AnimationClip[] clips = playerAnimator.runtimeAnimatorController.animationClips;
foreach (AnimationClip clip in clips)
{
clipLength = clip.length;
}
var depthOfField = postProcessingProfile.depthOfField.settings;
depthOfField.focalLength = 300;
StartCoroutine(changeValueOverTime(depthOfField.focalLength, 1, clipLength));
postProcessingProfile.depthOfField.settings = depthOfField;
}
IEnumerator changeValueOverTime(float fromVal, float toVal, float duration)
{
playerLockManager.PlayerLockState(true, true);
float counter = 0f;
while (counter < duration)
{
var dof = postProcessingProfile.depthOfField.settings;
if (Time.timeScale == 0)
counter += Time.unscaledDeltaTime;
else
counter += Time.deltaTime;
float val = Mathf.Lerp(fromVal, toVal, counter / duration);
dof.focalLength = val;
postProcessingProfile.depthOfField.settings = dof;
yield return null;
}
playerAnimator.enabled = false;
dephOfFieldFinished = true;
}
}
У меня в основной игре есть также имя объекта Openning Scene и прикрепленное к нему:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OpeningCutscene : MonoBehaviour
{
public NaviConversations naviConversation;
public DepthOfField dephOfField;
// Update is called once per frame
void Update()
{
if (dephOfField.dephOfFieldFinished == true)
{
naviConversation.PlayNaviConversation(0);
dephOfField.dephOfFieldFinished = false;
}
}
}
Это немного долго, но все подключено.
Игра начинается с маяn menu.
При нажатии на кнопку PLAY начинается новая игра.
При запуске новой игры запускается сценарий Depth Of Fieldиспользуя пост-обработку. Также я блокирую плеер, чтобы игрок не мог двигать ни мышью, ни самим игроком.
Когда сценарий глубины резкости закончил свою работу, разговор между Навии проигрыватель запускается. Когда разговор находится в действии, игрок может перемещать мышь на 360 градусов, но не может перемещать игрока в любом направлении.
Когда разговор заканчивается, игрок также может двигаться в любом направлении.
Проблемы:
При запуске новой игры, когда скрипт глубины резкости находится в работе, нажатие клавиши выхода приведет к открытию главного меню, а нажатие клавиши выхода - сноване возобновлять сценарий глубины резкости, но запустит его снова и снова.
Когда вы ждете окончания разговора, если не нажимаете клавишу escape, пока разговор не закончится, то при перемещении и нажатии клавиши escape он будетпринесите главное меню и снова возобновите игру с того же пункта.
Проблема в том, что когда игра делает что-то наподобие глубины резкости, она возобновляет игру, вместо этого возобновляя ее, или когда в середине разговора разговор никогда не будет продолжаться.
Идентификаторы с помощью клавиши escape - один раз, чтобы попасть в главное меню, и второй, чтобы возобновить игру.
Кнопка PLAY - это то, что должно начинать только новую игру, а не клавиша выхода.
Это немного долго, но все связано.