【学习笔记】unity脚本学习(五)【常用的方法函数Destroy、Instantiate 、SendMessage、invoke 、Coroutine】

news2024/9/21 12:29:08

目录

    • 常用的方法函数
      • Object体系结构
      • MonoBehaviour复习
        • 继承的变量
      • 继承自Object的方法
        • Destroy 物体的销毁
        • DestroyImmediate 立即销毁对象(强烈建议您改用 Destroy)
        • Object.DontDestroyOnLoad
        • Object.Instantiate 物体的生成
          • 类子弹生成案例
      • 继承自Component的方法
        • Component.CompareTag 比较tag
        • 消息推送
          • Component.SendMessage 消息推送
          • Component.SendMessageUpwards
          • Component.BroadcastMessage
          • 案例
      • MonoBehaviour的invoke方法
        • Invoke 延迟执行函数
        • InvokeRepeating
        • CancelInvoke
        • IsInvoking
      • MonoBehaviour的Coroutine方法
        • StartCoroutine 启动协程。
        • StopAllCoroutines
        • StopCoroutine
      • 小结

转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/130233098
视频参考 极客学院Unity3D视频精讲课程

常用的方法函数

Object体系结构

在这里插入图片描述
在这里插入图片描述
可以看到MonoBehaviour继承自Component,Component继承自Object

MonoBehaviour复习

MonoBehaviour官网API
之前学的start awake等都是Message事件响应函数,它们都是我们在脚本中直接使用的回调函数
在这里插入图片描述

继承的变量

在这里插入图片描述

继承自Object的方法

在这里插入图片描述

Destroy 物体的销毁

比较好懂

// 删除gameObject
Destroy(gameObject);
// Removes this script instance from the game object
Destroy(this);
// Removes the rigidbody from the game object
Destroy(GetComponent<Rigidbody>());
// Kills the game object in 5 seconds after loading the object 延迟删除)
Destroy(gameObject, 5);

注意:

  • 删除gameobject也会删除其下所有子物体

DestroyImmediate 立即销毁对象(强烈建议您改用 Destroy)

public static void DestroyImmediate (Object obj, bool allowDestroyingAssets= false);

  • obj 要销毁的对象。
  • allowDestroyingAssets 设置为 true 将允许销毁资源。
    该函数应只在编写 Editor 代码时使用,因为在编辑模式下, 永远不会调用延迟销毁。 在游戏代码中,您应该改用 Object.Destroy。Destroy 始终延迟进行 (但在同一帧内执行)。 使用该函数时要务必小心,因为它可以永久销毁资源! 另请注意,切勿循环访问数组并销毁正在迭代的元素。这会导致严重的问题(这是一条通用的编程实践,而不仅仅是在 Unity 中)。

Object.DontDestroyOnLoad

public static void DontDestroyOnLoad (Object target);
在加载新的 Scene 时,请勿销毁 Object。(scene切换时会释放老场景内存,如果想不释放某个对象,就可以用这个方法)

    void Start()
    {
        DontDestroyOnLoad(gameObject);
    }
    // Update is called once per frame
    [System.Obsolete]
    void Update()
    {
        if(Input.GetKey(KeyCode.Space)){
            //Application.LoadLevel("emp");
            Application.LoadLevel(1);
        }
    }

可以用场景名称,也可以用scenes in build中scene的index
在这里插入图片描述
如图,实现点击空格切换场景,但脚本所绑定的cube未被释放内存(这个方法可以用在比如切换场景但背景音乐丝滑过渡的场合)
在这里插入图片描述
注意:

  • 物体一个组件不释放,那么这个物体和子物体都将得到保留
    void Start()
    {
        DontDestroyOnLoad(GetComponent<Rigidbody>());
    }

在这里插入图片描述
脚本绑定到cube
在这里插入图片描述
但如果但将脚本挂cube(1)或者cube(2)上,则DontDestroyOnLoad对这三个cube都不产生效果,所以要求不释放内存的对象没有父对象

Object.Instantiate 物体的生成

public static Object Instantiate (Object original);
public static Object Instantiate (Object original, Transform parent);
public static Object Instantiate (Object original, Transform parent, bool instantiateInWorldSpace);
public static Object Instantiate (Object original, Vector3 position, Quaternion rotation);
public static Object Instantiate (Object original, Vector3 position, Quaternion rotation, Transform parent);
参数

  • original 要复制的现有对象。
  • position 新对象的位置。
  • rotation 新对象的方向。
  • parent 将指定给新对象的父对象。
  • instantiateInWorldSpace When you assign a parent Object, pass true to position the new object directly in world space. Pass false to set the Object’s position relative to its new parent.

描述
克隆 original 对象并返回克隆对象。
此函数会通过与编辑器中的复制命令类似的方式创建对象的副本。如果要克隆 GameObject,则可以指定其位置和旋转(否则,这些默认为原始 GameObject 的位置和旋转)。如果要克隆 Component,则也会克隆它附加到的 GameObject(同样可指定可选的位置和旋转)。

克隆 GameObject 或 Component 时,也将克隆所有子对象和组件,它们的属性设置与原始对象相同。
注意

  • 使用instantiate方法生成对象,比较消耗资源,尽管可以配合使用destroy销毁对象释放。后续优化可以使用对象池概念(估计类似java连接池这种)
  • 一般不生成场景中存在的物体,因为它需要加载,在其他场景就没法复用——>使用prefab预设体(hierarchy中将对象拉到assets中形成pref ab)
类子弹生成案例
    public Object obj;
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space)){
            //Quaternion.identity:旋转角默认0
            Object.Instantiate(obj,new Vector3(0,5,0),Quaternion.identity);
        }
    }

在这里插入图片描述
添加物体自销毁、施加一个脉冲力

    public float survivalTime = 3;
    void Start()
    {
        Destroy(gameObject,survivalTime);
    }
    public Rigidbody rig;
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space)){
            //Quaternion.identity:旋转角默认0
            // 声明为Rigidbody,注意这里输入的是Rigibody,返回的也是Rigibody,如果输入GameObject输出Rigibody,会报NullReferenceException异常
            Rigidbody copyRig = Object.Instantiate(rig,new Vector3(0,5,0),Quaternion.identity) as Rigidbody;
            copyRig.AddForce(Vector3.forward*5,ForceMode.Impulse);
        }
    }

在这里插入图片描述

继承自Component的方法

Component.tag和GameObject.tag都表示此游戏对象的标签。

Component.CompareTag 比较tag

public bool CompareTag (string tag);
Checks the GameObject’s tag against the defined tag.

注意比较tag有两种方法

  • CompareTag(“a”)比xxx.tag == "a"高效,原因是省去tag赋值的操作

消息推送

  • SendMessage
  • SendMessageUpwards
  • BroadcastMessage

使用场景:只要我们得到了一个类的引用,便可以向它的子类/类本身/父类传递某些消息,最终达到直接执行某个函数的目的,这样非常方便实现一个引用,简化开发复杂程度。

Component.SendMessage 消息推送

public void SendMessage (string methodName);
public void SendMessage (string methodName, object value);
public void SendMessage (string methodName, object value, SendMessageOptions options);
public void SendMessage (string methodName, SendMessageOptions options);

参数

  • methodName 要调用的方法的名称。
  • value 该方法的可选参数。
  • options 如果目标对象没有为消息实现该方法,是否应报错?

描述
调用此游戏对象中的每个 MonoBehaviour 上名为 methodName 的方法。
通过具有零参数,该接收方法可选择忽略此参数。 如果选项设置为 SendMessageOptions.RequireReceiver,则在任何组件均未拾取此消息时输出错误。
注意,不会将消息发送到非活动对象(即,在 Editor 中或使用 GameObject.SetActive 函数已停用的对象)。

Component.SendMessageUpwards

public void SendMessageUpwards (string methodName, SendMessageOptions options);
public void SendMessageUpwards (string methodName, object value= null, SendMessageOptions options= SendMessageOptions.RequireReceiver);

调用此游戏对象中的每个 MonoBehaviour 上或此行为的每个父级上名为 methodName 的方法。

Component.BroadcastMessage

public void BroadcastMessage (string methodName, object parameter= null, SendMessageOptions options= SendMessageOptions.RequireReceiver);
public void BroadcastMessage (string methodName, SendMessageOptions options);

调用此游戏对象或其任何子项中的每个 MonoBehaviour 上名为 methodName 的方法。

案例

up说比如足球踢到某个物体,那么就可以用这个方法触发被状物体的某个函数。
这几个方法使用的是反射方式,类似监听者模式,是官方提供的方法,后续应该会有自己实现的更高效的使用监听者模式实现的方法(delegate +event方式)。

这个sendMessage看起来非常重要,后续花个时间做个专题,这里就简单过一下。

MonoBehaviour的invoke方法

Invoke 延迟执行函数

public void Invoke (string methodName, float time);
在 time 秒后调用 methodName 方法。
注意:

  • invoke 的time是根据游戏的时间轴变化的,改变timeScale延迟会相应改变
  • 被调用的方法不能有参数
   public GameObject obj;
    public GameObject obj2;
    public float timeDelay = 2;
    public float myTimeScale = 1;

    // Update is called once per frame
    void Update()
    {
        Time.timeScale = myTimeScale;
        if(Input.GetKeyDown(KeyCode.Space)){
            Object.Instantiate(obj2,new Vector3(0,5,0),Quaternion.identity);
            Invoke("spawnCube",timeDelay);
        }
    }
    void spawnCube(){
        GameObject copyObj = Object.Instantiate(obj,new Vector3(0,5,0),Quaternion.identity);
            Rigidbody rig = copyObj.GetComponent<Rigidbody>();
            rig.AddForce(Vector3.forward*5,ForceMode.Impulse);
    }
    private void OnGUI() {
        GUILayout.TextArea("gameTime:" + Time.time.ToString());
        GUILayout.TextArea("realTime:" + Time.realtimeSinceStartup.ToString());
    }

在这里插入图片描述

InvokeRepeating

public void InvokeRepeating (string methodName, float time, float repeatRate);
time 秒后调用 methodName 方法,然后每repeatRate秒调用一次。

*注意:*如果将时间刻度设置为 0,该函数不起作用。

CancelInvoke

public void CancelInvoke ();
取消该 MonoBehaviour 上的所有 Invoke 调用。

IsInvoking

public bool IsInvoking (string methodName);
是否有任何待处理的 methodName 调用?

MonoBehaviour的Coroutine方法

Coroutine协同执行程序

  • 在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行
  • 开启协同程序就是类似于开启一个线程
  • 但是协程并不是线程

参数IEnumerator对象,通常有三种方式获得。

  • 第一种方式,也是最常用方式,是使用带有yield指令的协程函数。
    在这里插入图片描述
    Unity-C# 协程 IEnumerator 用法梳理
  • 第二种方式,继承Unity提供的类CustomYieldInstruction,但其实CustomYieldInstruction是实现了IEnumerator。
  • 第三种方式,就是自己实现IEnumerator接口,手动new出一个IEnumerator接口实现类。(后面测试会用到这个类)

StartCoroutine 启动协程。

public Coroutine StartCoroutine (IEnumerator routine);
启动协程。

public float step = 0.01f;
    private void OnMouseDown() {
        StartCoroutine(Move(step));
    }
    IEnumerator Move(float step){
        for(int i=0;i<500;i++){
            this.transform.Translate(step,0,0);
            yield return null;
        }
        this.transform.position = new Vector3(0,1,0);
        Debug.Log(this.name +"移动结束");
    }

在这里插入图片描述

StopAllCoroutines

public void StopAllCoroutines ();
停止在该行为上运行的所有协同程序。

StopCoroutine

public void StopCoroutine (string methodName);
public void StopCoroutine (IEnumerator routine);
public void StopCoroutine (Coroutine routine);
停止在该行为上运行的第一个名为 methodName 的协同程序或存储在 routine 中的协同程序。

小结

这里message传递,协程和方法延迟调用这三个还有待继续深入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/440834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

八股+面经

文章目录 项目介绍1.不动产项目数据机器学习算法调研图像提取算法调研数据集-ImageNetXceptionVGGInceptionDensenetMobilenet 2.图书项目技术栈面试问题 Java基础MapHashMap v.s Hashtable(5点)ConcurrentHashMap v.s Hashtable(2点)代理模式1. 静态代理2. 动态代理2.1 JDK 动…

什么样的人适合学习网络安全?怎么学?

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a;什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 会产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级学科&#xff0c;…

elasticsearch——数据同步

目录 数据同步思路分析 方案一&#xff1a;同步调用 方案二&#xff1a;异步通知 方案三&#xff1a;监听binlog 区别 关于elasticsearch与数据库数据同步 导入课前资料提供的hotel-admin项目&#xff0c;启动并测试酒店数据的CRUD 声明exchange、queue、RoutingKey 导…

Python列表和字典前面为什么会加星号(**)?

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 python 中&#xff0c;单星号*和双星号**除了作为“乘”和“幂”的数值运算符外&#xff0c; 还在列表、元组、字典的操作中有着重要作用。 一、列表&#xff08;list&#xff09;、元组&#xff08;tuple&#xff09…

flac格式如何转换为mp3,这3个方法超好用

随着音频格式的不断创新和发展&#xff0c;每种格式对应不同的特点。比如像flac格式可以提供无损音质的体验&#xff0c;但它的文件大小却是相对较大&#xff0c;不太适合在普通设备上进行传输和使用。而mp3作为一种流行的音频格式&#xff0c;它的压缩率较高&#xff0c;不但可…

OceanBase 4.1解读:我们想给用户一个开箱即用的OceanBase部署运维工具

欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 关于作者 肖磊 OceanBase 产品专家 负责 OceanBase 运维管控体系产品规划与设计&#xff0c;包括安装部署工具(OBD、OAT)、运维管控平台&#xff08;OCP、OCP Express&#xff09;&#xff0c;致力…

MySQL安装步骤详解

MySQL环境搭建 MySQL的下载 MySQL的4大版本 MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;自由下载&#xff0c;但不提供官方技术支持&#xff0c;适用于 大多数普通用户。 MySQL Enterprise Edition 企业版本&#xff0c;需付费&#xff0c;不能在线下载…

运行torch心得体会

遇到的问题&#xff1a; ①ModuleNotFoundError: No module named torch ②‘conda‘不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 ③import torch 提示找不到指定的模块visual C redistributable is not installed 过程&#xff1a; 用前一段时间就下…

流程图拖拽视觉编程--概述

一般的机器视觉平台采用纯代码的编程方式&#xff0c;如opencv、halcon&#xff0c;使用门槛高、难度大、定制性强、开发周期长&#xff0c;因此迫切需要一个低代码开发的视觉应用平台。AOI缺陷检测的对象往往缺陷种类多&#xff0c;将常用的图像处理算子封装成图形节点,如抓直…

「C/C++」C/C++强制类型转换

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 相关术语C语言中的强制类型转换C中的强制类型转换static_castdynamic_castreinterpret_castconst_cast 注意事项 相关术语 强制类型转换&#xff1a;是指将一个数据类型强制转换为另一个数据类型…

magic Grid

说明文档 A lightweight Javascript library for dynamic grid layoutshttps://vuejsexamples.com/a-lightweight-javascript-library-for-dynamic-grid-layouts/npm npm install magic-grid cnd <script src"https://unpkg.com/magic-grid/dist/magic-grid.cjs.js…

【C++ 七】类和对象:封装、继承、多态、友元、运算符重载

封装、继承、多态、对象的初始化和清理、C对象模型和this指针、友元、运算符重载 文章目录 封装、继承、多态、对象的初始化和清理、C对象模型和this指针、友元、运算符重载前言1 封装1.1 封装的意义1.1.1 封装意义一1.1.2 封装意义二 1.2 struct 和 class 区别1.3 成员属性设置…

数据结构——二叉树的修改与构造

数据结构——二叉树的修改与构造 一、修改二叉树226. 翻转二叉树1.前/后序递归2.广度优先搜索迭代3.拓展&#xff1a;修改中序遍历 / 中序统一迭代写法 114. 二叉树展开为链表 二、构造二叉树106. 从中序与后序遍历序列构造二叉树递归思路 105. 从前序与中序遍历序列构造二叉树…

Java day11

第11章 在用户界面上排列组件 11.1 基本的界面布局11.1.1 布置界面11.1.2 顺序布局11.1.3 方框布局11.1.4 网格布局11.1.5 边框布局 11.2 使用多个布局管理器11.3 卡片布局11.3.1 在应用程序中使用卡片布局11.3.2 单元格内边距和面板内边距 11.1 基本的界面布局 11.1.1 布置界…

瑞芯微rk3568移植openbmc(五)----关于novnc h265 webcodec硬解码

本章没有什么实质内容&#xff0c;其实在第四节调好了H264的webcodec以后&#xff0c;H265仅仅只需要改下参数&#xff0c;其他的都交给webgl去处理就行了&#xff0c;没有什么大的变化&#xff0c;vp8、vp9、h264、h265处理都一样&#xff0c;仅仅只是参数的变化&#xff0c;不…

Winform粉丝提问1——winform怎么在设计界面找到代码里的控件

前言&#xff1a; 今天订阅《Winform从入门到精通》的粉丝在VIP群里面问我一个问题&#xff0c;我感觉这个问题应该是初学者都会遇到的&#xff0c;所以我写了这篇文章来帮助初学者来理解这个问题&#xff0c;问题如下&#xff1a; 假设我在Form1界面上添加了两个Label&#x…

建筑行业为什么要数字化转型?

建筑行业为什么要数字化转型&#xff1f; 建筑行业作为国民经济的重要支柱产业之一&#xff0c;其生产过程繁琐、复杂&#xff0c;且产业链条长&#xff0c;涉及众多领域。 然而&#xff0c;目前传统的建筑模式已经无法适应行业的发展需求&#xff0c;建筑行业的数字化转型已…

PasteSpider之项目-服务-环境介绍

在PasteSpider中&#xff0c;项目和服务是重要的对象&#xff0c;只有理解什么是项目什么是服务后配置起来才不会稀里糊涂的&#xff01; 项目 PasteSpider中的项目和我们平时说的项目意思一样&#xff0c;比如你要开发一个在线客服系统(项目)&#xff0c;一个商城系统(项目),…

平台资金提现解决方案之实现单笔转账到支付宝账户功能

大家好&#xff0c;我是小悟 使用场景 不管是做APP、电脑网站、手机网站还是小程序&#xff0c;为了推广基本上都离不开用户分佣的场景。 换句话说就是在其平台内为每个用户设置“电子钱包”功能&#xff0c;而电子钱包在平台那里只是一串数字&#xff0c;这就需要平台为用户…

ESP32CAM的IDF环境开发

首先&#xff0c;我们需要先搭建一个IDFvscode的开发环境&#xff0c;然后再下载源码 esp32-cam 它这个源码有很多文件&#xff0c;我们可以将它分解到我们之前已有的idf环境中&#xff0c;首先是打开我们下载的文件路径 esp32-web-cam/esp-idf/components下面&#xff1a; 这…