2014-06-07 01:40:28 u010145745 阅读数 2953
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    1950 人正在学习 去看看 曾家海

       当我们打开unity3D自带的案例AngryBots时,会发现没有像常见程序那样的入口函数(比如,C的main函数,unity3D底层已经做好了吧)。取而代之,脚本中会有很多事件函数,用于响应游戏中消息,每个脚本都会有涉及Start、update等之类的函数负责初始化、更新等事件的处理,更像是一种分布式控制方式。脚本都是继承自MonoBehaviour内建类,以此与Unity内部工作机制相联系,它是一种组件可以挂接到GameObject上,可以改变GameObject的属性。

        Unity的脚本不像常规程序那样,会在一个循环中不断执行知道任务结束,它会通过调用一些事先声明好的事件函数,断断续续地将控制权传给一个脚本。在事件函数执行完毕后,控制权又交回给Unity,只要游戏运行过程中触发了事件,相应的事件函数就会被调用。MonoBehaviour类中定义了很多事件函数,可以自己查看,比较常见的是Awake、Start、FixedUpdate、Update、LateUpdate、OnDestroy、OnDisable、OnEnable、OnGUI等。

        在场景加载时,场景中的所有物体都会调用Awake函数。注意,不管有多少物体的Awake与Start函数被按任意顺序调用。在第一个Start函数调用前,所有的Awake函数都已执行。所以,可以在Start函数中调用任意在Awake函数中初始化过的信息。如果脚本实例化被启用,则Start函数在第一帧更新之前被调用。

        更新函数主要是放置处理GameObject的位置、方向、状态及行为等代码逻辑的地方,我们以此来追踪游戏逻辑、交互、动画、相机位置等。而FixedUpdate、Update、LateUpdate比较如下:

    1.   FixedUpdate:比Update调用更频繁;当帧率比较低时,每帧可被多次调用,如果帧率比较高,就可能不会被调用;所有的物理计算和更新都在FixedUpdate之后立即发生;当在FixedUpdate中计算物体移动时,不需要乘以Time.deltaTime,因为FixedUpdate是基于可靠的定时器的,与帧率无关。
    2. Update:每帧调用一次;帧更新的主要函数。
    3. LateUpdate:每帧调用一次,在Update之后执行;LateUpdate最常应用于第三人称控制器的相机跟随。(如果将角色的移动和旋转放在Update中,则可以把所有相机的移动旋转放在LateUpdate,从而在相机追踪到角色位置之前,确保角色已经完成了移动。

        Unity有个系统,用来渲染并响应GUI控件,这类代码不像普通的帧更新代码一样,必须放在周期性调用的OnGUI函数里。也可以检测场景中一个物体的鼠标事件,可用于实现指向性武器与展示鼠标下角色信息之类的需求。有个OnMouseXXX 事件函数集(OnMouseOver,OnMouseDown), 它们专门用于反馈用户鼠标行为。例如,鼠标点击一个物体时,这个物体挂的脚本的OnMouseDown函数就会被调用(如果有的话)。 

        物理引擎通过物体挂的脚本中的事件函数,来通知它发生了碰撞。OnCollisionEnter, OnCollisionStay, OnCollisionExit 函数分别在碰撞开始,持续与结束时调用。如果碰撞体设置成了触发器(用于只需要检测碰撞,而不需要对此碰撞进行物理反应的情况),那么会调用对应的OnTriggerEnter,OnTriggerStay,OnTriggerExit函数。如果一次物理更新中发生了多次碰撞,这些函数可能会被调用多次。这些函数会被传入一些碰撞的信息(碰撞位置,撞得物体是谁,等等)。

        MonoBehaviour类的详细事件函数列表可参考Unity3D的Documentation

            



2017-02-15 22:22:42 nmg10 阅读数 738
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    1950 人正在学习 去看看 曾家海

Unity3D中自带事件函数的执行顺序

在Unity3D脚本中,有几个Unity3D自带的事件函数按照预定的顺序执行作为脚本执行。其执行顺序如下:

编辑器(Editor)

  • Reset:Reset函数被调用来初始化脚本属性当脚本第一次被附到对象上,并且在Reset命令被使用时也会调用。
    编者注:Reset是在用户点击Inspector面板上Reset按钮或者首次添加该组件时被调用。Reset最常用于在见识面板中给定一个默认值。

第一次场景加载(First Scene Load)
这些函数会在一个场景开始(场景中每个物体只调用一次)时被调用。

  • Awake:这个函数总是在任何Start()函数之前一个预设被实例化之后被调用,如果一个GameObject是非激活的(inactive),在启动期间Awake函数是不会被调用的直到它是活动的(active)。
  • OnEnable:只有在对象是激活(active)状态下才会被调用,这个函数只有在object被启用(enable)后才会调用。这会发生在一个MonoBehaviour实例被创建,例如当一个关卡被加载或者一个带有脚本组件的GameObject被实例化。

注意:当一个场景被添加到场景中,所有脚本上的Awake()和OnEable()函数将会被调用在Start()、Update()等它们中任何函数被调用之前。自然的,当一个物体在游戏过程中被实例化时这不能被强制执行。

第一帧更新之前(Before the first frame update)

  • Start:只要脚本实例被启用了Start()函数将会在Update()函数第一帧之前被调用。

对于那些被添加到场景中的物体,所有脚本上的Start()函数将会在它们中任何的Update()函数之前被调用,自然的,当一个物体在游戏过程中被实例化时这不能被强制执行。

在帧之间(In between frames)

  • OnApplicationPause:这个函数将会被调用在暂停被检测有效的在正常的帧更新之间的一帧的结束时。在OnApplicationPause被调用后将会有额外的一帧用来允许游戏显示显示图像表示在暂停状态下。

更新顺序(Update Order)

当你在跟踪游戏逻辑和状态,动画,相机位置等的时候,有几个不同的事件函数你可以使用。常见的模式是在Update()函数中执行大多数任务,但是也有其它的函数你可以使用。

  • FixedUpdate:FixedUpdate函数经常会比Update函数更频繁的被调用。它一帧会被调用多次,如果帧率低它可能不会在帧之间被调用,就算帧率是高的。所有的图形计算和更新在FixedUpdate之后会立即执行。当在FixedUpdate里执行移动计算,你并不需要Time.deltaTime乘以你的值,这是因为FixedUpdate是按真实时间,独立于帧率被调用的。
  • Update:Update每一帧都会被调用,对于帧更新它是主要的负荷函数。
  • LateUpdate:LateUpdate会在Update结束之后每一帧被调用,任何计算在Update里执行结束当LateUpdate开始时。LateUpdate常用为第三人称视角相机跟随。

渲染(Rendering)

  • OnPreCull:在相机剔除场景前被调用。剔除是取决于哪些物体对于摄像机是可见的,OnPreCull仅在剔除起作用之前被调用。
  • OnBecameVisible/OnBecameInvisible:当一个物体对任意摄像机变得可见/不可见时被调用。
  • OnPreRender:在摄像机开始渲染场景之前调用。
  • OnRenderObject:在指定场景渲染完成之后调用,你可以使用GL类或者Graphics.DrawMeshNow 来绘制自定义几何体在这里。
  • OnPostRender:在摄像机完成场景渲染之后调用。
  • OnRenderImage(Pro Only):在场景徐然完成之后允许屏幕图像后期处理调用。
  • OnGUI:为了响应GUI事件,每帧会被调用多次(一般最低两次)。布局Layout和Repaint事件会首先处理,接下来处理的是是通过
    Layout和键盘/鼠标事件对应的每个输入事件。
  • OnDrawGizmos:用于可视化的绘制一些小玩意在场景视图中。

协同程序(Coroutines)

正常的协同程序更新是在Update函数返回之后运行。一个协同程序是可以暂停执行(yield)直到给出的依从指令(YieldInstruction )完成,写成的不同运用:

  • yield:在所有的Update函数都已经被调用的下一帧该协程将持续执行。
  • yield WaitForSeconds:一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后。
  • yield WaitForFixedUpdate:所有脚本上的FixedUpdate函数已经执行调用之后持续。
  • yield WWW:在WWW下载完成之后持续。
  • yield StartCoroutine:协同程序链,将会等到MuFunc函数协程执行完成首先。

销毁(When the Object is Destroyed)

  • OnDestory:这个函数在会在一个对象销毁前一帧调用,会在所有帧更新一个对象存在的最后一帧之后执行,对象也许会响应Object.Destroy 或一个场景关闭时被销毁。

退出游戏(When Quitting)
这些函数会在你场景中所有的激活的物体上调用:

  • OnApplicationQuit:这个函数在应用退出之前的所有游戏物体上调用,在编辑器(Editor)模式中会在用户停止PlayMode时调用,在网页播放器(web player)中会在网页视图关闭时调用。
  • OnDisable:当行为变为非启用(disable)或非激活(inactive)时调用。

脚本的生命周期流程图

vital.png
2014-03-23 23:11:06 s10141303 阅读数 5403
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    1950 人正在学习 去看看 曾家海

Unity脚本从唤醒到销毁都有着一套比较完善的生命周期,添加任何脚本都要遵守生命周期法则!

接下来介绍几种系统自调用的重要方法。首先要我们先来说明一下它们的执行顺序:

Awake --> Start --> Update --> FixedUpdate --> LateUpdate -->OnGUI -->Reset --> OnDisable -->OnDestroy

下面我们针对每一个方法进行详细的说明:

1.Awake用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如GameObject.FindWithTag()这样的函数搜索它们。每个游戏物体上的Awake以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息Awake总是在Start之前被调用。它不能用来执行协同程序。

2.Start:仅在Update函数第一次被调用前调用。Start在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。在所有脚本实例中,Start函数总是在Awake函数之后调用。

3.Update:正常帧更新,用于更新逻辑。每一帧都执行,处理Rigidbody时,需要用FixedUpdate代替Update。例如:给刚体加一个作用力时,你必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧。(两者帧长不同)FixedUpdate每固定帧绘制时执行一次,和update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。Update就比较适合做控制。

4.FixedUpdate:固定帧更新,Unity导航菜单栏中,点击“Edit-->Project Setting-->Time”菜单项后,右侧的Inspector视图将弹出时间管理器,其中“Fixed Timestep”选项用于设置FixedUpdate()的更新频率,更新频率默认为0.02s

5.LateUpdate:在所有Update函数调用后被调用,和fixedupdate一样都是每一帧都被调用执行,这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。LateUpdate,在每帧Update执行完毕调用,他是在所有update结束后才调用,比较适合用于命令脚本的执行。官网上例子是摄像机的跟随,都是在所有update操作完才跟进摄像机,不然就有可能出现摄像机已经推进了,但是视角里还未有角色的空帧出现。

6.OnGUI:在渲染和处理GUI事件时调用。比如:你画一个button或label时常常用到它。这意味着OnGUI也是每帧执行一次。

7.Reset:在用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个默认值。

8.OnDisable:当物体被销毁时 OnDisable将被调用,并且可用于任意清理代码。脚本被卸载时,OnDisable将被调用,OnEnable在脚本被载入后调用。注意: OnDisable不能用于协同程序。

9.OnDestroy:当MonoBehaviour将被销毁时,这个函数被调用。OnDestroy只会在预先已经被激活的游戏物体上被调用。注意:OnDestroy也不能用于协同程序。

备注:

协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程。在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。

2017-06-01 18:12:51 qq_20849387 阅读数 2701
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    1950 人正在学习 去看看 曾家海

今天让大家学习一下Unity3d里面的OpenGL 自带的API ,我们可以通过简单的使用OpenGL来在场景中利用相机渲染绘制图形。官方学习文档:https://docs.unity3d.com/ScriptReference/GL.html
1.第一步:通过相关官方的文档,我们可以了解GL接口以及一些标准OpenGL函数;
2.第二步:我们直接进入实操模式;
2.0 新建项目,在场景中创建Camera,并且附加OpenGLTest.cs 组件;
2.1 OpenGLTest.cs 代码如下(具体可以直接参考官方文档);

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

public class OpenGLTest : MonoBehaviour {

        public int lineCount = 80;
        public float radius = 4f;

        static Material lineMaterial;


        public void OnRenderObject()
        {
                CreateLineMaterial();
                // Apply the line material
                lineMaterial.SetPass(0);

                GL.PushMatrix();
                // Set transformation matrix for drawing to
                // match our transform
                GL.MultMatrix(transform.localToWorldMatrix);

                // Draw lines
                GL.Begin(GL.LINES);
                for (int i = 0; i < lineCount; ++i)
                {
                        float a = i / (float)lineCount;
                        float angle = a * Mathf.PI * 2;
                        // Vertex colors change from red to green
                        GL.Color(new Color(a, 1 - a, 0, 0.8F));
                        // One vertex at transform position
                        GL.Vertex3(0, 0, 0);
                        // Another vertex at edge of circle
                        GL.Vertex3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);
                }
                GL.End();
                GL.PopMatrix();
        }


        void OnPostRender()
        {
                // Set your materials
                GL.PushMatrix();
                // yourMaterial.SetPass( );
                // Draw your stuff
                GL.PopMatrix();

        }

        static void CreateLineMaterial()
        {
                if (!lineMaterial)
                {
                        // Unity has a built-in shader that is useful for drawing
                        // simple colored things.
                        Shader shader = Shader.Find("Hidden/Internal-Colored");
                        lineMaterial = new Material(shader);
                        lineMaterial.hideFlags = HideFlags.HideAndDontSave;
                        // Turn on alpha blending
                        lineMaterial.SetInt("_SrcBlend",(int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                        lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        // Turn backface culling off
                        lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
                        // Turn off depth writes
                        lineMaterial.SetInt("_ZWrite", 0);
                }
        }
}

2.2 运行项目看绘制的线条;

2016-02-16 14:48:35 ldy597321444 阅读数 366
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    1950 人正在学习 去看看 曾家海

文章源于 : http://www.jianshu.com/p/1d93ece664e2

在Unity3D脚本中,有几个Unity3D自带的事件函数按照预定的顺序执行作为脚本执行。其执行顺序如下:

编辑器(Editor)

  • Reset:Reset函数被调用来初始化脚本属性当脚本第一次被附到对象上,并且在Reset命令被使用时也会调用。
    编者注:Reset是在用户点击Inspector面板上Reset按钮或者首次添加该组件时被调用。Reset最常用于在见识面板中给定一个默认值。

第一次场景加载(First Scene Load)
这些函数会在一个场景开始(场景中每个物体只调用一次)时被调用。

  • Awake:这个函数总是在任何Start()函数之前一个预设被实例化之后被调用,如果一个GameObject是非激活的(inactive),在启动期间Awake函数是不会被调用的直到它是活动的(active)。
  • OnEnable:只有在对象是激活(active)状态下才会被调用,这个函数只有在object被启用(enable)后才会调用。这会发生在一个MonoBehaviour实例被创建,例如当一个关卡被加载或者一个带有脚本组件的GameObject被实例化。

注意:当一个场景被添加到场景中,所有脚本上的Awake()和OnEable()函数将会被调用在Start()、Update()等它们中任何函数被调用之前。自然的,当一个物体在游戏过程中被实例化时这不能被强制执行。

第一帧更新之前(Before the first frame update)

  • Start:只要脚本实例被启用了Start()函数将会在Update()函数第一帧之前被调用。

对于那些被添加到场景中的物体,所有脚本上的Start()函数将会在它们中任何的Update()函数之前被调用,自然的,当一个物体在游戏过程中被实例化时这不能被强制执行。

在帧之间(In between frames)

  • OnApplicationPause:这个函数将会被调用在暂停被检测有效的在正常的帧更新之间的一帧的结束时。在OnApplicationPause被调用后将会有额外的一帧用来允许游戏显示显示图像表示在暂停状态下。

更新顺序(Update Order)

当你在跟踪游戏逻辑和状态,动画,相机位置等的时候,有几个不同的事件函数你可以使用。常见的模式是在Update()函数中执行大多数任务,但是也有其它的函数你可以使用。

  • FixedUpdate:FixedUpdate函数经常会比Update函数更频繁的被调用。它一帧会被调用多次,如果帧率低它可能不会在帧之间被调用,就算帧率是高的。所有的图形计算和更新在FixedUpdate之后会立即执行。当在FixedUpdate里执行移动计算,你并不需要Time.deltaTime乘以你的值,这是因为FixedUpdate是按真实时间,独立于帧率被调用的。
  • Update:Update每一帧都会被调用,对于帧更新它是主要的负荷函数。
  • LateUpdate:LateUpdate会在Update结束之后每一帧被调用,任何计算在Update里执行结束当LateUpdate开始时。LateUpdate常用为第三人称视角相机跟随。

渲染(Rendering)

  • OnPreCull:在相机剔除场景前被调用。剔除是取决于哪些物体对于摄像机是可见的,OnPreCull仅在剔除起作用之前被调用。
  • OnBecameVisible/OnBecameInvisible:当一个物体对任意摄像机变得可见/不可见时被调用。
  • OnPreRender:在摄像机开始渲染场景之前调用。
  • OnRenderObject:在指定场景渲染完成之后调用,你可以使用GL类或者Graphics.DrawMeshNow 来绘制自定义几何体在这里。
  • OnPostRender:在摄像机完成场景渲染之后调用。
  • OnRenderImage(Pro Only):在场景徐然完成之后允许屏幕图像后期处理调用。
  • OnGUI:为了响应GUI事件,每帧会被调用多次(一般最低两次)。布局Layout和Repaint事件会首先处理,接下来处理的是是通过
    Layout和键盘/鼠标事件对应的每个输入事件。
  • OnDrawGizmos:用于可视化的绘制一些小玩意在场景视图中。

协同程序(Coroutines)

正常的协同程序更新是在Update函数返回之后运行。一个协同程序是可以暂停执行(yield)直到给出的依从指令(YieldInstruction )完成,写成的不同运用:

  • yield:在所有的Update函数都已经被调用的下一帧该协程将持续执行。
  • yield WaitForSeconds:一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后。
  • yield WaitForFixedUpdate:所有脚本上的FixedUpdate函数已经执行调用之后持续。
  • yield WWW:在WWW下载完成之后持续。
  • yield StartCoroutine:协同程序链,将会等到MuFunc函数协程执行完成首先。

销毁(When the Object is Destroyed)

  • OnDestory:这个函数在会在一个对象销毁前一帧调用,会在所有帧更新一个对象存在的最后一帧之后执行,对象也许会响应Object.Destroy 或一个场景关闭时被销毁。

退出游戏(When Quitting)
这些函数会在你场景中所有的激活的物体上调用:

  • OnApplicationQuit:这个函数在应用退出之前的所有游戏物体上调用,在编辑器(Editor)模式中会在用户停止PlayMode时调用,在网页播放器(web player)中会在网页视图关闭时调用。
  • OnDisable:当行为变为非启用(disable)或非激活(inactive)时调用。

脚本的生命周期流程图


Unity 一些信息:


没有更多推荐了,返回首页