游戏设计模式笔记(一)[自用]

2023-11-06

目录

学习内容

学习笔记

设计模式简介(Design Pattern)

单例模式的学习

第一种方式

第二种方式

第三种方式

单例模式的优点


学习内容

  1. 设计模式简介(Design Pattern)
  2. 单例模式的学习
  3. 单例模式的优点

学习笔记

设计模式简介(Design Pattern)

  • 解决共通的问题
  • 归纳相同的解决方案
  • 类结构和组装方式
  • 高复合度与组合使用

单例模式的学习

下面先以不使用单例模式的情况下为案例,创建一个玩家(Player)脚本

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

public class Player: MonoBehaviour
{
    //取名
    string name_ = "player";

    //sayHello方法
    public void sayHello()
    {
    Debug.LogError("I am" + name_);
    }
}

再创建一个敌人(Enemy)脚本

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

public class Enemy : MonoBehaviour
{
    //定义游戏体
    GameObject player;
    Player playerItem;

    void Start()
    {
        //主角游戏体名假定为"Player"
        player = GameObject.Find("Player");
        playerItem = player.GetComponent<Player>();
    }

    void Update()
    {
        Debug.Log(player.transform.position);
        //Update实时更新获取组件的消耗过大
        //player.GetComponent<Player>().sayHello;
        playerItem.sayHello();
    }
}

但是我们会发现,假设我们有多个需要Find我们的主角的游戏体,那我们在每个脚本中都会定义类似的变量 ,甚至相同的方法。这样会增加我们的工作量,同时代码冗余大,且在后期的维护中会造成不便 。


那我们现在使用三种单例模式,来完成这个案例

第一种方式

玩家(Player)脚本

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

///<summary>
///
///<summary>
public class Player : MonoBehaviour
{
    //定义主角类的一个单实例
    public static Player instance;

    //取名
    string name_ = "player";

    private void Awake()
    {
        instance = this;
    }

    //sayHello方法
    public void sayHello()
    {
        Debug.LogError("I am" + name_);
    }
}

敌人(Enemy)脚本

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

public class Enemy : MonoBehaviour
{
    //定义游戏体
    //GameObject player;
    //Player playerItem;

    void Start()
    {
        //主角游戏体名假定为"Player"
        //player = GameObject.Find("Player");
        //playerItem = player.GetComponent<Player>();
    }

    void Update()
    {
        Debug.Log(Player.instance.transform.position);
        //Update实时更新获取组件的消耗过大
        //player.GetComponent<Player>().sayHello;
        Player.instance.sayHello();
    }
}

 这样是不是节省了很多代码  ଘ(੭ˊᵕˋ)੭  !

但是它也是并不是完美的。假设我们的游戏中有多个单例,由于在多个单实例的情况下,我们对其进行初始化,但我们不知道哪个Awake会被先执行(不过可以通过编辑器进行设置),所以获取属性可能会出现问题。


第二种方式

玩家(Player)脚本

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

///<summary>
///
///<summary>
public class Player : MonoBehaviour
{
    //定义主角类的一个单实例
    static Player instance;

    //Instance作为属性
    public static Player Instance 
    {
        get
        {
            if (instance == null)
            {
                //创建该类
                instance = FindObjectOfType<Player>();
            }
            FindObjectOfType没有找到该类的情况
            //if (instance == null)
            //{
            //    GameObject obj = new GameObject();
            //    obj.AddComponent<Player>();
            //    //下面两种都行
            //    //instance = FindObjectOfType<Player>();
            //    instance = obj.GetComponent<Player>();
            //}
                return instance;
        }
    }

    //取名
    string name_ = "player";

    private void Awake()
    {       
        //instance = this;
    }

    //sayHello方法
    public void sayHello()
    {
        Debug.LogError("I am" + name_);
    }
}

将原先的instance私有化,用新定义的属性Instance来获取以及调用。

敌人(Enemy)脚本

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

public class Enemy : MonoBehaviour
{
    //定义游戏体
    //GameObject player;
    //Player playerItem;

    void Start()
    {
        //主角游戏体名假定为"Player"
        //player = GameObject.Find("Player");
        //playerItem = player.GetComponent<Player>();
    }

    void Update()
    {
        //Debug.Log(Player.instance.transform.position);
        Update实时更新获取组件的消耗过大
        player.GetComponent<Player>().sayHello;
        //Player.instance.sayHello();
        Debug.Log(Player.Instance.transform.position);
        Player.Instance.sayHello();
    }
}

只要将instance替换成Instance即可

这样就不会像第一种方式那样,去担心调用的时候是否以及被实例化了 。


第三种方式

创建一个单例模板SingleTon<T>类

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

///<summary>
///
///<summary>
public class SingleTon<T> : MonoBehaviour where T:SingleTon<T>
{
    private static T _instance;

    public static T Instance
    {
        get 
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType(typeof(T)) as T;
                if (_instance == null)
                {
                    GameObject obj = new GameObject();
                    //隐藏实例化的new game object
                    //obj.hideFlags = HideFlags.HideAndDontSave;
                    _instance = obj.AddComponent<T>();
                }
            }
            return _instance;
        }    
    }
}

通过泛型做到一个模板类里,这样就不需要再之后其他的类中重新写

obj.hideFlags = HideFlags.HideAndDontSave;

开启时,实例会隐藏,且切换场景实例会消失不会保留。

修改玩家(Player)脚本

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

///<summary>
///
///<summary>
public class Player : SingleTon<Player>
{
    定义主角类的一个单实例
    //static Player instance;

    Instance作为属性
    //public static Player Instance 
    //{
    //    get
    //    {
    //        if (instance == null)
    //        {
    //            //创建该类
    //            instance = FindObjectOfType<Player>();
    //        }
    //        FindObjectOfType没有找到该类的情况
    //        //if (instance == null)
    //        //{
    //        //    GameObject obj = new GameObject();
    //        //    obj.AddComponent<Player>();
    //        //    //下面两种都行
    //        //    //instance = FindObjectOfType<Player>();
    //        //    instance = obj.GetComponent<Player>();
    //        //}
    //            return instance;
    //    }
    //}

    //取名
    string name_ = "player";

    private void Awake()
    {       
        //instance = this;
    }

    //sayHello方法
    public void sayHello()
    {
        Debug.LogError("I am" + name_);
    }
}

此时Player里面的Instance已经继承了父类,故不需要再次创建,也可以在敌人(Enemy)脚本被调用。


单例模式的优点

  • 同时间只存在一个对象
  • 快速获取对象的方法
  • 适合游戏中单一功能的管理器
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

游戏设计模式笔记(一)[自用] 的相关文章

  • 通过 Active Directory 搜索进行有效分页

    在 NET 中使用 Active Directory 搜索进行分页的有效方法是什么 在 AD 中进行搜索的方法有很多 但到目前为止我找不到如何有效地进行搜索 我希望能够表明Skip and Take参数并能够检索结果中与我的搜索条件匹配的记
  • 异步回调到BackgroundWorker

    我想使用 NET FTP 库 http netftp codeplex com http netftp codeplex com 该库提供 BeginOpenRead string AsyncCallback object 使用异步编程模型
  • 在 MS word .docs 中插入 MathMl 、 Tex 或 LaTex 方程?

    我一直在寻找 C 中 Net 的一些 dll 用于在 MS Word 中插入任何 MathMl Tex 或 LaTex 方程 我尝试了一些类似 DocX 的工具 但它们失败了 你知道吗 或任何提示如何做到这一点 谢谢 Word 2007 可
  • 使用 C# 使用证书进行 SSL 客户端身份验证

    我需要创建一个 C 应用程序 该应用程序必须使用 SSL 向服务器发送 API 请求 我需要创建客户端身份验证 我已经拥有服务器 CA 证书 客户端证书 cer 客户端私钥 pem 和密码 我找不到有关如何创建客户端连接的示例 有人可以建议
  • 获取在 Unity 中实现接口的所有类型

    如果您只想知道解决方案 请跳至更新 我有一个应用程序 它使用以下代码来获取并运行许多工作方法 var type typeof IJob var types AppDomain CurrentDomain GetAssemblies Sele
  • Microsoft.Web.Administration 内存泄漏

    拥有一个 Windows 服务 除其他外 还可以监视 IIS 应用程序池 如果任何池已配置应用程序但未运行 则该池 池 将启动 这已经运行良好一段时间了 最近发现该服务存在内存泄漏 查看内存转储 罪魁祸首是用于检查应用程序池的 Micros
  • 如何在 VS 2013 的立即窗口中执行 LINQ 和/或 foreach?

    在调试过程中探测当前状态时 立即窗口是非常有用的工具 我了解到 通过使用问号 人们可以在那里做更多的事情 如图所示在这篇文章中 https stackoverflow com questions 32934635 execute metho
  • 检查文件是真实文件还是符号链接

    有没有办法使用 C 来判断文件是真实文件还是符号链接 我已经挖过了MSDN W32 文档 https learn microsoft com en us windows win32 fileio file management functi
  • 如何从 nuget 包中排除子目录和内容

    所以我有一个网站正在尝试打包用于 Octopus Deploy 我有以下文件夹结构 Web Views WantThis Dontwantthis WantThis1 WantThis2 lots more Scripts 我试图排除 Do
  • 未构建 csproj 时抑制 AfterBuild 目标

    我在 MSBuild 中有一个构建后目标来复制一些构建输出 这是 linkedin 作为对AfterBuild目标 暴露于Microsoft CSharp targets
  • send() 使我的程序崩溃

    我正在运行服务器和客户端 我正在我的计算机上测试我的程序 这是服务器中向客户端发送数据的函数 int sendToClient int fd string msg cout lt lt sending to client lt lt fd
  • 将二维整数作为 Readonly/const 存储在单独的类中,同时保持非公开

    这是我在使用这个地方作为我的 去处 以获取关于什么有效 无效 为什么等的一般意见之后的第一个问题 那么让我们试试这个 由于我的经验有限 我一直在尝试寻找更好的方法来创建固定数据字段 我可以在整个程序中引用这些字段 例如我反复显示的最终用户可
  • 根据值更改 DataGrid 单元格颜色

    我有一个 WPF 数据网格 我想要根据值使用不同的单元格颜色 我的 xaml 上有以下代码 Style TargetType DataGridCell 但不是只选择一个单元格而是选择所有行 我缺少什么 如果您尝试设置DataGrid Cel
  • C# 如何在没有 GacUtil 的情况下在 GAC 中注册程序集?

    我需要使用批处理文件在 GAC 中注册程序集 有没有办法找到安装位置GacUtil exe或者有没有办法在没有 GacUtil 的情况下注册程序集 Your bestbet is to use a powershell script tha
  • 了解C/C++中函数调用的堆栈框架? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我也是 C C 和汇编语言的新手 这
  • allocator.construct 循环是否等于 std::uninitialized_copy?

    在此背景下T是某种类型并且allocator是该类型的分配器对象 默认情况下是std allocator
  • cygwin $'\r':命令未找到错误

    我稍微修改了一个项目 在调试下它运行得很好 当我尝试在不调试的情况下构建它时 它显示错误 无法修复它 make Making all in third party make 1 Entering directory cygdrive c U
  • 如何使 RSACryptoServiceProvider 在没有填充(nopadding)的情况下工作?

    我需要使 C 应用程序与 Java 应用程序兼容 Java 应用程序使用Cipher getInstance RSA ECB nopadding 初始化器使密码 ECB 和无填充 但是 在 C 中 您有 2 个填充选项 OAEP 填充或 P
  • 什么时候适合在 C++ 中使用 static(在未命名的命名空间上)?

    我一整天都在阅读有关未命名命名空间的文章 大多数文章都解释了何时应该在 static 关键字上使用未命名命名空间 但我仍然有一个大问题什么时候适合使用静态 毕竟它还没有完全弃用 那么带有静态函数的头文件我现在应该将它们放入未命名的命名空间中
  • C# 多重继承

    目前我正在学习 C 和 ASP NET MVC 4代码优先方法 我是 Visual Basic 开发人员 现在我想开始 C 而且 现在我遇到了必须管理多重继承的情况 但是 对于Class i来说这是不可能的 那么 我应该如何管理我拥有的这些

随机推荐

  • Microsoft Dynamics的五种关键能力

    1 集成通信与协作 您需要在工程部门 制造部门和分包商间进行同步通信 例如 如果工程部门改变了设计 运营部门应该立即知道有关的详细情况 您的通信解决方案需要同 ERP 系统相集成 以确保分包商能够支持工程部门在敏捷性方面的提高 产品数据管理
  • 集成开发环境:IDE

    集成开发环境 IDE IDE Integrated Development Environment 是用于提供程序开发环境的应用程序 一般包括代码编辑器 编译器 调试器和图形用户界面等工具 集成了代码编写功能 分析功能 编译功能 调试功能等
  • 机器学习(2)——鸢尾花数据集

    在上次房价数据集中做出一些改进 对鸢尾花数据集进行预测 需要导入的库 from sklearn datasets import load iris 导入鸢尾花数据集 from sklearn linear model import Logi
  • spark安装运行在webUI界面不显示worker

    spark conf spark env sh 文件中需要显式地设置一些环境变量 不用系统默认值 亲测 ubuntu16 04系统 spark env sh中手动配置 export JAVA HOME lt gt jdk1 8export
  • 33. 实战:实现某网站店铺信息的查询与批量抓取(附源码)

    目录 前言 目的 思路 代码实现 1 请求URL 获取源代码 2 解析源代码 获取数据 3 完善保存数据的函数save data 4 理清main函数逻辑 循环传递每一页有效信息的参数 完整代码 运行效果 总结 前言 近日 我们每周四都能刷
  • C#类与结构体的区别

    C 中类 class 与结构体 stract 的区别 1 类是引用类型 结构体是值类型 2 结构体不支持继承 但可以实现接口 类即支持继承也能实现接口 3 结构体中不可以声明无参的构造函数 4 结构体不能定义析构函数 5 结构体不可用作其他
  • 关于json数据的写入(write())必须为str类型及写入后双引号“变为‘号问题

    1 原始json数据 text 黎城县东崖底中心校学生用床购置项目成交公告 label 1 duoyu 0 text 淮南师范学院采购2017年智库项目 科研建设项目 学科及科技创新平台项目 1包 中标公示 label 1 duoyu 0
  • SpringBoot对接微信小程序支付功能开发(二,支付回调功能)

    接着上一篇 SpringBoot对接微信小程序支付功能开发 一 下单功能 在上一篇下单功能中我们有传支付结果回调地址 下面是回调接口实现 package com office miniapp controller import cn hut
  • Blender材质贴图入门图文教程

    推荐 将 NSDT场景编辑器 加入你的3D开发工具链 大家好 今天跟大家分享Blender材质贴图入门图文教程 一套blender的PBR材质包 和HDRI环境纹理贴图 在文末领取 希望能助到大家更高效完成场景练习 据我了解 越来越多人开始
  • Redis、Redission实现分布式锁

    Redis实现 使用spring data redis提供的接口实现redis分布式锁
  • kali使用aircrack无线攻击wifi超详细步骤(包含监听网卡启动,获得握手包,密码本生成)

    平台及工具 linux kali平台 aircrack ng 工具 免驱监听网卡 详细操作 1 首先启动kali 插入网卡 输入ifconfig查看kali是否检测到监听网卡 注意监听网卡要免驱动的 ifconfig 查看自身网卡信息 如图
  • React lazyLoad懒加载

    在React中使用lazy懒加载 效果图 目录结构 index js import React from react import ReactDOM from react dom import App from App import Bro
  • PID算法与PID自整定算法

    PID算法与PID自整定算法 本文是由于研发恒温槽项目故需要了解PID控制算法和PID自整定算法 为方便本人日后需要故作此记录 直接粘贴代码吧 这是PID位置式控温算法 函数名 void Pid positional float speed
  • 【Qt教程】4.1 - Qt5 文件系统 QFile文件读写操作

    1 Qt文件系统简介 QFile 文件系统是应用程序必不可少的部分 Qt作为一个通用开发库 提供了跨平台的文件操作能力 Qt通过 QIODevice 提供了对I O设备的抽象 使这些设备具有读写字节块的能力 在所有的I O设备中 文件I O
  • java forName() 方法

    forName 方法会进行类加载 将MyClass装在到JVM上 静态代码块 在类加载时执行 且只执行一次 如果你只想执行一个类的静态代码块 其它代码不执行 可以使用forName 方法 package leetcode0606 refle
  • Mybatis:传参+提交事务(自动or手动)+sql多表关联查询(两种方法)

    目录 一 参数两种类型 二 传参的几种方法 三 提交事务 四 sql多表关联查询 两种方法 一 参数两种类型 1 参数 预编译方式 更安全 只用于向sql中传值 select from admin where account account
  • Buuctf(Easy Calc 1)

    一 解题步骤 1 发现了一个可以得到计算结果的输入框 说明这题可能是一道命令执行 或者注入题目 我们输几个数字发现可以得到正确答案 但输入字母就会报错 我们看一下html源码 进行代码审计
  • java给byte赋值_关于JAVA中Byte数据类型二进制赋值运算报错问题

    自从JDK7更新之后 新增了二进制变量的表示 支持将整数类型用二进制来表示 用0b开头 例如 byte b byte 0b1000 0001 short s short 0b1000 0000 0000 0001 新手在这个时候会遇到一个问
  • rabbitmq 客户端golang实战

    rabbitmq消息模式 rabbitmq中进行消息控制的组建可以分为以下几部分 exchange rabbitmq中的路由部件 控制消息的转发路径 queue rabbitmq的消息队列 可以有多个消费者从队列中读取消息 consumer
  • 游戏设计模式笔记(一)[自用]

    目录 学习内容 学习笔记 设计模式简介 Design Pattern 单例模式的学习 第一种方式 第二种方式 第三种方式 单例模式的优点 学习内容 设计模式简介 Design Pattern 单例模式的学习 单例模式的优点 学习笔记 设计模