Unity读书系列《Unity3D游戏开发》——脚本(一)

这篇具有很好参考价值的文章主要介绍了Unity读书系列《Unity3D游戏开发》——脚本(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

脚本在Unity的重要程度不用多说,她是大部分软件的核心组件。
我们将在此篇文章学习脚本模版及其拓展、脚本的生命周期、脚本的执行顺序、脚本序列化,下一篇为脚本编译与调试。


一、脚本模版及其拓展

1、脚本模版

如下图我们可以在Project视图右键进行脚本创建,除了C#脚本,还有两类脚本;Testing用来做单元测试,Playables是TimeLine引入的新概念。
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎
通常来讲我们会根据项目修改脚本模版,位置在Unity安装位置的Resource文件夹内,例如:“C:\Program Files\Unity 2021.3.16f1\Editor\Data\Resources\ScriptTemplates”。除了按照项目修改模版,通常会将脚本编码改成UTF-8并在脚本模版中加入中文或中文字符。
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎

2、拓展脚本模版

如果按上述方法修改脚本模版会十分麻烦,不说每个版本的unity都需要修改,项目里每个成员都需要修改,当模版变动难道每个人都要重新修改吗。我们想做到版本管理可以拓展脚本的方式添加模版。

二、脚本的生命周期

Unity脚本有一套完整的生命周期,无需手动调用。其中包含初始化、更新回调、渲染、销毁,我们经常使用的协程等也在其内。
官方解释:
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎
书中解释:
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎

三、脚本的执行顺序

在上一章中当有两个脚本标记了"[CustomEditor(typeof(Camera))]",只会执行第一个创建的脚本逻辑。
为什么呢?Unity的脚本可以预先挂载场景中,也可以在运行时动态添加,所以用Script Execution Order使用来管理脚本的执行顺序,我们可以在此添加脚本并设置顺序。
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎
我们考虑一件事,现在有多个脚本,A脚本在Awake获取B脚本的数据,A如果比B先执行那就会报错。实际上这种时序的问题还会发生在项目越发复杂,初始化过多的情况。不仅如此,多个脚本还会产生多余消耗,假设每个脚本都有初始化(Awake、Start等)和更新(Update)的方法,几百个脚本同时运行,性能差的主机可能分分钟卡死。
解决方法:将系统分类,每个系统的初始化等功能都设置入口,功能统一调用。初学者推荐尝试单例的写法来管理小项目,再根据项目尝试工厂模式、适配器模式等设计模式,最后学习框架的思想。

四、脚本序列化

想了解脚本序列化,首先我们需要明白脚本本身并没有保存数据,而是将数据保存于文件中,也就是脚本可以通过序列化和反序列化来保存游戏。
书中举例,给场景其中一个物体加上脚本Test.cs,再找一个预制体Prefab.prefab加上脚本Test.cs。接下来我们修改场景中的脚本数据,也就是Id,那么数据将保存在Scene.unity;同理,在Project下修改预制体上的脚本Id,那么数据会保存在预制体文件夹内。

如果把预制体赋值到场景的脚本中(脚本中的public GameObject prefab;),那么数据会存在Scene.unity。大家仔细想想,平常雀氏是这样操作的,只是不明所以罢了。

public class Test : MonoBehaviour
{
	public int Id;
	public GameObject prefab;
}

1、序列化数据

打开上面的预制体和场景,就会发现里面存着序列化的数据,这里不做展示。
通常,公开的对象会支持序列化格式,如果不想显示可以加上[HideInInspector],私有序列化需要再代码上加上[SerializeField]。

public class Test : MonoBehaviour
{
	[SerializeField]
	private int Id;
	[SerializeField]
	private GameObject prefab;
}

假如我此时还想访问呢,直接请出serializedObject.FindProperty()访问私有属性。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class Script_04_08 : MonoBehaviour
{
    [SerializeField]
    private int id;
    [SerializeField]
    private string name;
    [SerializeField]
    private GameObject prefab;
}

#if UNITY_EDITOR
[CustomEditor(typeof(Script_04_08))]
public class ScriptInsector : Editor
{
    public override void OnInspectorGUI()
    {
        //更新最新数据
        serializedObject.Update();
        //获取数据信息
        SerializedProperty property = serializedObject.FindProperty("id");
        //赋值数据
        property.intValue = EditorGUILayout.IntField("主键", property.intValue);

        property = serializedObject.FindProperty("prefab");
        property.objectReferenceValue = EditorGUILayout.ObjectField("游戏对象",
            property.objectReferenceValue,typeof(GameObject),true);

        //全部保存数据
        serializedObject.ApplyModifiedProperties();
    }
}
#endif

2、serializedObject

serializedObject只能在Editor中使用,它专门用于获取设置的序列化信息。通常,要开发复杂的编辑组件,都需要重写OnInspectorGUI()方法,但是如果希望有些用源生的绘制结构,同时兼容有些自定义渲染的话,那该怎么办呢?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class SerializedObjectTest : MonoBehaviour
{
    [SerializeField]
    private int id;
    [SerializeField]
    private GameObject[] targets;
}

#if UNITY_EDITOR
[CustomEditor(typeof(SerializedObjectTest))]
public class ScriptInsector : Editor
{
    public override void OnInspectorGUI()
    {
        //更新最新数据
        serializedObject.Update();
        //获取数据信息
        SerializedProperty property = serializedObject.FindProperty("id");
        //赋值数据
        property.intValue = EditorGUILayout.IntField("主键", property.intValue);
        //以默认样式绘制数组数据
        EditorGUILayout.PropertyField(serializedObject.FindProperty("targets"), true);
        //全部保存数据
        serializedObject.ApplyModifiedProperties();
    }
}
#endif

效果如下:
Unity读书系列《Unity3D游戏开发》——脚本(一),读书系列之《Unity3D游戏开发》,unity,游戏引擎

3、监听部分元素修改事件

脚本面板中,参与绘制的元素都是在OninspectorGUI中绘制的。我们想监听其中的一个元素有两种方法,第一种适用于简单的脚本,在脚本中写入Onvalidate(),当面板信息发生改变就会回调该方法;

void Onvalidate(){
Debug.log("信息改变");
}

第二种需要监听GUI的元素写在EditorGUI.BeginChangeCheck()。我们监听变化则需要在if(EditorGUI.EndChangeCheck()) 中处理。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class Test : MonoBehaviour
{
    [SerializeField]
    private GameObject[] targets;
}

#if UNITY_EDITOR
[CustomEditor(typeof(Test))]
public class ScriptInsector : Editor
{
    public override void OnInspectorGUI()
    {
        //更新最新数据
        serializedObject.Update();
        //标记检查
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("targets"), true);
        //标记检查发生变化
        if(EditorGUI.EndChangeCheck()) {
            Debug.Log("元素发生变化");
}
        //判断面板元素是否任意发生改变
        if(GUI.changed) {

        }
        //全部保存数据
        serializedObject.ApplyModifiedProperties();

    }
}
#endif

五、定时器与间隔定时器

通常我们可以用协程做定时器,缺陷是依赖于脚本,所以封装一个不依赖脚本实现的定时器是很有必要的。
详细使用请看定时器与间隔定时器。

六、工作线程(多线程)

工作线程(多线程)是指在一个程序中同时执行多个任务的能力。多线程编程可以提高程序的性能和响应性,特别是在需要同时执行多个任务的情况下。工作线程通常用于执行耗时的任务,以避免阻塞主线程,从而保持程序的流畅性。
目前很多主流游戏或软件在启动或下载等待时会使用多线程技术,应用十分广泛。
详细使用请看Unity多线程。


总结

这篇文章将介绍Unity中脚本的核心概念和重要性。我们探讨如何创建和定制脚本以满足特定需求,以及脚本的生命周期、执行顺序和序列化等内容。后面两个示例(定时器和工作线程的运用)我分别用单独的章节说明,如果需要再去学习运用;这种安排旨在强调项目驱动的学习方式,同时鼓励读者在实践中运用这些示例来更快地提升自己的技能。逐步学习并根据需求应用所学知识,将使读者能够更有效地掌握相关技能。
最后,感谢大家观看,欢迎讨论指正错误,别忘了点赞👍。文章来源地址https://www.toymoban.com/news/detail-860671.html

到了这里,关于Unity读书系列《Unity3D游戏开发》——脚本(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Unity3D】Unity 脚本 ③ ( C# 脚本的执行入口函数 | 获取当前游戏物体及物体名称 | 获取游戏物体的 Transform 组件数据 | UnityEngine 命名空间简介 )

    在 C# 脚本中控制 游戏物体 GameObject 运动 , 要先获取该物体 , 然后 修改其 Transform 组件的属性 ; 在 游戏开始运行后 , 会自动执行 游戏物体 GameObject 上的 C# 组件代码 , 程序入口是 MonoBehaviour#Start() 函数 ; 在 C# 脚本中 , 主要的内容都在 Start() 函数 中实现 ; 在 C# 脚本中 , 游戏物体

    2023年04月12日
    浏览(52)
  • Unity3D 脚本3(旋转)

    一、物体的旋转 给物体调转一个旋转角度。 1、Quaternion四元组(x,y,z,w) transfrom.rotation()=... 不方便操作,官方不建议用 2、Euler Angle 欧拉角 transfrom.eulerAngles = new Vector(0,45,0); transfrom.LocalE ulerAngles = new Vector(0,45,0); 这样就可以让物体旋转45度。 在Update 中修改角度持续旋转 Vecto

    2023年04月16日
    浏览(41)
  • 【Unity3D脚本】Transform类

    欢迎大家学习指正 目录 一、Transform类简介 二、个别核心功能介绍 1.查找变换组件  2.改变位置、角度 1.缩放 2.移动 3.旋转  4.设置父物体  总结 一、Transform类简介 Transform类提供了查找(父、根、子)变换组件、改变位置、角度、大小功能 场景中的每一个对象都有一个Trans

    2024年02月16日
    浏览(30)
  • Unity3D教程:抓取物件脚本、变数、名称

    游戏中相当常使用的功能GetComponent,经常用来Get(取得)物件上的Component(组件)资讯,若没有取得组件会回传null值。 gameObject . GetComponent ( “ScriptName” ); 如果发现要抓取GetComponent上的值为大写可能就要注意一下原本的变数是否为小写如图1所示: TextMesh 是3D Text上原本就包含的

    2024年02月15日
    浏览(28)
  • 【unity3D】退出游戏功能的实现

    💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的退出游戏功能的实现 新建一个button按钮,在Hierachy面板点击右键,然后UI—Button。 调节Button位置和Button下面Text文本的内容和大小。 新建一个脚本 新建一个空物体,然后

    2024年02月11日
    浏览(40)
  • Unity3D教程:2D游戏技能特效

    在我们的2D图形游戏中不可缺少大量的光影、技能特效,像Diablo II中的魔法效果的实现,幸好我们拥有强大的CPU来为我们实现Alpha混合与色彩饱和混合,接下来让我们来讨论一下如何用这些方法来实现我们游戏中所需要的技能特效。     一、Alpha混合特效     Alpha混合可以让我

    2024年02月01日
    浏览(29)
  • 使用Unity3D制作2D游戏的重点做法

    官网上有提供一个 2D游戏的教学范例 ,这个游戏只不过把镜头摆放在横向位置跟随角色移动,游戏内物件运动时固定一个轴不动,使他像横轴式的2D游戏来玩,本质上其实还是个3D游戏,所以如果没有3D建模的话不就没办法做2D游戏了?其实这些并没有定论,就看制作者如何运

    2024年02月11日
    浏览(35)
  • 以unity3d为例解读:游戏数据加密

    目录 前言 1、Virbox 一、Virbox 是怎么做的? 1、如何对程序进行保护? 2、如何对资源进行保护? 3、使用加密工具前后比较 二、Virbox 保护方案特点 l 更安全 l 更全面 l 更简单 2、DES和RSA加密算法 一、DES加密算法 二、RSA加密算法 RSA加密算法的基本流程如下: 网络游戏数据文

    2024年02月02日
    浏览(50)
  • 【Unity3D】如何用使用Unity实现退出游戏的功能

    1、使用Unity编译器时: 2、打包后: 很多时候,我们都知道Application.Quit()代码,但是我们在Unity编译器调试的时候发现即使挂上了这个代码的组件或物体都无法退出编译,因为该代码只在打包后可以实现退出功能。 所以我们可以把两个实现代码同时写入脚本,这样既可以在编

    2024年02月11日
    浏览(42)
  • Unity3D项目之游戏场景小地图制作

    创建一个场景资源,可在asset store资源商店下载,选择心仪场景。 链接:https://assetstore.unity.com/?locale=zh-CN 添加一个对象GameObject,命名为player,子物体包括:主摄像机,角色,后面步骤会添加一个plane。 添加一个地图摄像机,命名为MapCamera。修改属性projection为OrthoGraphic;Size为

    2024年02月11日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包