【Unity研究】进程、线程、对象池的关系

2023-10-26

目录

简要概括

名词解释

实例

进程

线程

对象池

实际使用

对象池实际操作(含代码)

建立主线程以外的线程方法

在主线程中运行的生命周期

在副线程中运行的生命周期


简要概括

正在运行的Unity游戏就可以看做一个进程的实例,线程是进程内的执行单元(一个进程可以拥有多个线程),Unity游戏中的详细操作是在同一个进程里的中执行的。

名词解释

实例

“实例”指具体的实际存在的单个对象或者事物。在计算机中,进程就是程序的实例,也就是指程序在某个时间段内的运行过程。

进程

进程(Process)是计算机中正在运行的一个程序或任务的实例。在操作系统中,进程是资源分配的基本单位,每个进程都拥有自己独立的内存空间和系统资源,包括CPU、内存、文件、网络连接等。进程的出现是为了解决多道程序同时运行的冲突问题,通过将系统资源分配给多个进程,提高了计算机系统的效率和可用性。

每个进程都有自己的地址空间,包括代码段、数据段、堆和栈。堆和栈是两种不同的内存分配方式,堆用于动态分配内存,而栈则用于管理函数调用和变量分配。进程之间是相互独立的,可以并行运行,并且通过IPC和共享内存等方式进行通信和数据交换。

操作系统通过进程调度算法决定何时和如何切换进程,以保证每个进程都能得到足够的运行时间和系统资源,并且根据进程的优先级和状态等进行调度。进程的状态通常包括运行态、就绪态、等待态和终止态等。操作系统通过进程管理来保证系统的稳定性和安全性,防止进程之间的冲突和竞争,提高了计算机系统的效率和可靠性。

线程

线程是进程内的执行单元,一个进程可以拥有多个线程,每个线程都是独立的执行流。在Unity的代码中,update是在主线程中被执行的,不是在单独的线程中,而销毁物品等操作也是在主线程中执行的。

对象池

为了减少线程压力而创造的方法。

实际使用

对象池实际操作(含代码)

简单来说,对象池就是个含有list的类,而list也就是所谓的对象池的“池子”。

将需要操作的物品放在list中,然后隐藏。

需要使用对象的时候从对象池拿出对象,也就是显示物品。

不需要的时候放回,也就是隐藏物品。

彻底不需要时销毁(destroy),释放内存,并将对象从池子中移除。

对象池:

public class EnemyPool
{
    private List<GameObject> enemyPool;
    private GameObject enemyPrefab;
    private int poolSize;

//创建对象池;更新对象池对象
    public EnemyPool(GameObject prefab, int size)
    {
        enemyPrefab = prefab;
        poolSize = size;
        enemyPool = new List<GameObject> ();

        for (int i = 0; i < poolSize; i++) {
            GameObject enemy = GameObject.Instantiate(enemyPrefab) as GameObject;
            enemy.SetActive(false);
            enemyPool.Add(enemy);
        }
    }
//从对象池中拿出对象
    public GameObject GetEnemy()
    {
        foreach (GameObject enemy in enemyPool) {
            if (!enemy.activeInHierarchy) {
                enemy.SetActive(true);
                return enemy;
            }
        }

        GameObject newEnemy = GameObject.Instantiate(enemyPrefab) as GameObject;
        newEnemy.SetActive(true);
        enemyPool.Add(newEnemy);

        return newEnemy;
    }
//放回对象
    public void ReleaseEnemy(GameObject enemy)
    {
        enemy.SetActive(false);
    }
}

实际使用:

public class GameManager : MonoBehaviour
{
    public GameObject enemyPrefab;
    public int enemyPoolSize;

    private EnemyPool enemyPool;

    private void Start ()
    {
        enemyPool = new EnemyPool(enemyPrefab, enemyPoolSize);
    }

    private void Update () 
    {
        //从对象池中获取敌人对象
        GameObject enemy = enemyPool.GetEnemy();

        //对敌人对象进行操作
        enemy.transform.position += Vector3.forward * Time.deltaTime;

        //将敌人对象放回对象池中
        enemyPool.ReleaseEnemy(enemy);
    }
}

为什么要用对象池?

对象池可以使应用程序更高效地利用有限的线程资源,相比起“在编辑器里就把所有物品放到场景中”和“在游戏开始时实例化所有物品(这个方法会让游戏卡顿)”,对象池能动态操控物品的出现和隐藏。

线程效率受内存限制,而物体的实例化、销毁、隐藏显示都在线程中进行,为了节省资源,我们要尽量减少一次性的操作数量。

使用对象池,需要考虑的东西:物品创建和销毁的时机

物品创建时机:可以在游戏加载时一次性创建所有需要的物品对象,或者等到玩家进入游戏世界后,根据需要动态创建。

物品销毁时机:当物品离开玩家的视野范围时,可以将其销毁,或者等到玩家不再需要该物品时再销毁。

对象池的大小:需要考虑在游戏中最大需要创建的物品数量,确定对象池的大小。对象池的大小应该不要过小,否则可能会频繁地创建和销毁物品对象,造成性能损失。(不过用list就不用考虑这一点了,使用数组才需要考虑,用list只需要在不需要物品时及时把物品移出对象池)

对象池的回收和重复利用:一旦物品被销毁,其所占用的资源应该被释放,并将该物品对象重新放回对象池中,以便下次重复利用。

建立主线程以外的线程方法

1.Thread类

示例:

using System;
using System.Threading;

public class Program
{
    static void Main(string[] args)
    {
        // 创建一个新线程
        Thread newThread = new Thread(Compute);

        // 启动线程
        newThread.Start();

        // 在主线程中执行一些其他操作
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread is running.");
            Thread.Sleep(100);
        }
    }

    static void Compute()
    {
        // 在新线程中执行一些计算密集型的操作
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("New thread is running.");
            Thread.Sleep(100);
        }
    }
}

2.异步

3.协程(Coroutine类)

4.Job System

Job System是Unity自带的,可以使游戏逻辑转移到多线程中执行。使用Job、JobHandle和JobQueue等组件来管理和调度任务。

5.Entity Component System (ECS)

ECS是Unity中的一种数据驱动的编程模式,可以将游戏逻辑从主线程转移到其他线程中执行,并行处理大量数据。

6.Native Plugin

使用Native Plugin可以在C++或其他编程语言中编写独立于Unity的多线程代码,然后将其集成到Unity中。使用该方法可以获得更高的性能和更灵活的控制。

在主线程中运行的生命周期

  1. Awake()
  2. Start()
  3. Update()
  4. FixedUpdate()
  5. LateUpdate()
  6. OnGUI()
  7. OnDisable()
  8. OnEnable()
  9. OnDestroy()

在副线程中运行的生命周期

  1. OnApplicationFocus()
  2. OnApplicationPause()
  3. OnApplicationQuit()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Unity研究】进程、线程、对象池的关系 的相关文章

  • c#获取cpu序列号

  • Unity 粒子特效、材质发光 HDR ShaderGraph图文教程[完成lit发光设置]

    效果如图 准备工作 在hdr模式下 关闭Directional Light 相机设置 移动球挂一个点光源作为子节点 设置自行调节 0 创建移动球的材质及shader shader gt 在Project Create Shader Grap
  • Unity-AR 简介

    Unity AR 简介 现有Unity AR Sdk ARKit 苹果推出的AR开发平台 ARCore Google 推出的增强现实 SDK ARFoundation ARFoundation是ARKit XR插件和ARCore XR插件
  • UnityVR--组件3--Line Renderer--线性渲染

    目录 线性渲染组件简介 绘制线条Line Renderer组件介绍 绘制拖尾Trail Renderer组件介绍 应用1 使用Line Renderer绘制线段 应用1实现 使用系统工具或自定义工具绘制线段 应用2 Trail Render
  • Unity之获取游戏物体对象或组件的几个方法

    文章目录 前言 通过物体名称获取对象 GameObject Find Transform Find 通过物体标签获取对象 GameObject FindWithTag GameObject FindGameObjectWithTag Gam
  • 【IMGUI】 各种辅助类 EditorGUIUtility、EditorUtility、GUIUtility、GUILayoutUtility

    EditorGUIUtility class in Editor 继承自 GUIUtility EditorGUI 的各种辅助程序 EditorGUIUtility currentViewWidth 我尝试打印了下这个值和position
  • Unity打开工程时卡住的问题

    自从Unity升级了一个版本后 Unity打开工程卡住的问题越来越严重了 具体表现为 选择工程后 Unity窗口消失 但进程还在 有时候等个几分钟能出来 有时候等10分钟都不见得能出来 直观感受上看 似乎是Unity加载工程的时候某一步卡了
  • unity3d大型互动照片墙

    1 本次应客户需求 制作一个大型照片墙互动 输出分辨率为9600 4320 注 unity3d官方推荐最大分辨率为8192 3686 4 经过现场长达24小时暴力测试中途未发生问题 姑且判定可以达到正常标准 废话不多说 先上效果 unity
  • Unity保存图片到相册

    Unity保存图片到Android相册 Java 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
  • unity实现鼠标右键控制视角

    主要实现的功能是相机跟随主角 鼠标右击移动后 相机的视角会旋转 思路 在主角里创建空的子物体 把相机绑在空物体上 通过旋转空物体来实现视角的旋转 要把相机调整到适当位置 代码如下 public float rotateSpeed 100 设
  • Unity万向节死锁解决方案(2023/12/4)

    1 万向节死锁无法解决 这是因为它的特性就是如此 就像玻璃杯就是玻璃 这不可否认 别钻牛角尖昂 2 大多数情况下欧拉角足够用 例如 CF 摄像机不可能绕z轴旋转 x轴旋转也不会超过九十度 因为那样人物的腰子会被扭断 塔防游戏 保卫萝卜 吃鸡
  • unity3d 自定义的图片无法放入source image中

    须将图片的texture type改为 sprite
  • unity小球跟随音乐节奏放大缩小和改变颜色

    放在小球身上 设置对应组件即可 using System Collections using System Collections Generic using Unity VisualScripting using UnityEngine
  • 【Unity】如何让Unity程序一打开就运行命令行命令

    背景 Unity程序有时依赖于某些服务去实现一些功能 此时可能需要类似打开程序就自动运行Windows命令行命令的功能 方法 using UnityEngine using System Diagnostics using System T
  • Unity中URP下的指数雾

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • VS2022 | 显示Unreal Engine日志

    VS2022 显示Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发常见操作梳理之NPC药品商店系统(NGUI版)

    后续会出UGUI Json的版本 敬请期待 游戏开发中经常会出现药品商店 实际操作与武器商店类似 甚至根据实际情况可以简化设置 废话不多说 直接上代码 药品商店的源码 using System Collections using Syste
  • 游戏开发常见操作梳理之角色选择一

    进入游戏后 我们经常会进入角色选择的界面 通常是左右两个按钮可以更改角色供玩家选择 对于这种界面我们通常使用数据持久化将角色信息存储起来 接下来的笔记中 我将使用自带的数据持久化系统对其进行操作 实现角色的选择页面 后续会更新xml系列的文

随机推荐

  • 【HDLBits 刷题 10】Circuits(6)Finite State Manchines 10-17

    目录 写在前面 Finite State Manchines Lemmings1 Lemmings2 Lemmings3 Lemmings4 Fsm onehot Fsm ps2 Fsm ps2data Fsm serial 写在前面 HD
  • LeetCode922. 按奇偶排序数组 II

    LeetCode922 按奇偶排序数组 II 给定一个非负整数数组 A A 中一半整数是奇数 一半整数是偶数 对数组进行排序 以便当 A i 为奇数时 i 也是奇数 当 A i 为偶数时 i 也是偶数 你可以返回任何满足上述条件的数组作为答
  • protobuf 中数据编码规则

    背景 protobuf 是一种跨平台的序列化结构数据的方法 可用于网络数据传输及存储 protobuf 在生成的 C 代码中为 proto 文件中的每个 message 生成了对应的 C 类 并提供了数据成员的读写方法 本文对 protob
  • 以太网知识-GMII / RGMII接口

    今天和海翎光电的小编一起分析MII RMII SMII 以及GMII RGMII SGMII接口的信号定义 及相关知识 同时小编也对RJ 45接口进行了总结 分析了在10 100模式下和1000M模式下的连接方法 GMII 接口分析 GMI
  • 避免跨域的CDN部署方案

    我们的一个项目采用动静分离的部署方式 服务接口在自己的服务器上 静态资源保存在OSS 通过CDN访问 不过这样有时会有跨域问题 本文总结解决的办法 原来的做法 原本的做法 服务接口部署在自己的服务器上 通过域名api xxx com访问 不
  • 添加序号_Excel——合并单元格添加序号

    点击上方关注我们获取更多 在工作中 为了数据便于查看 经常需要将内容相同的单元格进行合并 在进行了批量合并单元格后 如何给合并单元格添加序号成为又一难点 今天就来和大家分享一下在EXCEL中如何给合并单元格添加序号 以下表数据 城市销售数据
  • UVA-806 空间结构 题解答案代码 算法竞赛入门经典第二版

    GitHub jzplp aoapc UVA Answer 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 一道遍历四叉树的题目 在遍历的同时还要记住路径 做一些额外的操作 题目本身并不难 但是格式要求较多 比如输出路径时12个就换行 不
  • 恶意代码检测理论(静态与动态分析基础)

    什么是恶意代码 恶意代码 malicious code 又称为恶意软件 malicious software Malware 是能够在计算机系统中进行非授权操作的代码 恶意代码类型 1 蠕虫或计算机病毒 可以自我复制和感染其他计算机的恶意代
  • Linux逆向 - Mirai-上

    Mirai Mirai 变种 资料 源码 Mirai源码 xd0ol1 Mirai 源码分析 https paper seebug org 142 绿盟 MIRAI源码分析报告 http blog nsfocus net mirai sou
  • C#中结构体排序方法(Array.sort() + ICompare)

    感觉C 比C 麻烦许多 资料也少 找了半天竟然没有找到一个能用的结构体排序 这是待排序的结构体 public struct la public int id public int sb 首先 C 需要调用一个空间 类似头文件 using S
  • 自学移动端(APP)自动化测试

    国庆已经过去了 新的一周已经开始了 各地疫情又开始出现复发了 我们能做的就是做好个人防护 去哪报备 到哪扫码亮码 主动做核酸 随时做好家里存储至少一周的食物 拒绝过度防疫 拒绝过度恐慌 拒绝过度焦虑 有工作的最起码还有钱能到手 没有工作的可
  • 万字长文深度剖析AIGC技术!(网络架构&自监督)

    作者 派派星 编辑 CVHub 点击下方卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 全栈算法 技术交流群 前景回顾 Welcome to back 在 万字长文带你解读AIGC入门篇 一文中 我们详
  • 计算机网络生活应用,浅谈计算机网络在生活中的应用

    摘要 进入21世纪科技高速发展 特别是计算机网络的进一步发展 计算机的应用更为普遍 计算机网络的应用已经渗透到社会的各个领域 正在日益改变着传统的工作 学习和生活的方式 推动着社会的科技发展 资源的共享 通信 这两种计算机网络最基本的功能在
  • elementUI的表格多选功能之规定禁止选择

    elementUI的el table表格多选功能之禁用多选 在进行表格的多选的时候我们会碰到那种 只允许部分内容可以被选择 不符合的要禁用多选框 这个时候就要用到elementUI el table的selectable 所以我们可以这样写
  • mysql导入sql文件、数据库时报错ERROR: ASCII '\0' appeared in the statement

    window环境下mysql导入sql文件时报错 ERROR ASCII 0 appeared in the statement 错误原因 文件编码不正确 解决办法 下载UltraEdia对文件进行转码 如果是使用powershell导出的
  • 计算机网络笔记整理2——物理层

    点此链接可跳转到 计算机网络笔记整理 目录索引页 参考书籍 计算机网络 第八版 谢希仁编著 文章目录 点此链接可跳转到 计算机网络笔记整理 目录索引页 物理层的基本概念 物理层接口的基本特性 数据通信的基础知识 信道的极限容量 信道能够通过
  • AODV协议概述

    AODV是由Nokia研究中心的Charles E Perkins和加利福尼亚大学Santa Barbara的Elizabeth M Belding Roryer以及Cincinnati大学Samir R Das等共同开发 已经被 IETF
  • JDBC总结

    JDBC 规范 Java DataBase Connectivity 标题 JDK 提供 Java链接数据库的规范 采用JDBC访问数据库的基本步骤 A 载入JDBC驱动程序 B 定义连接URL C 建立连接 D 创建Statement对象
  • 光纤工程的接续、施工与测试技术规范及要点

    1 光纤接续 1 光纤接续 光纤接续应遵循的原则是 芯数相等时 要同束管内的对应色光纤对接 芯数不同时 按顺序先接芯数大的 再接芯数小的 2 光纤接续的方法有 熔接 活动连接 机械连接三种 在工程中大都采用熔接法 采用这种熔接方法的接点损耗
  • 【Unity研究】进程、线程、对象池的关系

    目录 简要概括 名词解释 实例 进程 线程 对象池 实际使用 对象池实际操作 含代码 建立主线程以外的线程方法 在主线程中运行的生命周期 在副线程中运行的生命周期 简要概括 正在运行的Unity游戏就可以看做一个进程的实例 线程是进程内的执