天天看点

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

一、脚本

脚本介绍

是附加在游戏物体上用于定义游戏对象行为指令的代码。(*.cs文件)

Unity支持两种高级编程语言:C#、javascript

文件名与类名必须一致。

不能在脚本中写构造函数;

脚本中属性通常也不会写,一般只包含字段和方法

附加到游戏物体的脚本类必须从MonoBehaviour类继承

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

语法

using 命名空间;
public class 类名:MonoBehaviour
{
    void 方法名()
    {
        Debug.Log("调试显示信息");
        print("本质就是Debug.Log方法");
    }
}
           

编译过程

源代码 --(CLS)-> 中间语言 – (Mono Runtime) -> 机器码

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

二、开发工具

MonoDevelop

Unity自带脚本编辑器,创建Mono应用程序,适用于Linux、

Mac OS X和Windows的集成开发环境,支援C#、BOO和

JavaScript等高级编程语言。

Visual Studio

微软公司的开发I具包,包括了整个软件生命周期中需要的大部分工具,如团队开发工具、集成开发环境等等。

在Unity中通过菜单设置修改默认的脚本编辑器:

Edit-- Preferences-- External Tools- External Script Editor

三、脚本生命周期

介绍

Unity脚本从唤醒到销毁的过程。

消息(必然事件):当满足某种条件Unity引擎自动调用的函数。

初始化阶段

场景开始时

1.Awake

场景创建时或prefab实例化时,若为inactive则在active时调用,仅执行一次OnEnable

2.场景加载完,GameObject实例化时,对象enabled时

OnLevelWasLoaded

3.场景全部加载完成后

Reset Editor级别,非playmode下脚本挂载时或主动调用

Start

4.仅在场景中所有Awake 和 OnEnable执行后,所有场景中对象第一帧update之前,且仅执行一次

物理计算阶段

1.fixedupdate

每帧根据帧率高低可能多次调用也可能不调用,执行后立即开始物理计算和更新,做移动计算时无需使用Time.deltaTime

2.状态机周期

1.状态机更新

2.OnStateMachineEnter 挂载在一个动画图形上的状态机首次进入一个状态时的第一帧调用

3.OnStateMachineExit退出状态的最后一帧调用

4.处理图形 评估所有动画图形

5.触发动画事件

在该时间内当前帧和最后一帧之间,触发所有动画片段的动画事件

6.状态周期回调(OnStateEnter/OnStateUpdate/OnStateExit) 一个状态层有最多三个活跃状态,current state, interrupted state, and next state,对应阶段周期方法顺序执行

3.内部物理更新

4. 状态机周期

1.处理动画

渲染动画结果图形

2.IK动画周期

由workthread写入Transform

3.写入属性

由主线程写入场景其他动画属性

4.碰撞事件(Collision、Trigger)

5.协程(yield WaitForFixedUpdate)

在所有脚本的FixedUpdated执行后再执行

输入事件

OnMouseXXX

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

游戏逻辑

1.update

2.协程

除WaitForFixedUpdate和WaitForEndOfFrame其他协程时机

3.状态机周期

同物理计算阶段过程,单无内部物理更新

4.lateupdate 开始时update的计算都已完成,一普遍用法是相机跟随,update中对人物移动的计算已全部完成,此时在lateupdate中更新相机位置

场景渲染

1.OnWillRenderObject

若物体可见则每个相机调用一次

2.OnPreCull

相机剔除动作前

3.OnBecameVisible/OnBecameInvisible

对任何相机可见/不可见时调用

4.OnPreRender

相机渲染前

5.OnRenderObject

所有常规场景渲染完成时,可在此绘制自定义几何图形

6.OnPostRender

当一个相机渲染完场景后

7.OnRenderImage

场景渲染后,可对Image做后期处理(滤镜)

Gizmo 渲染

OnDrawGizmos

仅在editor

GUI渲染

OnGUI 每帧多次调用

帧结束

yield WaitForEndOfFrame

暂停

OnApplicationPause

一帧最后时调用,调用后会再触发一帧以刷新图像和切换暂停状态

退出/销毁

OnApplicationQuit

OnDisable

OnDestroy

所有帧刷新后

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

四、调试

Unity编辑器调试

将程序投入到实际运行中,通过开发工具进行测试,修正逻辑错误的过程。

1.控制台调试

Debug.Log(变量);

print(变量);

2.定义共有变量,程序运行后在检测面板查看数据

使用VS调试

调试步骤:

(1)在可能出错的行添加断点

(2)启动调试

(3)在Unity中Play场景

(4)也在调试时右键–>快速监视,在快速监视面板便捷的调试和查看数据;在即时窗口输入代码进行调试

五、常用API

介绍

API(Application Programming Interface)

应用程序编程接口1 , 是一些预先定义的函数。

Unity擎提供了丰富的组件和类库,为开发者提供了非常大的便利,熟练掌握和使用这些API对于游戏开发效率提高很重要。

Unity API图解合集

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API
UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

Component

component类提供了查找组件的功能,可以在当前物体、后代和先辈中查找

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

GetComponent

如果游戏对象有附加type类型的组件,则返回,如果没有则为空。

GetComponentInChildren

返回此游戏对象上type类型的组件或任何它的子对象,使用深度首先搜索

GetComponentInParent

返回次对象或任何它的父对象type类型的组件。

/// <summary>
/// component类提供了查找组件的功能,可以在当前物体、后代和先辈中查找
/// </summary>
public class ComponentDemo : MonoBehaviour
{
    private void OnGUI()
    {
        if(GUILayout.Button("GetComponent"))
        {
            this.GetComponent<MeshRenderer>().material.color = Color.red;
        }
        if (GUILayout.Button("GetComponents"))
        {
            //获取当前物体所有组件
            var allComponent = this.GetComponents<Component>();
            foreach(var item in allComponent)
            {
                Debug.Log(item.GetType());
            }
        }
        if (GUILayout.Button("GetComponents2"))
        {
            //获取后代物体的指定类型组件(从自身开始查找)
            var allComponent = this.GetComponentsInChildren<MeshRenderer>();//GetComponentsInParent(获取先辈物体的...)
            foreach (var item in allComponent)
            {
                item.material.color = Color.red;
            }
        }
    }
}
           

Transform

Transform:Transform提供了查找(父、根、子)变换组件、改变位置、角度、大小功能

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

Translate

移动transform在translation的方向和距离。

简单的说,向某方向移动物体多少距离。

Rotate

应用一个欧拉角的旋转角度,eulerAngles.z度围绕z轴,eulerAngles.x度围绕x轴,eulerAngles.y度围绕y轴(这样的顺序)。

TransformPoint

变换位置从局部坐标到世界坐标

注意,返回位置受缩放影响。如果你是处理方向使用Transform.TransformDirection。

Find

通过名字查找子对象并返回它。

如果没有查找到子对象名字,将返回null。如果名字包含“/”字符它将向路径一样穿越层次。

SetSiblingIndex

设置同级对象的索引。

/// <summary>
/// Transform提供了查找(父、根、子)变换组件、改变位置、角度、大小功能
/// </summary>
public class TransformDemo : MonoBehaviour
{
    public Transform tf;
    //****************查找变换组件*********************
    private void OnGUI()
    {
        if(GUILayout.Button("foreach -- transform"))
        {
            foreach(Transform child in this.transform)
            {//child为 每个子物体的变换组件
                print(child.name);
            }
        }
        if (GUILayout.Button("root"))
        {
            //获取根物体变化组件
            Transform rootTF = this.transform.root;
        }
        if (GUILayout.Button("parent"))
        {
            //获取父物体变化组件
            Transform parentTF = this.transform.parent;
        }
        if (GUILayout.Button("Setparent"))
        {
            //设置父物体 
            //当前物体的位置 视为 世界坐标
            //this.transform.SetParent(tf);

            //当前物体的位置 视为 localPosition
            this.transform.SetParent(tf,false);
        }
        if (GUILayout.Button("Find"))
        {
            //根据名称获取子物体
            Transform childTF = this.transform.Find("子物体名称");
        }
        if (GUILayout.Button("Find"))
        {
            int count = transform.childCount;
            //根据索引获取子物体
            for (int i = 0; i < count; i++)
            {
                Transform childTF = this.transform.GetChild(i);
            }
        }
        //****************改变位置、角度、大小*********************
        if (GUILayout.Button("pos / scale"))
        {
            //物体相对于世界坐标系原点的位置
            //this.transform.position

            //物体相对于父物体轴心点的位置
            //this.transform.localPosition

            //相对于父物体的缩放比例
            //this.transform.localScale

            //理解为:物体与模型缩放比例(自身缩放比例 * 父物体缩放比例
            //this.transform.lossyScale
 
            //lossyScale为只读型,不能像localScale那样更改
        }

        if(GUILayout.Button("Translate"))
        {
            //向自身坐标系z轴移动一米
            //this.transform.Translate(0, 0, 1);
            //向世界坐标系z轴移动一米
            this.transform.Translate(0, 0, 1,Space.World);
        }
        if (GUILayout.Button("Rotate"))
        {
            //向自身坐标系y轴旋转10度
            this.transform.Rotate(0, 0, 1);
            //向世界坐标系y轴旋转10度
            //this.transform.Rotate(0, 0, 1,Space.World);
        }
        if (GUILayout.RepeatButton("RotateAround"))
        {
            this.transform.RotateAround(Vector3.zero, Vector3.up, 1);
        }
    }

}
           

GameObject

GameObject游戏对象:GameObject提供了添加、设置游戏对象,查找、销毁游戏对象的功能

UnityUnity脚本和常用API学习记录一、脚本二、开发工具三、脚本生命周期四、调试五、常用API

AddComponent

给游戏物体添加一个名称为componentType的组件类。

Find

找到并返回一个名字为name的游戏物体。

FindGameObjectsWithTag

返回具体tag标签的激活的游戏对象列表,如果没有找到则为空。

Object.FindObjectOf

返回Type类型第一个激活的加载的对象。

/// <summary>
/// GameObject提供了添加、设置游戏对象,查找、销毁游戏对象的功能
/// </summary>
public class GameObjectDemo : MonoBehaviour
{
    private void OnGUI()
    {
        //在场景中物体激活状态(物体实际激活状态)
        //this.gameObject.activeInHierarchy
        //物体自身激活状态(物体在Inspector面板中的状态)
        //this.gameObject.activeSelf
        //设置物体启用/禁用
        //this.gameObject.SetActive()

        if(GUILayout.Button("添加光源"))
        {
            //Light light = new Light();   无效
            //要想添加光源
            //创建组件
            GameObject lightGo = new GameObject();
            //添加组件
            Light light = lightGo.AddComponent<Light>();
            light.color = Color.red;
            light.type = LightType.Point;
        }

        //在场景中根据名称查找物体(慎用)
        //GameObject.Find("游戏对象名称");

        //获取所有使用该标签的物体
        GameObject[] allEnemy = GameObject.FindGameObjectsWithTag("Enemy");
        //获取使用该标签的物体(单个)
        GameObject playerGo = GameObject.FindWithTag("player");

        //Object

        //根据类型查找对象
        //Object.FindObjectOfType<MeshRenderer>();
        //FindObjectsOfType<MeshRenderer>();
        //销毁对象
        //Object.Destroy
    }
}