经典游戏案例:unity官方推荐3d跑酷

学习目标:实现跑酷核心算法

游戏画面

项目结构目录

部分核心代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 游戏管理器是一个状态机,根据当前的游戏状态,它将在状态之间切换。
/// </summary>
public class GameManager : MonoBehaviour
{
    /// <summary>
    /// 单例模式
    /// </summary>
    public static GameManager instance { get { return s_Instance; } }
    protected static GameManager s_Instance;

    public AState[] states;
    //返回栈顶的游戏状态
    public AState topState { get { if (m_StateStack.Count == 0) return null; return m_StateStack[m_StateStack.Count - 1]; } }
    //消耗品数据库
    public ConsumableDatabase m_consumableDatabase;
    //游戏状态栈
    protected List<AState> m_StateStack = new List<AState>();
    //游戏状态字典
    protected Dictionary<string, AState> m_StateDict = new Dictionary<string, AState>();
    //函数执行顺序:awake onenable start
    protected void OnEnable()
    {
        PlayerData.Create();
        s_Instance = this;

        m_consumableDatabase.Load();
        m_StateDict.Clear();

        if (states.Length == 0)
        {
            return;
        }
        //初始化游戏状态字典
        for (int i = 0; i < states.Length; ++i)
        {
            states[i].manager = this;
            m_StateDict.Add(states[i].GetName(), states[i]);
        }

        m_StateStack.Clear();
        PushState(states[0].GetName());
    }

    protected void Update()
    {
        if (m_StateStack.Count > 0)
        {
            m_StateStack[m_StateStack.Count - 1].Tick();
        }
    }

    #region 游戏状态管理
    /// <summary>
    /// 游戏状态间的切换
    /// </summary>
    /// <param name="newState"></param>
    public void SwitchState(string newState)
    {
        AState state = FindState(newState);
        if(state == null)
        {
            Debug.LogError("Can't find the state named " + newState);
            return;
        }
        
        m_StateStack[m_StateStack.Count - 1].Exit(state);
        state.Enter(m_StateStack[m_StateStack.Count - 1]);
        m_StateStack.RemoveAt(m_StateStack.Count - 1);
        m_StateStack.Add(state);
    }
    /// <summary>
    /// 返回上一步游戏状态,并移除栈顶游戏状态
    /// </summary>
    public void PopState()
    {
        if (m_StateStack.Count < 2)
        {
            Debug.LogError("Can't pop states, only one in stack.");
            return;
        }

        m_StateStack[m_StateStack.Count - 1].Exit(m_StateStack[m_StateStack.Count - 2]);
        m_StateStack[m_StateStack.Count - 2].Enter(m_StateStack[m_StateStack.Count - 2]);
        m_StateStack.RemoveAt(m_StateStack.Count - 1);

    }
    /// <summary>
    /// 进入新的游戏状态,并将其入栈
    /// </summary>
    /// <param name="name"></param>
    public void PushState(string name)
    {
        AState state;
        if(!m_StateDict.TryGetValue(name,out state))
        {
            Debug.LogError("Can't find the state named " + name);
            return;
        }

        if (m_StateStack.Count > 0)
        {
            m_StateStack[m_StateStack.Count - 1].Exit(state);
            state.Enter(m_StateStack[m_StateStack.Count - 1]);
        }
        else
        {
            state.Enter(null);
        }
        m_StateStack.Add(state);
    }

    /// <summary>
    /// 在字典中查找游戏状态
    /// </summary>
    /// <param name="statename"></param>
    /// <returns></returns>
    public AState FindState(string statename)
    {
        AState state;
        if (!m_StateDict.TryGetValue(statename, out state)){
            return null;
        }
        else
        {
            return state;
        }
    }
    #endregion
}
/// <summary>
/// 游戏状态,用栈结构来存放
/// </summary>
public abstract class AState:MonoBehaviour
{
    [HideInInspector]
    public GameManager manager;
    /// <summary>
    /// 进入目标游戏状态前要执行的操作
    /// </summary>
    /// <param name="from">从哪个状态进入</param>
    public abstract void Enter(AState from);
    /// <summary>
    /// 离开目标游戏状态后要执行的操作
    /// </summary>
    /// <param name="to"></param>
    public abstract void Exit(AState to);
    /// <summary>
    /// 在目标游戏状态中要执行的操作
    /// </summary>
    public abstract void Tick();
    /// <summary>
    /// 获取游戏状态名(返回字符串)
    /// </summary>
    /// <returns></returns>
    public abstract string GetName();
}

下载链接:https://gitee.com/unity_demo/carzy-dash

相关推荐
数智工坊5 小时前
【深度学习RL】DQN:深度强化学习的里程碑——让AI从像素中学会玩Atari游戏
论文阅读·人工智能·深度学习·游戏·transformer
2601_956002816 小时前
gta侠盗猎车手5 2026最新绿色破解版免费下载 pc版 手机版通用
游戏·智能手机·游戏程序·团队开发·游戏美术·数字雕刻·关卡设计
德迅云安全-小潘6 小时前
游戏行业如何保障网络安全
服务器·网络·游戏
上海云盾第一敬业销售6 小时前
游戏开服即“炸服“?CC攻击成游戏行业隐形杀手
服务器·网络·游戏
资源分享助手15 小时前
小马游戏 Horsey Game 下载与介绍(老番茄推荐)
游戏
阿斯加德D1 天前
天国:拯救 2风灵月影修改器下载(已汉化)2026最新版下载分享
测试工具·游戏·3d·游戏程序
YF02111 天前
Android 物理摇杆按键映射技术详解
android·游戏
li星野1 天前
双指针 & 贪心算法六题通关:从回文串到跳跃游戏(Python + C++)
python·游戏·贪心算法
无人装备硬件开发爱好者2 天前
STM32G474 + 1.32 寸 OLED(128×96)俄罗斯方块游戏实现指南
stm32·嵌入式硬件·游戏
小清兔2 天前
Addressable的设置打包流程
笔记·游戏·unity·c#