经典游戏案例: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

相关推荐
EanoJiang8 分钟前
类蜘蛛侠+刺客信条暗杀动作系统开发日志
游戏
★YUI★1 小时前
学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
java·学习·游戏·unity·c#
谷宇.2 小时前
【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
游戏·unity·c#·游戏程序·unity3d·游戏开发·游戏编程
NRatel21 小时前
亚马逊S3的使用简记(游戏资源发布更新)
游戏·unity·amazon s3
天波信息技术分享1 天前
AI 云电竞游戏盒子:从“盒子”到“云-端-芯”一体化竞技平台的架构实践
人工智能·游戏·架构
小杨 想拼1 天前
使用js完成抽奖项目 效果和内容自定义,可以模仿游戏抽奖页面
前端·游戏
qq_546937272 天前
一款开源的远程桌面软件,旨在为用户提供流畅的游戏体验,支持 2K 分辨率、60 FPS,延迟仅为 40ms。
游戏
How_doyou_do2 天前
关于截屏时实现游戏暂停以及本地和上线不同步问题
游戏
李昕壑2 天前
CS2服务器是何方神圣
游戏
wanhengidc2 天前
云手机选哪个比较好用?
服务器·网络·安全·游戏·智能手机