Unity 从零开始的框架搭建1-3 关于命令模式的一些思考

Unity 从零开始的框架搭建1-2 事件的发布-订阅-取消的小优化及调用对象方法总结[半干货]-CSDN博客

本人水平有限 如有不足还请斧正,该文章专栏是向QFrameWork作者凉鞋老师学习总结得来,吃水不忘打井人,不胜感激

关于此模式我曾实现过,但是我看了凉鞋老师的课后有了一些思考C# x Unity 从玩家控制类去分析命令模式该如何使用_unity c# 命令模式-CSDN博客

0.场景引入

就比如场景中有一些敌人

有一些敌人被点击到了就消失有些就随机移动

引入ICommand

cs 复制代码
public interface ICommand 
{
   public void Execute();
}

实现Icommand

cs 复制代码
using UnityEngine;

public class Enemy : MonoBehaviour {
    private ICommand _moveCommand;
    private ICommand _destroyCommand;

    void Start() {
        _moveCommand = new MoveCommand(this);
        _destroyCommand = new DestroyCommand(this);
    }

    // 被点到就消失
    public void OnMouseDown() {
        if(this.CompareTag("EnemyR"))
            _moveCommand.Execute();
        else
        _destroyCommand.Execute();
    }
}
public struct MoveCommand : ICommand {
    private Enemy _enemy;

    public MoveCommand(Enemy enemy) {
        _enemy = enemy;
    }

    public void Execute() {
        float x = Random.Range(-5, 5);
        float z = Random.Range(-5, 5);
        _enemy.transform.position = new Vector3(x, 0, z);
    }
}

public struct DestroyCommand : ICommand {
    private Enemy _enemy;

    public DestroyCommand(Enemy enemy) {
        _enemy = enemy;
    }

    public void Execute() {
        Object.Destroy(_enemy.gameObject);
    }
}

1.ICommand类做到了什么?

这可能就要扯到MVC了,你一定要搞清楚M和C的区别

M:做任务的

C:控制的,下命令的

所以---------------------------------------------------------------------------------------------------------------------------

没有使用命令模式时:

• 模型(Model):Enemy类(包含了移动和销毁的逻辑)

• 视图(View):Unity中的3D物体(敌人)

• 控制器(Controller):Enemy类中的OnMouseDown方法(包含了与用户交互的代码)

使用命令模式后:

• 模型(Model):具体的命令类(例如MoveCommand和DestroyCommand)

• 视图(View):Unity中的3D物体(敌人)

• 控制器(Controller):Enemy类中的OnMouseDown方法(负责调用命令)


2.每次执行都去new会不会造成性能浪费?

我是说在这个场景之中,不得不去"new"对象

cs 复制代码
   void Update() {
       if (Input.GetMouseButtonDown(0)) {
           if (this.CompareTag("EnemyR")) {
               ICommand moveCommand = new MoveCommand(this);
               moveCommand.Execute();
           } else {
               ICommand destroyCommand = new DestroyCommand(this);
               destroyCommand.Execute();
           }
       }
   }

对比这篇文章:C# x Unity 从玩家控制类去分析命令模式该如何使用_unity c# 命令模式-CSDN博客

我在这里进行了小小的变动

原因: 内存上栈比堆快 AI说的

栈在内存分配和释放操作上比堆快,主要基于以下原因:

1. 分配机制

  • **栈的分配**:栈的内存分配非常简单直接,类似于往栈中压入数据。栈有一个栈顶指针,当有新的数据(如局部变量、函数调用信息等)需要存储时,栈顶指针移动相应的字节数,为新数据腾出空间。这个过程几乎不涉及复杂的查找或计算,是一个高效的线性操作。例如,在一个函数中定义一个 `int` 类型的局部变量,栈顶指针只需移动4字节(假设为32位系统),即可完成该变量的内存分配。

  • **堆的分配**:堆的内存分配则相对复杂。堆内存是一块连续的、较大的内存区域,但被分配出去的内存块大小不一且分布离散。当程序请求在堆上分配内存时,堆管理器需要遍历已分配和未分配的内存块列表,寻找一块大小合适的空闲内存块。如果没有恰好合适的内存块,可能还需要进行内存分割等操作。这种查找和处理过程会消耗更多的时间和资源。例如,在堆上分配一个动态数组,堆管理器需要找到足够大的连续内存空间,如果没有合适的,可能需要将一个较大的空闲块分割成满足数组大小的部分和剩余的空闲块。

2. 释放机制

  • **栈的释放**:栈的内存释放遵循后进先出(LIFO)原则,如同从栈中弹出数据。当一个函数执行结束,其对应的栈帧会被销毁,栈顶指针会恢复到函数调用前的位置,栈上为该函数局部变量等分配的内存空间自动被释放。这个过程不需要额外的复杂操作,直接移动栈顶指针即可,非常高效。例如,函数执行完毕后,函数内定义的局部变量(存储在栈上)所占用的内存会随着栈帧的弹出而立即释放。

  • **堆的释放**:堆上对象的内存释放较为复杂,尤其是在使用垃圾回收机制(如在C#、Java等语言中)的环境下。当一个对象不再被引用时,它不会立即被释放。垃圾回收器需要定期运行,通过标记 - 清除、复制、标记 - 整理等算法来识别和回收不再使用的对象。这个过程涉及到对整个堆内存的扫描、标记存活对象、移动和整理内存等操作,不仅会暂停应用程序的正常执行(产生"stop - the - world"现象),而且算法本身也比较复杂,消耗较多的CPU时间和资源。即使在手动管理内存的语言(如C++)中,释放堆内存也需要程序员手动调用 `delete` 或 `free` 等函数,并且要确保释放的时机和顺序正确,否则容易引发内存泄漏等问题。

3. 内存结构特点

**栈的结构**:栈的内存结构相对简单和紧凑,数据按照顺序依次存储在栈上,内存布局相对固定。这种简单的结构使得栈的内存管理效率高,访问速度快。例如,在栈上访问一个局部变量,由于其内存位置是在栈顶附近,根据栈顶指针和变量在栈帧中的偏移量,可以快速定位到变量的内存地址。

  • **堆的结构**:堆的内存结构较为复杂,由于频繁的分配和释放操作,容易产生内存碎片化问题。即堆中会出现许多不连续的空闲内存块,虽然总的空闲内存空间可能足够,但由于不连续,无法满足某些较大内存块的分配请求。为了应对碎片化问题,堆管理器需要额外的机制来管理和整理内存,这进一步增加了堆内存管理的复杂性和开销。

• struct是值类型,分配在栈上,通常会有更好的性能,特别是在频繁创建和销毁对象的情况下,因为它们不需要垃圾回收

• class是引用类型,分配在堆上,可能会导致更多的垃圾回收开销,特别是在频繁创建和销毁对象的情况下。

不信也没办法,我不知道怎么去追踪每一次点击之后:"上一个失去引用的对象 在 内存中被释放" 这个过程

相关推荐
步、步、为营40 分钟前
.NET 的IOC框架Unity代码示例
unity·游戏引擎·.net
Magnum Lehar1 小时前
wpf游戏引擎的script实现
游戏引擎·wpf
留待舞人归5 小时前
【Unity优化】提高热更新和打包速度
游戏·unity·游戏引擎·unity3d·优化
tealcwu5 小时前
【Unity踩坑】Unity 6在Mac平台编译运行时去除‘trial version‘
macos·unity·游戏引擎
为你写首诗ge6 小时前
【热更新知识】学习一 Lua语法学习
unity·lua
为你写首诗ge7 小时前
【热更新知识】学习三 XLua学习
unity·lua
程序员小刘9 小时前
如何开始HarmonyOS 5与Godot引擎融合开发?
华为·游戏引擎·godot·harmonyos
T.D.C17 小时前
【动画】Unity2D骨骼动画-Animation2D
unity·动画
AgilityBaby17 小时前
Unity实现不倒翁
笔记·unity·c#·游戏引擎
XR-AI-JK2 天前
Unity VR/MR开发-开发环境准备
unity·vr·mr