Unity脚本介绍和常用API

脚本介绍

在这里插入图片描述

1.脚本

介绍

  • 脚本是附加在游戏物体上用于定义游戏对象行为的指令代码
  • Unity支持三种高级编程语言:
    C#、JavaScript 和 Boo Script(unity4以前支持的)

语法结构

using 命名空间;
public class 类名:MonoBehaviour
{
    void 方法名()
    {
        Debug.Log("调试显示信息");
        print("本质就是Debug.Log方法");
    }
}
  • 文件名与类名必须一致(如果在Unity里更改了C#文件的名称,在Visual Studio里也要改类名)
  • 写好的脚本必须附加到物体上才执行
  • 附加到游戏物体的脚本类必须从MonoBehavior类继承

编译过程

  • 编译运行过程
    源代码 --(CLS)-> 中间语言 – (Mono Runtime) -> 机器码

2.开发工具

MonoDevelop

  • unity自带的脚本编辑器,创建Mono应用程序,适用于Linux、Mac OS X和Windows的集成开发环境,支持C#和JavaScript等

Visual Studio

  • 微软公司的开发工具包,包括了整个软件生命周期中需要的大部分工具,如团队开发工具,集成开发环境等等。
  • 在Unity中通过菜单设置修改默认的脚本编辑器:
    在这里插入图片描述

3.脚本生命周期

简介

  • unity脚本从唤醒到销毁的过程
  • 消息(也叫必然事件):当满足某种条件Unity引擎自动调用的函数

脚本和C#类有几点不同,首先,脚本里的字段如果访问级别为public,那么可以直接在unity里看见,访问级别为private,那么在unity里会隐藏。如果private字段想在unity里显示,需要在前面写[SerializeField],如果public字段不想显示,需要在前面写[HideInInspector]

此外,脚本里不能写属性和构造函数,只能写方法。

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

/// <summary>
/// 脚本生命周期/必然事件/消息
/// </summary>
public class Lifecycle : MonoBehaviour
{
    //脚本:.cs的文本文件  类文件
    //        附加到游戏物体中,定义游戏对象行为指令的代码

    //c#类
    //字段
    //属性
    //构造函数
    //方法


    //脚本
    //字段
    //方法

    //序列化字段  作用:在编译器中显示私有变量
    [SerializeField]
    private int a = 10;

    //作用:在编译器中隐藏字段
    [HideInInspector]
    public float b;

    [Range(0, 100)]
    public int c;

    //属性在编译器中不能显示,通常脚本中不写
    public int A
    {
        get
        { return this.a; }
        set
        {
            this.a = value;
        }
    }

    public Lifecycle()
    {
        //Debug.Log("构造函数");
        //不要在脚本里写构造函数
        //不能在子线程中访问主线程成员
        //b = Time.time;
    }

    private int d;
    //*********************初始阶段***************************
    //执行时机:创建游戏对象 --》 立即执行1次 (早于Start)
    //作用:初始化
    private void Awake()
    {
        Debug.Log("Awake--" + Time.time + "--" + this.name);
    }
    //执行时机:创建游戏对象 --》脚本启用--》 才执行(1次)
    //作用:初始化
    private void Start()
    {
        d = Random.Range(1, 101);
        Debug.Log("Start--" + Time.time + "--" + this.name);
    }
}

脚本生命周期的阶段

1.初始阶段

在这里插入图片描述
初始阶段有两个重要方法:Awake和Start
Awake:执行时机:创建游戏对象 --》 立即执行1次 (早于Start)
作用:初始化

Start:执行时机:创建游戏对象 --》脚本启用–》 才执行(1次)
作用:初始化

一般情况下初始阶段只在脚本里写Start即可,除非需要在执行Start函数之前先判断是否执行该函数,才写Awake,因为Awake的调用时机始终在Start之前。

2.物理阶段

在这里插入图片描述
物理阶段方法:FixedUpdate
FixedUpdate:固定更新,Unity初始值为0.02s,一般不作修改。
执行时机:每隔固定时间,执行一次。(时间可以修改)
适用性:适合对物体做物理操作(移动,旋转…),不会受到渲染影响

输入事件

在这里插入图片描述

游戏逻辑

Update:更新,时间不固定,脚本启用后每次渲染场景时调用,频率与设备性能及渲染量有关
执行时机:渲染帧执行,执行间隔不固定
适用性:处理游戏逻辑,比如让物体移动,旋转
因为在Update里写游戏逻辑比较方便,所以Update比Fixedupdate更常用

LateUpdate:延迟更新,在Update函数调用后执行,适用于跟随逻辑

场景渲染

OnBecameVisible 当可见:
当Mesh Renderer在任何相机上可见时调用

OnBecameInvisible 当不可见:
当Mesh Renderer在任何相机上都不可见时调用

3.结束阶段

OnDisable 当不可用:
对象变为不可用或附属游戏对象非激活状态时此函数被调用

OnDestroy 当销毁:
当脚本销毁或附属的游戏对象被销毁时被调用

OnApplicationQuit 当程序结束:
应用程序退出时被调用

4.调试

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

Unity编辑器调试

  • 1.控制台调试
    Debug.Log(变量);

    print(变量);

  • 控制台(console)面板可用快捷键Ctrl+Shift+C打开,建议勾选其中的Clear On Play(运行时清空),Collapse(折叠相同项),同时注意必须勾选右上角的三个感叹号中的第一个,否则即使有错误也不会显示内容,只显示错误数目。控制台调试只适合简单调试,而且调试完后记得要删除调试语句,不然会非常占用资源。

  • 2.定义共有变量,程序运行后在检测面板(Inspector)查看数据
    若想查看数据的实时变化规律,可以先定义一个变量,然后在Inspector面板查看

Unity编辑器进行调试,只适合一些小的问题调试

使用VS调试

因为脚本是在vs里编写的,所以程序员更愿意直接在vs里进行调试,而且vs功能很强大,可以调试绝大多数问题。我用的是vs2019,安装时就有unity调试工具。
调试步骤:
(1)在可能出错的行添加断点
(2)启动调试
(3)在Unity中Play场景
(4)在vs中按F11逐条调试
(5)调试完毕按F5退出调试

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

因为Update和其他方法不同,它是逐帧运行的,所以在调试时需要单帧调试

  • 步骤:启动调试->运行场景->暂停游戏->加断点->单帧执行->结束

常用API

在这里插入图片描述

核心类图

在这里插入图片描述
因为Unity类与类之间有继承关系,子类可以使用父类的方法,从而使编程更加方便

1.Component

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

/// <summary>
/// component类提供了查找组件的功能,可以在当前物体、后代和先辈中查找
/// </summary>
public class ComponentDemo : MonoBehaviour
{
    private void OnGUI()
    {
        if (GUILayout.Button("transform"))
        {
            this.transform.position = new Vector3(0,0,10);
        }
        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;
            }
        }
    }
}

2.Transform

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

/// <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
            //如:父物体localScale为3  当前物体localScale为2
            //    lossyScale为6
            //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);
        }
    }

}

3.GameObject

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

/// <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
    }
}
  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值