【Unity3D日常开发】Unity3D中实现不同脚本之间的执行顺序控制

这篇具有很好参考价值的文章主要介绍了【Unity3D日常开发】Unity3D中实现不同脚本之间的执行顺序控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

推荐阅读

  • CSDN主页
  • GitHub开源地址
  • Unity3D插件分享
  • 简书地址
  • 我的个人博客

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

首先,来了解一下事件函数的执行顺序,下图是官方给的脚本中事件函数的执行顺序:

unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
众所周知,Unity中某个脚本的事件函数执行顺序是Awake、Start、Update、LateUpdate等,那么不同脚本之间的事件函数的调用顺序是怎么样的呢,以及如何控制不同脚本之间的事件函数的调用顺序呢?

看完这篇文章你就能找到答案。

二、不同脚本之间的事件函数的调用顺序

.meta文件

看似每个脚本之间的调用顺序是随机的,其实是有迹可循的。

痕迹就在于生成.cs文件后同步生成的.cs.meta文件:
unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
打开.cs.meta文件:
unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
executionOrder: 0 这个就是执行顺序。

越小执行的优先级越高。

默认的情况下就是0。若想让脚本最先执行,可以把它设置为负值。

既然知道了脚本的执行顺序,那么怎么控制脚本的执行顺序呢。

三、控制脚本的执行顺序

3-1、修改.cs.meta文件

直接打开脚本的.meta文件,然后修改executionOrder的值。

越小执行的优先级越高。

3-2、在Unity中设置脚本的执行顺序

在Unity中设置脚本的执行顺序:

unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
在Project视图中随便找一个脚本,点击右上角Execution Order后弹出Project Settings视图,然后设置执行顺序即可。

3-3、使用代码控制脚本的执行顺序

脚本执行顺序工具类:

新建脚本命名为AttributeUtils.cs,双击打开脚本,编辑代码:

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

// 定义属性类 管理相关的函数
[System.AttributeUsage(AttributeTargets.All)]
public class SFHCall : Attribute
{
    public SFHCall(int lev)
    {
        level = lev;
    }

    public int GetLevel()
    {
        return level;
    }
    protected int level;
}
// 定义属性类 设置函数的属性
[System.AttributeUsage(AttributeTargets.All)]
public class SFHStartCall : SFHCall
{
    public SFHStartCall(int lev) : base(lev)
    {
        level = lev;
    }
}
// 管理执行对象
public class AtrributeFlagFunction
{
    public MonoBehaviour monob;
    public MethodInfo methodInfo;
}
// 属性工具类
public class AttributeUtils
{
    // 使用字典来存储所有的相关函数
    public static SortedList myFuctionList = new SortedList();
    public static void GetAllDestByProperties<T>(object[] mono) where T : SFHCall
    {
        int length = mono.Length;
        for (int i = 0; i < length; i++)
        {
            Cache<T>((MonoBehaviour)mono[i]);
        }
    }
    private static void Cache<T>(MonoBehaviour p) where T : SFHCall
    {
        var type = p.GetType();
        // 不会重复调用父类的方法了。
        var fields2 = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
        foreach (var field in fields2)
        {
            AtrributeFlagFunction aff = new AtrributeFlagFunction();
            var objs = field.GetCustomAttributes(typeof(T), false);
            if (objs.Length > 0)
            {
                aff.monob = p;
                aff.methodInfo = field;
                T attr = (T)objs[0];
                int value = attr.GetLevel();
                if (!myFuctionList.ContainsKey(value))
                {
                    {
                        List<AtrributeFlagFunction> AttributeList = new List<AtrributeFlagFunction>();
                        AttributeList.Add(aff);
                        myFuctionList.Add(value, AttributeList);
                    }
                }
                else
                {
                    List<AtrributeFlagFunction> mlist = (List<AtrributeFlagFunction>)myFuctionList[value];
                    mlist.Add(aff);
                }
            }
        }
    }
}

这个脚本是用属性来获取所有的对象的函数,然后再去排列顺序去执行。

实例化属性管理工具类:

再新建脚本StartFromHere.cs,双击打开脚本,修改代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.Reflection;

public class StartFromHere : MonoBehaviour
{
    void Start()
    {
        //初始化 获取所有的相关函数 并执行
        InitialStart();
    }

    private void InitialStart()
    {
        MonoBehaviour[] testMono = FindObjectsOfType<MonoBehaviour>();
        AttributeUtils.GetAllDestByProperties<SFHStartCall>(testMono);
        for (int i = 0; i < AttributeUtils.myFuctionList.Count; i++)
        {
            List<AtrributeFlagFunction> mlist = (List<AtrributeFlagFunction>)AttributeUtils.myFuctionList.GetByIndex(i);
            for (int j = 0; j < mlist.Count; j++)
            {
                AtrributeFlagFunction item = mlist[j];
                MonoBehaviour monob = item.monob;
                object result = item.methodInfo.Invoke((object)monob, new object[] { });
                if (item.methodInfo.ReturnType == typeof(IEnumerator))
                {
                    monob.StartCoroutine((IEnumerator)result);
                }
            }
        }
    }
}

这个脚本就是实例化脚本执行顺序工具类,需要挂载在对象上。

使用方法:

新建三个脚本,随便命名,然后编辑代码:

public class SFHTest1 : MonoBehaviour
{
    [SFHStartCall(1)]
    void OnStart()
    {
        Debug.Log("第一个执行");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SFHTest2 : MonoBehaviour
{
    [SFHStartCall(2)]
    void OnStart()
    {
        Debug.Log("第二个执行");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SFHTest3 : MonoBehaviour
{
    [SFHStartCall(3)]
    void OnStart()
    {
        Debug.Log("第三个执行");
    }
}

SFHStartCall后面的参数就是执行顺序,越大越早执行,然后都挂载到对象上:
unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎
执行结果:
unity update执行顺序,# Unity3D之日常开发,unity,游戏引擎

四、后记

本篇文章实现了如何控制脚本执行的顺序。

最后使用了一个脚本执行顺序工具类来控制脚本的执行顺序。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:文章来源地址https://www.toymoban.com/news/detail-782477.html

专栏 方向 简介
Unity3D开发小游戏 小游戏开发教程 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶 入门 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUI UGUI Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据 文件读取 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合 数据集合 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发 虚拟仿真 总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件 插件 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发 日常记录 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG 日常记录 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。

到了这里,关于【Unity3D日常开发】Unity3D中实现不同脚本之间的执行顺序控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D编辑器开发】Unity3D中实现Transform快速复制粘贴【非常实用】

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 在开发中,常常会遇到频繁复制粘贴物体的坐标、旋转、缩放的操作。 使用Unity自带的组件复制粘贴比

    2024年02月07日
    浏览(69)
  • Unity读书系列《Unity3D游戏开发》——脚本(一)

    脚本在Unity的重要程度不用多说,她是大部分软件的核心组件。 我们将在此篇文章学习脚本模版及其拓展、脚本的生命周期、脚本的执行顺序、脚本序列化,下一篇为脚本编译与调试。 如下图我们可以在Project视图右键进行脚本创建,除了C#脚本,还有两类脚本;Testing用来做

    2024年04月28日
    浏览(86)
  • 【Unity3D小功能】Unity3D中实现Text显示版本功能

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 在项目开发中,会遇到要控制版本的情况,比如说对比版本号,版本不对再更新版本的功能,这些就是

    2024年02月05日
    浏览(77)
  • 【Unity3D小功能】Unity3D中实现点击‘文字’出现‘UI面板’

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 QQ群:398291828 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 宠粉博主又来了,今天有粉丝问我如何实现点击一段文字然后出现的面板在那段文字附近显示: 深入了

    2024年04月13日
    浏览(83)
  • 【Unity3D小功能】Unity3D中实现仿真时钟、表盘、仿原神时钟

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 今天实现一个时钟工具,其实在之前已经完成了一个简单的时钟工具:【Unity3D应用案例系列】时钟、

    2024年02月05日
    浏览(78)
  • 【Unity3D小功能】Unity3D中实现UI擦除效果、刮刮卡功能

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 使用Unity3D实现UI的擦拭效果、刮刮卡功能的效果实现方式比较多,比如说用Shader、Texture渲染都是可以

    2024年02月04日
    浏览(246)
  • 【Unity3D日常BUG】Unity3D打包WEBGL平台运行出现无法解析gzip、构建压缩等问题

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 在Unity3D中打包WEBGL运行出现这样的错误: 具体分析: 1、无法解析xxx.gz文件 2、启用了构建压缩,但是

    2024年02月07日
    浏览(58)
  • Unity3D中实现动画的方式:

    Unity3D中实现动画的方式有很多种,以下是其中两种常用的方式: 1. 使用Animation组件 使用Animation组件可以制作简单的关键帧动画。步骤如下: 将需要动画的物体选中,然后在Inspector面板中点击Add Component按钮,选择Animation组件。 在Project面板中创建动画剪辑(Animation Clip)。

    2024年02月08日
    浏览(78)
  • Unity3D中实现Player的第一人称视角

    效果,上面为Scene场景,下面为Game场景 0创建地形,当然可以先简单的创建一个空白的Terrain。这里我已经对地形进行了初步的编辑和渲染。 1.在Hierarchy视图中右键创建一个胶囊体(Capsule)作为Player,添加好后重置胶囊体的位置,并且调整胶囊体在一个合适的位置。  2.将Main

    2023年04月08日
    浏览(51)
  • Unity3D中实现人物的第一人称视角

    打开unity创建一个场景地图可以添加一个Plane作为地面 在Hierarchy视图中右键创建一个胶囊体(Capsule)作为Player,添加好后重置胶囊体的位置,并且调整胶囊体在一个合适的位置。 将Main Camera拖拽到到player内作为子对象,重置一下Main Camera的transform,并且再调整一下它在player中

    2024年02月11日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包