unity——C#

一.unityC#脚本基础

如图是unity中C#脚本的基本框架,我们来解释一下:

1.using UnityEngine:引入unity引擎的命名空间,如果我们想使用unity引擎自带的功能,那么必须引入这个命名空间。

2.public class NewMonoBehaviourScript : MonoBehaviour:这里MonoBehaviour是所以几乎所有unity脚本的基类,我们编写的unity脚本类一般必须继承这个类。

1.生命周期方法

1.void Start() { ... }

执行时机:它会在脚本被启用后、第一帧的 Update 执行之前,自动调用一次。

作用:通常用来做"准备工作"。比如初始化变量、获取场景中其他物体的引用、设置游戏的初始状态等。

2.void Update() { ... }

执行时机:它会在游戏的每一帧都被自动调用一次。如果游戏运行在 60帧/秒,Update 里的代码 1 秒钟就会执行 60 次,但是相邻帧的时间间隔不一定相同。

作用:通常用来处理需要实时变化的逻辑。比如检测玩家的按键输入、让角色持续移动、倒计时等。

3.void Awake() { ... }

最早调用的函数,只调用一次。

4.void onEnable() { ... }

与void Start() { ... }的区别:

Start():脚本的一生中只执行一次。

OnEnable():脚本每激活一次,就会执行一次。如果物体反复开关,它就会反复调用

5.void FixedUpdate()

默认固定时间间隔0.02秒会调用一次,可以在设置中更改。

6.void LateUpdate()

在所有的Update方法执行完之后调用。

7.void OnDisable()

与void onEnable相似,在脚本被设置为非激活状态会调用一次。

8.void OnDestory()

在脚本销毁时调用一次。

一般函数的调用顺序

1.Awake ------ 最早。不管物体是否激活,只要脚本0实例存在就会调用。只调一次。

2.OnEnable ------ 其次。只有在物体处于激活状态时才会调用。每次激活都会调。

3.Start ------ 最后。在第一次帧更新前调用。只调一次(前提是物体是激活的)。

需要注意的是:这些生命周期方法使用的类都必须继承MonoBehaviour。

2.脚本的调用顺序

默认是先创建的脚本先执行,但是如果我们使用start方法进行初始化,这可能会造成初始化问题,所以我们一般使用Awake方法进行初始化,此外,如果我们还想要控制一些脚本的执行顺序,可以在unity中设置。

3.变量的设置

我们可以在C#脚本使用public作用域来声明一个变量,通过这种方法声明的变量可以在unity中直接设定器数值,而如果我们定义一个private的变量,那么只有这个脚本中能够访问,不能在unity中设定

二.调试方法

1.Debug.Log("test"),普通输出test。

2.Debug.LogWaring("test"),警告输出tset

3.Debug.LogError("test"),错误输出

4.Debug.DrawLine(vector3.zero,vector3.one),画线,基础接收两个参数,表示画出直线的起始位置坐标与结束位置坐标。

5.Debug.DrawRay(vector3.zero,vector3.one),画射线,基础接收两个参数,表示画出的直线的起始位置与方向,4与5相同,也可以接收第三个参数,Color.red/blue等,表示画出线的颜色。

三.vector3

vector3最常见的作用是表示一个三维向量,当然其还能表示坐标,旋转等。

1.初始化方式

(1)基本初始化方式:vector3 v=new vector3(1,2,3)

(2)初始化属性:vector3 v=vector3.zero/one/left/right/foward等;

也可以:v.x,v.y,v.z这样的赋值。

2.常见方法

(1)求两个向量的夹角:vector3.Angle(vector3.zero,vector3.one),接收两个向量。

(2)计算两个坐标之间的距离:vector3.Distance(vector3.zero,vector3.one),接收两个坐标,计算它们之间的距离。

(3)向量点乘:vector3.Dot(vector3.zero,vector3.one),接收两个向量,计算它们点乘的结果。

(4)向量叉乘:vector3.Cross(vector3.zero,vector3.one),接收两个向量,计算叉乘的结果(向量的叉乘就是造出一个与这两个向量都垂直的向量,且这个向量的长度等于原来两个向量围城的面积)。

(5)插值:vector3.Lerp(vector3.zero,vector3.one,0.5f),接收两个向量与一个叉乘系数t(0<t<1)(插值的作用是根据插值系数t,找到一个位于传入坐标之间的等比例的坐标,数学计算公式是a+(b-a)*t,我们这里假设传入的第一个参数是a,第二个是b,常见的插值系数t是0.5,即找到一个位于坐标a,b之间的坐标)

3.常见属性

(1)取向量的模:v.magnitude,获取向量v的模,sqrMagnitude,获取向量模的平方,计算量小于直接取模,可用于比较两个向量的长度大小。

(2)单位化向量/规范化向量:v.normalized,将返回向量v化为单位向量的结果。

4.Vector2

此外,如果我们需要使用二维的向量,如UI的制作,也可以使用Vector2

四.欧拉角与四元数

欧拉角与四元数都是描述旋转的变量,一般在脚本中,考虑到计算的效率问题,我们都使用四元数

欧拉角的表示使用的就是vector3。

四元数:

1.初始化方法

(1)Quaternion q=new Quaternion(x,y,z,w),基础初始化方式,接收数个整数。

(2)初始化属性:Quaternion q=Quaternion.idenity,无旋转的四元数。

利用欧拉角转化为四元数:Quaternion q=Quaternion.Euler(x,y,z)

我们也可以通过看向一个位置进行初始化:Quaternion q=Quaternion.LookRotation(x,y,z)

我们也可以将一个四元数转化为欧拉角:vector3 v=q.eulerAngles;

五.物体类的使用

unity中所有游戏物体的类都是GameObject。

1.脚本代码中获取物体

(1)GameObject go=this.gameObject;

(2)我们也可以简写为gameObject,其就是这个游戏物体。

(3)获取其他游戏物体:public GameObject x,获取该物体的子物体命名为x(记得在unity中将该子物体挂载到该物体的脚本中)

(4)我们还可以通过游戏物体的名称来获取游戏物体:GameObject 命名 =GameObject.Find("游戏物体的名称")

(5)通过标签来获取游戏物体:GameObject 命名 =GameObject.FindWithTag("游戏物体的标签"),如果存在多个物体使用同一个标签,会发生覆盖,对于多个物体使用同一个标签,我们可以使用FindGameObjectsWithTag,返回一个物体类类型的数组。

2.常见属性与方法

(1)获取游戏物体的名字:go.name

(2)获取游戏物体的标签:go.tag

(3)获取游戏物体的图层:go.layer

(4)获取游戏物体的激活状态:x.activeInHierarchy/activeSelf(注意这里不要对父物体使用,因为脚本挂载在父物体上,如果父物体未激活的话,那么脚本根本不会运行),

这里activeInHierarchy是获取当前真正的激活状态(或者说父物体的激活状态,因为一旦父物体未激活,其子物体也不会激活),activeSelf获取的是物体自身的激活状态(其不一定真正激活,这取决于其父物体)。

(5)获取游戏物体的Transform组件:如我们所有游戏物体都有Transform组件:Transform t=this.transform(一个游戏组件其实就是一个脚本,对应一个类,所以Transform的类型就是Transform类),与GameObject相同,我们在使用时也可以直接使用:transform.position(获取位置)

(6)获取游戏物体的其他组件:需要通过泛型:模式:该组件的类 命名 =GetComponent<给组件的类>(),GetComponent也可以显示的指定一个游戏物体:GameObject.GetComponent

(7)获取当前游戏物体的子/父物体上的组件:与(6)格式相同,

使用GetComponentInChildren/GetComponentInParent。

(8)添加一个组件:ganmObject.AddComponent<组件类>();

(9)设置一个游戏物体的激活状态:go.SetActive(true/false);

(10)通过代码将一个预设体实例化为一个真正的物体:

获取预设体:public GameObject x,然后在unity中将预设体挂载到脚本上

实例化预设体:Instantiate(x);

实力化一个预设体并将其作为当前游戏物体的子物体:Instantiate(x,transform);

实力化一个预设体并为其设置位置,旋转等:Instantiate(x,Vector3.zero,Quaternion.indentity);

(11)设置一个组件的激活状态:组件名.enable=true/false。

销毁生成的游戏物体:Destory(该游戏对象)重载接收第二个参数表示销毁的时间。

六.时间类

unity中时间类是Time。

1.常见属性与方法

(1)获取游戏从开始到现在所花费的时间:Time.time

(2)更改时间缩放值:Time.timeScale,默认为1,可用于实现加速,减速与时间的暂停。

(3)固定时间间隔:Time.fixedDeltaTime(0.02秒)

(4)上一帧到这一帧所用的游戏时间:Time.deltaTime,可用于制作计时器

七.Application类

常用于在 Unity 中进行存档、读取配置文件或加载外部资源。

1.常见属性与方法

(1)获取游戏数据文件夹路径(Assets文件夹路径):Application.dataPath,返回对应路径字符串,一般情况是只读,程序打包以后该路径中的内容会被加密压缩,但是如果游戏只是pc端的,那么这里是可读,可写的,我们可以通过字符串拼接的方式访问该文件夹中的文件,但是对于移动端来说,该路径位于安装路径下,不可写。

(2)获取持久化文件夹路径:Application.persistentDataPath,可读可写,一般用于游戏的存档

(3)StreamingAssets文件夹路径:Application.streamingAssetsPath,只读,并不会加密压缩

(4)临时文件夹路径:Application.temporaryCachePath,

(5)控制是否在后台运行:Application.runlnBackground;

(6)打开一个链接:Application.OpenURL(" ")打开一个链接

(7)退出游戏:Application.Quit();

八.场景类与场景管理类

使用场景类需要先导入场景管理类的命名空间:using UnityEngine.SceneManagement

场景管理类为SceneManager,场景类为Secene

1.常见属性与方法

(1)同步加载场景:SceneManager.LoadScene(1),接收一个场景索引(记得在unity中将场景添加到场景列表中)

(2)我们也可以使用场景的名称来跳转:SceneManager.LoadScene(" "),也可以接收第二个参数表示替换加载(只显示一个场景)SceneManager.LoadScene("new scene",LoadSceneMode.Single),表示叠加加载(同时显示两个场景):SceneManager.LoadScene("new scene",LoadSceneMode.AddActive)

异步加载:SceneManager.LoadSceneAsync("new scene"),对于大型场景,同步加载会发生卡顿,为了解决这种情况,我们需要使用异步加载,在加载的同时设计一个进度条,同时对于大规模场景,我们一般会对场景进行划分,动态的生成玩家周围的场景,以节省性能。

(3)获取当前激活的场景:Secene s=SceneManager.GetActiveScene();

(4)获取场景的名称:s.name

(5)场景是否被加载:s.isLoaded

(6)场景路径:s.path

(7)查看场景索引:s.buildIndex

(8)获取场景中所有的游戏物体:GameObject \[\] gos=scene.GetRootGameObject(),返回一个包含所有游戏物体的数组,只能获取最外层的游戏物体,即无法获取子物体

(9)获取当前加载的场景数量:SceneManager.sceneCount;

(10)创建一个新场景:SceneManager.CreateScene("命名")

(11)卸载一个场景:SceneManager.UnloadScene(s)(同步)

SceneManager.UnloadSceneAsync(s)(异步)

2.unity协程简介

假如我们想要异步的加载一个场景,就需要使用到协程,协程与C#的异步不同但相似,都是为了解决线程阻塞的问题。

使用协程必须引入using System.Collections;

如图是一个协程的基本框架,也是异步创建场景的实现。

获取加载进度:asyncLoad.progress,一般该操作放在Update函数中,加载进度是从0到0.9。

场景自动跳转设置:asyncLoad.allowSceneActivation=true/false(默认是true表示自动跳转)

九.Transform类

Transform类控制游戏物体的位置,旋转,缩放以及父子关系。

1.常见方法与属性

(1)获取位置:transform.position,获取游戏物体在世界中的位置,

transform.localposition,获取游戏物体相对于父物体的位置。

(2)获取旋转:transform.rotation,获取游戏物体在世界中的旋转

transform.localRotation,获取游戏物体相对于父物体的旋转,这俩种都是四元数表示

欧拉角表示:transform.eulerAngles,获取游戏物体在世界中的旋转

transform.localEulerAngles,获取游戏物体相对于父物体的旋转

(3)获取缩放:transform.localScale,获取游戏物体相对于父物体的缩放

(4)获取当前物体的方向:transform.forward,获取前方

transform.right获取右方,transform.up,获取上方,(我们一般将unity中y作为上方,z作为前方,x作为右方),返回的都是一个vector3

(5)让物体看向一点:transform.lookAt(Vector3.zero),接收一个vector3,放在Update中实现时刻看向。

(6)实现旋转:transform.Rotate(Vector3.up,1),接收两个参数,旋转的轴,旋转的角度,放在Update中实现时按帧旋转

(7)实现绕某个物体旋转:transform.RotateAround(Vector3.zero,Vector3.up,5)

(8)实现移动:transform.Translate(Vector.forward*0.1f),按0.1的速度向指定方向移动,需要注意的是这种移动方法默认是朝着移动物体的自身认为的方向移动的即是Space.Self,如果这时我们的物体在旋转,比如朝向某个方向,就会导致移动方向出现问题,这时我们就需要加上Space.World,使其使用世界坐标系的方向移动,同时这里的位移计算是输入向量×速度系数(10)×时间(Δt),为了斜向速度与直线速度的统一我们一般需要将传入的向量单位化.normalized

(9)获取父物体的Transform组件:transform.parent,

获取游戏物体:transform.parent.gameObject

(10)获取子物体的个数:transform.childCount

(11)解除与子物体的父子关系:transform.DetachChildren()

(12)获取子物体的Transform组件:transform.Find("子物体名称")

transform.GetChild(0),接收一个索引。

(13)判断一个物体是否是另一个物体的子物体:child.isChildOf(transform),返回一个bool值

(14)设置父物体:child.SetParent(transform),将transform设置为child的父物体。

(15)获取该物体的名字:transform.name与gameObject.name相同

(16)获取自身的其他的组件:transform.GetComponent<组件名>(),但不能通过transform使用AddComponent,原因是AddComponent是定义在GameObject中的,而GetComponent定义在Component基类中。

十.键盘,鼠标操作

对于键盘,鼠标操作我们需要实时监控,所以我们需要将其写在Update中,对于旧版unity的键盘,鼠标操作,都是在Input类中,而在新版,我们需要通过Player Input组件控制。

1.常见方法与属性

旧版

(1)鼠标的点击:if(Input.GetMouseButtonDown(0)),(表示如果鼠标右键单击,则执行什么操作,即返回值是一个bool值,0表示鼠标右键,1表示鼠标左键,2表示鼠标滚轮)

(2)持续按下鼠标:Input.GetMouseButton(0),监听是否持续按下鼠标左键,同样返回bool值

(3)抬起鼠标:Input.GetMouseButtonDownUp(0),监听是否抬起鼠标左键。

(4)键盘操作:与鼠标操作类似:包括按下,持续按下,松开,GetKeyDown,GetKey,GetKeyUp

参数我们可以使用枚举KeyCode.A/B等,也可以使用字符串"a"/"b"等,但注意不能使用大写的字符

串。

(5)获取鼠标点击的位置:Input.MousePosition()

新版

在新版的unity中,我们需要在unity中添加Player Input组件,并创建一个Input Action文件挂载到其上,在Input Action文件中自定义的添加包括键盘,鼠标,虚拟轴,虚拟按键,触摸等。

新版在C#脚本中我们需要直接获取到Player Input组件,进行操作,组件的类为PlayerInput。

(1)开启动作方法:input.CurrentActionMap.Enable()

(2)切换方法:input.SwitchCurrnetAction(" ")

(3)按下动作事件:input.actions"动作命名".performed+=jump,实际上是一个事件。

(4)触发动作:private void jump(InputAction.CallbackContext obj) { },通过事件触发

(5)松开动作事件:input.actions"动作命名".cancled+=jump,这样是将这两种都绑定到了同一个事件上,想要区分,我们可以在这个事件中进行判断,即:if(obj.performed),判断其该属性是否为真。

(6)而对于虚拟轴的设置,我们需要将其设置为Vector2类型的量,我们就需要读取其返回的Vector2了:Vector2 vec2=input.actions"动作命名".readValue<Vector2>();,得到的Vector2就是虚拟轴的表示向量。

(7)获取鼠标点击的位置:Mouse.currnet.position.ReadValue()

十一.虚拟轴与虚拟按键

虚拟轴(Virtual Axis)是 Unity 旧版输入系统(Input Manager)中的一个核心概念,你可以把它理解为一个抽象的、取值范围在 -1 到 1 之间的"数轴",目的是提高兼容性和简化代码。

1.常见方法

(1)获取虚拟轴:旧unity上的方法:float horizontal = Input.GetAxis("Horizontal"),接收虚拟轴的名称

(2)获取虚拟按键:Input.GetButtonDown(" "),接收一个虚拟按键名称,与键盘相同,同样存在

GetButton,GetButtonUp方法

十二.触摸方法

一般用于手机与平板

1.常见方法与属性

(1)开启多点触摸:Input.multiTouchEnabled=true,默认是false

(2)判断触摸次数:Input.touchCount;如果为1,则为单点触摸

(3)创建触摸对象:Touch touch=Input.touches0,根据我们触摸的次数返回对应touches数组中存储的Touch对象,对应的对象存储该触摸的信息。

(4)触摸的位置:touch.position

(5)触摸的阶段:

cs 复制代码
   if(Input.touchCount==1)
        {
            Touch touch=Input.touches[0];
            switch(touch.phase)
            {
                case TouchPhase.Began://触摸开始
                    Debug.Log("Touch Began");
                    break;
                case TouchPhase.Moved://触摸移动
                    Debug.Log("Touch Moved");
                    break;
                case TouchPhase.Stationary://触摸静止
                    Debug.Log("Touch Stationary");
                    break;

                case TouchPhase.Ended://触摸结束
                    Debug.Log("Touch Ended");
                    break;
                case TouchPhase.Canceled://触摸取消
                    Debug.Log("Touch Canceled");    
                    break;
            }
        }

十三.音频类

unity中音频类为AudioClip,音频播放器组件类为AudioSource

1.常见方法与属性

(1)获取音频:public AudioClip music,之后需要在unity中进行音频的挂载。

(2)获取播放器组件:使用获取组件的通用方法:

AudioSource musicPlayer=GetComponent<AudioSource>();

(3)设定播放片段:musicPlayer.cilp=music

(4)设定循环播放:musicPlayer.loop=true

(5)设定音量:musicPlayer.volume

(6)播放:musicPlayer.Play()(无论暂停与否,都从初始状态开始播放);

(7)控制播放的继续与暂停:

musicPlayer.isPlaying,判断是否正在播放,返回bool值,只读

musicPlayer.Stop()停止播放(会将播放进度归零),musicPlayer.Pause()暂停播放(会保存播放进度),musicPlayer.UnPause()继续播放(与musicPlayer.Pause()联用,从当前保存的进度继续播放)

(8)播放音效:musicPlayer.PlayOneShot(),声音可以重叠

(9)对于存在大量音频与音效的,逐个挂载较慢,我们一般采用动态加载的方式,将所所有音频与音效放在Resourse文件夹下,默认放在这个文件夹下的音频可以直接在脚本中查找到:musicPlayer.clip=Resourse.Load<AudioClip>("音频文件名")

2.Resourse文件夹

对于存储在Resourse文件夹下的资源,我们可以在运行时动态加载,通过Resources.LoadAll<T>(path)或者Resources.Load<T>(path),在脚本中获取。

十四.视频类

视频类的使用需要引入UnityEngine.Vedio命名空间,视频类为VedioClip,视频播放器类为VedioPlayer

1.常见方法与属性

(1)获取视频,视频播放器组件与音频操作相同,不再赘述

(2)视频播放同样存在Play,isPlaying,Stop,Pause等音频相同的方法,同样不再赘述。

十五.角色控制类

unity中角色控制类为CharacterControler

如是根据虚拟轴实现的简单移动:

常见方法:(1)简单移动方法:player.SimpleMove(move*20),接收方向*速度,需要按秒移动的话*Time.deltaTime

十六.碰撞与触发监听

碰撞信息类:Conllision,触发类Collider,碰撞与触发非常相似,但是Conllision是碰撞信息类,获取碰撞器需要:collision.collider,但这里的collider就是碰撞器

1.常用方法:

碰撞与触发的检测都要求碰撞双方都存在碰撞器组件,至少又一方存在刚体组件,如果是触发的话,还需要至少有一方存在触发器。

碰撞

(1)监听发生碰撞:private void OnCollisionEnter(Conllision collision)

(2)监听持续碰撞:private void OnCollisionStay(Conllision collision)

(3)结束碰撞方法:private void OnCollisionExit(Conllision collision)

可以通过collision.gameObject.name获取碰撞到的物体。

触发

(1)监听发生碰撞:private void OnTriggerEnter(Collider collider)

(2)监听持续碰撞:private void OnTriggerStay(Collider collider)

(3)结束碰撞方法:private void OnTriggerExit(Collider collider)

注意这两种方法的参数类型不相同,碰撞的参数是Conllision碰撞信息类,获取碰撞组件需要Conllision.Collider,而触发的参数是Collider直接就是触发的物体的碰撞器组件

十七.射线类

unity中射线类是Ray,射线碰撞检测信息类RaycastHit

常见方法属性

(1)创建一条射线:Ray ray=new Ray(Vector3.zero,Vector3.up),接收两个参数,起始位置与方向,

但我们更为常用的是通过摄像机射出(也就是我们从屏幕一点发射的一条射线)一条射线:Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition),接收一个参数,表示鼠标点击的位置。

(2)检测射线是否碰到游戏物体:Physics.Raycast(ray,out hit),返回bool值,表示射线是否碰到带碰撞器的游戏物体,接收两个参数,射线与一个射线碰撞检测类型的变量,记录碰撞的信息,

(3)通过hit碰撞信息,获取射线碰撞物体的坐标位置:hit.point

(4)除了单检测,我们还可以使用多检测:Physics.RaycastAll(ray,100,1<<10),返回一个RaycastHit类型的数组,记录所有检测到的物体的碰撞信息,第二个参数表示检测的射线的距离,第三个参数表示检测第十个图层的物体。

十八.线段与拖尾渲染器

unity中线段渲染器类是LineRenderer

常用方法与属性

(1)获取线段渲染器的方法与通用的获取组件的方法相同

(2)画线:设置线的点的数量:lineRenderer.positionCount=3;

设置点的位置:逐个设置:lineRenderer.SetPosition(0,Vector3.zero),接收两个参数,点的索引与位置。

多个设置:lineRenderer.SetPositions(vec3)接收一个Vector3类型的数组。

(3)其他设置:设置开始颜色:lineRenderer.startColor=Color.white,结束颜色:endColor

开始时的宽度:lineRenderer.startWidth,结束时的宽度:endWidth。

十九.动画类

unity中旧版的动画类为Animation,新版的为Animator

常用方法与属性

旧版

(1)获取动画播放组件的方法与通用的获取组件的方法相同

(2)播放动画,animation.Play(" "),接收一个参数,要播放的动画的名称。

新版

(1)获取动画播放组件的方法与通用的获取组件的方法相同

(2)播放动画,animator.Play(" "),接收一个参数,要播放的动画的名称。

(3)触发动画:animator.SetTrigger("动画名称");

(4)获取参数:animator.GetFloat/GetInt/GetBool("要获取的参数名称").

(5)实现帧事件,在模型的Animation中填写帧事件函数,为某一帧或某几帧的动画添加事件(如为一个跑步动画在脚落地时播放脚步声等),我们需要在人物模型的脚本中控制帧事件函数,直接在脚本中public就可以直接访问到。

二十.反向动力学(IK)

常用方法与属性

(1)基础方法:private void Onanimator(int layerdex),关于ik的都写在这个方法中,接收一个参数,表示动画图层的编号。

(2)设置权重:animator.SetLookAtWeight(1),接收一个int类型的参数,表示权重。

(3)设置指向的位置:animator.SetLookAtPosition(target.position)修改头部IK,设置其他部分的Ik需要animator.SetLookAtPositionWeight(AvatarGoal.RightHand,1)接收一个枚举,和一个权重,

设置旋转的话也相同,使用animator.SetLookAtRotationWeight(AvatarGoal.RightHand,1)

二十一.导航

需要引入UnityEngine.AI,代理组件类:NavMeshAgent

(1)获取导航代理组件的方法与通用的获取组件的方法相同

(2)设置一个位置为导航的目标位置:agent.SetDestination(point),接收一个Vector3表示导航到的位置。

二十二.灯光类

常用方法与属性

(1)获取灯光组件的方法与通用的获取组件的方法相同

(2)灯光的开启与关闭,与组件的激活相同,直接设置组件的激活状态

(3)灯光的强度与范围:light.intensity,light.range,都是数值,修改直接改变其数值

二十三.钢体

钢铁类为Rigidbody

常用方法与属性

(1)获取钢体组件的方法与通用的获取组件的方法相同

(2)修改钢体的速度:rb.linearVelocity(x,y,z),参数接收一个向量,一般情况下操作钢体,无论是加力还是改变速度都必须要写在FixedUpdate中,因为写在updae中两帧直接的频率不固定,会导致修改的速度不稳定,导致物体出现异常抖动,抽搐等问题。

(3)给钢体添加力:rb.AddForce(Vector3.up*200)参数给一个力的方向*力的大小

二十四.UI界面

使用新的UI文本必须引入TMPor,文本为string类型

1.下拉组件的控制

下拉组件类为Dropdown

(1)获取下拉组件的方法与通用的获取组件方法相同。

(2)获取组件选项:List<Dropdown.OptionData>option=dropdown.options

(3)修改选项:options.Add(new Dropdown.optinoData("选项的命名"))

dropdown.optinos=options.

2.新版文本组件的控制

(1)获取下拉组件的方法与通用的获取组件方法相同。

(2)动态的修改文本内容有两种方式:通过text.text=" "和通过scoreText.SetText("Score:{0} ",score);,其中SetText可以接收两个参数,应该表示字符串和占位符,一个表示占位的变量。

2.常用UI布局组件

(1)mask遮罩组件:父物体遮罩子物体

(2)文本适配:动态的根据文本的大小修改文本显示框,Content Size Fitter

(3)图像布局组件:解决一个面板中多个图像的布局问题:Vertiacl Layout Group(垂直方向上的布局),Horizontal Layout Group(水平方向上的布局),Grid Layout Group(网格布局)

三种移动控制的比较

根据以上内容,我们知道了三种移动的控制方式,我们简单介绍它们的区别:

1.利用transform组件控制移动

transform.position += ...transform.Translate(...),没有什么物理的属性,实际上是通过每一帧的瞬移来1实现位置1的移动的。对于物理相关的检测需要我们后续自行添加。

常用于摄像机跟随、UI动画、或者不需要碰撞的子弹。

2.利用charactor Control组件

专门用于人物角色,它不是严格的物理刚体,也不是纯粹的瞬移。它是一个胶囊体碰撞器加上专门的移动逻辑,处于物理系统和瞬移之间。

常用于:第一人称射击游戏、第三人称动作游戏的玩家角色

3.利用刚体组件控制移动

物理交互最真实

常用于需要真实物理互动的物体。

相关推荐
cici158742 小时前
C# LAS 点云读取与处理工具
stm32·单片机·c#
OnlyEasyCode2 小时前
C# 发送QQ邮箱验证码or其他
开发语言·c#
晓13132 小时前
【Cocos Creator 3.x】篇——第一章 简介
前端·javascript·游戏引擎
winlife_2 小时前
全程用 AI 做一款商业级手游 · EP9 收尾与复盘:做到了哪,没做到哪,边界在哪
java·开发语言·人工智能·unity·ai编程·游戏开发·mcp
晓13133 小时前
【Cocos Creator 2.x】篇——第五章 游戏常用关键技术
前端·javascript·vue.js·游戏引擎
caimouse3 小时前
2D 与 3D 跨平台游戏引擎
游戏引擎
123的故事4 小时前
工具分享(2)-NSmartProxy内网穿透工具。
c#·.net·nsmartproxy
EQ-雪梨蛋花汤4 小时前
【Unity笔记】Unity URP 透明玻璃出现白色光斑?Directional Light 镜面高光问题分析与解决
3d·unity·数字孪生