unity学习第1天

本身也具有一些unity知识,包括Eidtor界面使用、Shader效果实现、性能分析,但对C#、游戏逻辑不太清楚,这次想从开发者角度理解游戏,提高C#编程,从简单的unity游戏理解游戏逻辑,更好的为工作服务。

unity2019.4.40f1c1,使用Unity官网FPS Microgame(如下图)。原本想从游戏源码启动流程开始学习,但Unity核心代码没有开源,就还是先理解游戏逻辑。

游戏分成 5个Scene,我们关注MainScene,其中有个GameManager,从Inspector看挂有许多Scripts,我们先一个个分析。

GameFlowManager,引用using UnityEngine.SceneManagement,定义类GameFlowManager前半部分是在自定义Eidtor界面,这里float timeRatio = 1 - (m_TimeLoadEndGameScene - Time.time) / endSceneLoadDelay;不是很理解,待续

cs 复制代码
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameFlowManager : MonoBehaviour
{
    [Header("Parameters")]
    [Tooltip("Duration of the fade-to-black at the end of the game")]
    public float endSceneLoadDelay = 3f;
    [Tooltip("The canvas group of the fade-to-black screen")]
    public CanvasGroup endGameFadeCanvasGroup;

    [Header("Win")]
    [Tooltip("This string has to be the name of the scene you want to load when winning")]
    public string winSceneName = "WinScene";
    [Tooltip("Duration of delay before the fade-to-black, if winning")]
    public float delayBeforeFadeToBlack = 4f;
    [Tooltip("Duration of delay before the win message")]
    public float delayBeforeWinMessage = 2f;
    [Tooltip("Sound played on win")]
    public AudioClip victorySound;
    [Tooltip("Prefab for the win game message")]
    public GameObject WinGameMessagePrefab;

    [Header("Lose")]
    [Tooltip("This string has to be the name of the scene you want to load when losing")]
    public string loseSceneName = "LoseScene";


    public bool gameIsEnding { get; private set; }

    PlayerCharacterController m_Player;
    NotificationHUDManager m_NotificationHUDManager;
    ObjectiveManager m_ObjectiveManager;
    float m_TimeLoadEndGameScene;
    string m_SceneToLoad;

    void Start()
    {   
        Debug.Log("Start Game: " + m_Player);
        //返回场景中的所填类型的随机个体
        m_Player = FindObjectOfType<PlayerCharacterController>();
        //DebugUtility.cs不是Unity中的内置脚本,存在Assets/FPS/Scripts/DebugUtility.cs
        DebugUtility.HandleErrorIfNullFindObject<PlayerCharacterController, GameFlowManager>(m_Player, this);

        m_ObjectiveManager = FindObjectOfType<ObjectiveManager>();
		DebugUtility.HandleErrorIfNullFindObject<ObjectiveManager, GameFlowManager>(m_ObjectiveManager, this);

        AudioUtility.SetMasterVolume(1);
    }

    void Update()
    {
        if (gameIsEnding)
        {   
            Debug.Log("m_TimeLoadEndGameScene: " + m_TimeLoadEndGameScene);
            Debug.Log("Time.time: " + Time.time);
            Debug.Log("endSceneLoadDelay: " + endSceneLoadDelay);
            float timeRatio = 1 - (m_TimeLoadEndGameScene - Time.time) / endSceneLoadDelay;
            Debug.Log("timeRatio: " + timeRatio);
            
            endGameFadeCanvasGroup.alpha = timeRatio;

            AudioUtility.SetMasterVolume(1 - timeRatio);

            // See if it's time to load the  (after the delay)
            if (Time.time >= m_TimeLoadEndGameScene)
            {
                Debug.Log("Scene loading: " + m_SceneToLoad);
                SceneManager.LoadScene(m_SceneToLoad);
                gameIsEnding = false;
            }
        }
        else
        {
            if (m_ObjectiveManager.AreAllObjectivesCompleted())
                EndGame(true);

            // Test if player died
            if (m_Player.isDead)
                EndGame(false);
        }
    }

    void EndGame(bool win)
    {
        // unlocks the cursor before leaving the scene, to be able to click buttons
        Cursor.lockState = CursorLockMode.None;
        Cursor.visible = true;

        // Remember that we need to load the appropriate end scene after a delay
        gameIsEnding = true;
        endGameFadeCanvasGroup.gameObject.SetActive(true);
        if (win)
        {
            m_SceneToLoad = winSceneName;
            m_TimeLoadEndGameScene = Time.time + endSceneLoadDelay + delayBeforeFadeToBlack;

            // play a sound on win
            var audioSource = gameObject.AddComponent<AudioSource>();
            audioSource.clip = victorySound;
            audioSource.playOnAwake = false;
            audioSource.outputAudioMixerGroup = AudioUtility.GetAudioGroup(AudioUtility.AudioGroups.HUDVictory);
            audioSource.PlayScheduled(AudioSettings.dspTime + delayBeforeWinMessage);

            // create a game message
            var message = Instantiate(WinGameMessagePrefab).GetComponent<DisplayMessage>();
            if (message)
            {
                message.delayBeforeShowing = delayBeforeWinMessage;
                message.GetComponent<Transform>().SetAsLastSibling();
            }
        }
        else
        {
            m_SceneToLoad = loseSceneName;
            m_TimeLoadEndGameScene = Time.time + endSceneLoadDelay;
        }
    }
}
相关推荐
丰锋ff33 分钟前
设计模式学习笔记
笔记·学习·设计模式
我命由我123451 小时前
财务学习 - 配比原则
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·学习方法
BFT白芙堂1 小时前
Franka & DROID :面向真实场景的机器人操作数据集
人工智能·学习·机器学习·机器人·具身智能·franka·robotiq
M78佐菲2 小时前
Linux多线程:创建、回收与互斥同步
linux·笔记·学习·算法
sunoo-2292 小时前
【Linux 系统编程】学习第七天:线程属性 | 互斥锁 | 死锁 | 信号量 核心知识点 + 踩坑实战
linux·c语言·笔记·vscode·学习
Romantic_love_2 小时前
USART串口初始化源码解析
stm32·单片机·嵌入式硬件·学习
小雪崩2 小时前
嵌入式学习 day33:线程进阶
linux·c语言·学习
MartinYeung53 小时前
[论文学习]AI-Trader:实时金融市场中自主代理的基准测试
人工智能·深度学习·学习
懿路向前3 小时前
【HarmonyOS学习笔记】2026-08-27 | 端插件踩坑与设计取舍
笔记·学习·harmonyos
QuZhengRong3 小时前
【AI】Agent 全栈进阶|Agent 设计模式
人工智能·学习·设计模式·llm·agent