Unity脚本(二)

article/2025/10/4 21:03:20

视频教程:https://www.bilibili.com/video/BV12s411g7gU?p=122   

目录

Transform

GameObject

Object

GetComponentInParent

LookAt

GetSiblingIndex、SetSiblingIndex

Instantiate 


Transform

对象的位置、旋转和缩放

场景中的每个对象都有一个Transform,用于存储和操作对象的位置、旋转和缩放。 每个Transform都可以有一个父级,能够分层应用位置、旋转和缩放

Transform.position:相对于世界坐标系原点的位置 

Transform.localPosition:相对于父物体轴心点的位置,若没有父级,则其与Transform.position相同

Transform.localScale:相对于父物体的缩放比例

ps:Inspector面板中的Position、Rotation、 Scale均是相对于父物体的

将Inspector面板设置为debug

  

Transform.lossyScale: 物体的全局缩放比例(只读)

ps:lossyScale=自身缩放比例*父物体缩放比例;假设父物体localScale为2,子物体localScale为3,则其lossyScale为6

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TransformDemo : MonoBehaviour
{public Transform root;void OnGUI(){if (GUILayout.Button("foreach--transform")){foreach (Transform child in this.transform){print(child.name);}}if (GUILayout.Button("root")){print(this.transform.parent);}if (GUILayout.Button("Space.World--setParent")){//当前物体的位置视为世界坐标this.transform.SetParent(root);}if (GUILayout.Button("Self.World--setParent")){//当前物体的位置视为localScalethis.transform.SetParent(root, false);}if (GUILayout.Button("DetachChildren")){this.transform.DetachChildren();}if (GUILayout.Button("Find")){print(this.transform.Find("Cube"));}if (GUILayout.Button("childCount")){int count = this.transform.childCount;for (int i = 0; i < count; i++){print(transform.GetChild(i));}}if (GUILayout.Button("Self.World--Z+1")){this.transform.Translate(0, 0, 1);}if (GUILayout.Button("Space.World--Z+1")){this.transform.Translate(0, 0, 1, Space.World);}if (GUILayout.Button("Self.World--Rotate_X+1")){this.transform.Rotate(10, 0, 0);}if (GUILayout.Button("Space.World--Rotate_X+1")){this.transform.Rotate(10, 0, 0, Space.World);}if (GUILayout.RepeatButton("RotateAround")){this.transform.RotateAround(Vector3.zero, Vector3.up, 1);}}
}

foreach--transform按钮:获取直接(第一代)子物体的物体名

有如下图的父子关系,child 1、child 2和child 3是父物体parent的直接(第一代)子物体,而_child 1、_child 2是其间接(第二代)子物体;将TransformDemo挂载至父物体parent上 

运行后点击foreach--transform按钮,可以观察到控制台输出第一代子物体的物体名

Transform.parent:获取根物体的Transform组件

root按钮:输出根物体的物体名(类似树中的根节点);如同样有上文中的父子关系图,分别将脚本挂载至child 1和_child 1并点击root按钮,可以观察到控制台输出的均是parent

Transform.SetParent:设置当前Transform的父级

Space.World--setParent按钮与Self.World--setParent按钮:两者的功能都是将当前游戏对象设置为另一游戏对象的子物体(设置父级),区别在于设置父子关系后的位置

在Space.World--setParent按钮中 

this.transform.SetParent(root)

 等价于

this.transform.SetParent(root,true)

上述代码的含义为将当前物体设置为root的子物体后,将当前物体相对于世界坐标系原点的位置转换为相对于root的localPosition,即当前物体在世界坐标系中的位置不发生改变

如下图root(15,0,0),Cube(15,0,5),执行后Cube中世界坐标的位置仍为(15,0,5),而相对于root的localPosition为(0,0,5) 

而在Self.World--setParent按钮中

this.transform.SetParent(root, false)

该代码的含义为将当前物体设置为root的子物体后,将当前物体相对于世界坐标系原点的位置作为相对于root的localPosition,即当前物体在世界坐标系中的位置等于父物体在世界坐标中的位置+当前物体此前在世界坐标中的位置(两者的向量和)

如下图root(15,0,0),Cube(15,0,5),执行后Cube中世界坐标的位置为(30,0,5),而相对于root的localPosition为(15,0,5)

Transform.DetachChildren:解除父级的所有直接(第一代)子项(子物体)

DetachChildren按钮: 若有如foreach--transform中父子结构,同样为parent挂载该脚本,运行后点击DetachChildren按钮,则parent的所有直接子项解除与父级parent的关系;即分离出了child 1、child 2、child 3,而_child 1和_child 2仍分别作为child 1和child 2的子项

Transform.Find:寻找并返回对应名称的子项

 Find按钮:在所有直接子项中寻找并返回名为Cube的子项

ps:可写成如下路径的格式代表父子层级 

transform. Find("LeftShoulder/Arm/Hand/Finger");

Transform.childCount:返回父级的直接(第一代)子项数 

Transform.GetChild:按索引返回对应的直接(第一代)子项

childCount按钮:与foreach--transform按钮功能类似但可以按索引返回对应的第一代子项;同样以foreach--transform中父子结构为例,为parent挂载该脚本,运行并点击childCount按钮,可以观察到控制台输出父级parent的第一代子项

Transform.Translate:按世界坐标或者本地坐标移动物体

Self.World--Z+1按钮与Space.World--Z+1:两者的功能都是使物体的Z轴+1,但参考系不同,Self.World--Z+1参考的是物体的自身坐标而Space.World--Z+1参考的是世界坐标

在Self.World--Z+1中

this.transform.Translate(0, 0, 1)

等同于

this.transform.Translate(0, 0, 1, Space.Self)

 关于自身坐标与世界坐的区别,如下图所示

Transform.Rotate:按世界坐标或者本地坐标旋转物体,通常以欧拉角而不是四元数提供旋转

Self.World--Rotate_X+1按钮与Space.World--Rotate_X+1按钮,两者的功能均是将物体绕X轴选择1度,而区别同样在于参考系不同

Transform.RotateAround:围绕穿过世界坐标中的一点的旋转轴旋转物体

RotateAround按钮:使物体围绕穿过坐标原点方向向量为(0,1,0)的旋转轴进行旋转

使用递归在层级未知的情况下查找子项

编写脚本TransformHelper

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TransformHelper : MonoBehaviour
{public string target;void OnGUI(){if (GUILayout.Button("Recursion_Find")){print(Recursion_Find(this.transform, target));}}Transform Recursion_Find(Transform root, string name){Transform target = root.transform.Find(name);if (target) return target;if (root.transform.childCount == 0) return null;foreach (Transform child in root.transform){if (Recursion_Find(child, name) != null){return Recursion_Find(child, name);}}return null;}
}

 更改foreach--transform中展示父子结构,在child 3添加一个名为target的Cube作为查找的目标

在parent上挂载脚本并进行参数设置后,运行场景点击Game面板中左上角的Recursion_Find按钮,可以观察控制台输出了子项target

GameObject

GameObject.activeInHierarchy:物体实际激活状态 

GameObject.activeSelf:物体自身激活状态(Inspector面板中的状态,且是只读的)

如下图,父级child 1被禁用导致子项_child 1被禁用,但实际上子项_child 1在Inspector面板中仍是启用状态

  

 

在上述情况下,子项_child 1的activeInHierarchy为fales,而activeSelf为true

GameObject.SetActive:启用/禁用物体

GameObject.AddComponent<T>():将组件T添加到游戏对象

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameObjectDemo : MonoBehaviour
{void OnGUI(){if (GUILayout.Button("添加光源")){GameObject lightGO = new GameObject();Light light = lightGO.AddComponent<Light>();light.color=Color.red;light.type=LightType.Point;}}
}

ps:在脚本中挂载组件时无需使用new关键字创建对象,因为执行AddComponent方法以包含了使用new进行构造的过程

为某一游戏对象挂载该脚本,运行后点击Game面板中左上角的“添加光源”按钮,即可发现创建中新增了一个挂载light组件且名为New Game Object的游戏对象 

 

GameObject.Find("游戏对象名称"):在场景中根据名字查找物体(慎用,该方法将会尝试遍历场景中的每一个游戏对象)

GameObject.FindGameObjectWithTag("标签名称"):返回第一使用该标签的物体(单个)

GameObject.FindGameObjectsWithTag("标签名称"):返回所有使用该标签的物体(数组)

Object

Object.Destroy(Object obj, float delay= 0.0F):移除GameObject、组件或资源

obj要销毁的对象
delay(可选)销毁对象前的延迟时间

Object.DestroyImmediate:立即销毁游戏对象(建议改用 Destroy)

Object.DontDestroyOnLoad:在加载新的Scene时,不销毁Object

Object.FindObjectOfType<T>():返回第一个类型为T的激活对象(单个)

Object.FindObjectsOfType<T>():返回所有类型为T的对象(数组)

查找血量最低的敌人 

编写脚本Enemy

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : MonoBehaviour
{public float hp;
}

在场景中创建三个游戏物体分别命名为Enemy 1、 Enemy 2、Enemy 3,为其挂载脚本Enemy并设置不同的Hp

 

 

 

编写脚本Find_Enemies并将其挂载至某一游戏物体后,运行场景并点击“查找血量最低的敌人”按钮

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Find_Enemies : MonoBehaviour
{void OnGUI(){if (GUILayout.Button("查找血量最低的敌人")){var enemy_list = Object.FindObjectsOfType<Enemy>();Enemy min = enemy_list[0];foreach (Enemy i in enemy_list){if (i.hp < min.hp){min = i;}}print(min);}}
}

查找距离最近的敌人  

分别将Enemy 1、Enemy 2、Enemy 3设置至不同位置

  

 在脚本Find_Enemies中添加代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Find_Enemies : MonoBehaviour
{public Transform target;void OnGUI(){//查找血量最低的敌人if (GUILayout.Button("查找距离最近的敌人")){var enemy_list = Object.FindObjectsOfType<Enemy>();Enemy closer = enemy_list[0];float minDist = Vector3.Distance(closer.transform.position, target.position);foreach (Enemy i in enemy_list){float newDist = Vector3.Distance(i.transform.position, target.position);if (newDist < minDist){closer = i;minDist = newDist;}}print(closer);}}
}

创建一个名为target空物体作为距离的参照物,即哪一个Enemy对象与target距离最近;运行场景并点击“查找距离最近的敌人”按钮

  

Vector3.magnitude:返回该向量的模长(只读)

ps:new Vector3(x,y,z).magnitude=(x^2+y^2+z^2)^(1/2)

Vector3.sqrMagnitude:返回该向量的模长的平方(只读)

ps:new Vector3(x,y,z).sqrMagnitude=x^2+y^2+z^2

Vector3.Distance(Vector3 a, Vector3 b):返回a与 b间的距离,与(a-b).magnitude相同

GetComponentInParent

Component.GetComponentInParent<T>():从当前游戏对象开始查找T组件,若有直接返回,若无则向上遍历父级,直到找到为止

LookAt

Transform.LookAt:使当前物体向前矢量指向目标位置

GetSiblingIndex、SetSiblingIndex

Transform.GetSiblingIndex:获取同级(共享一个直接父级并且处于同一级别)索引

  

Transform.SetSiblingIndex:设置/更改同级索引

Instantiate 

Object.Instantiate:克隆对象并返回


http://chatgpt.dhexx.cn/article/pQQ4A6NB.shtml

相关文章

Unity 剧情类游戏基础脚本

本文主要用于给新人提供实现剧情类游戏的基本思路。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; 然后是一个很重要的 [System.Serializable] 它的作用是使得在检查器窗口来看到我i们自己创建的类从而实现在检…

Unity脚本(三)

视频教程&#xff1a;https://www.bilibili.com/video/BV12s411g7gU?p128 目录 Time Prefab Animation Time Time.time&#xff1a;自应用程序启动以来&#xff0c;每帧的开始时间&#xff08;只读&#xff09; Time.deltaTime&#xff1a;每帧间隔&#xff0c;或说完…

NS版暗黑破坏神3金手指开发教程(1)

最近重温了NS版的暗黑三&#xff0c;因为空闲时间实在有限&#xff0c;面对这样一款刷刷刷的经典作品&#xff0c;为了护肝以及更爽快的游玩&#xff0c;同时为了弥补自己丢失已久的汇编技能&#xff0c;加上NS版暗黑三最初版本里有带完整调试信息的elf文件&#xff0c;于是有了…

NS版暗黑破坏神3金手指开发教程(3)

上一节&#xff0c;我们初步介绍了修改人物力量的方法&#xff0c;也大致说了一下hexworkshop和IDA的简单操作&#xff0c;这一节&#xff0c;我们将进阶到复杂度高一些的人物全属性修改&#xff0c;搜索方法基本跟上一节的力量公式一样&#xff0c;需要一定的耐心和细心&#…

Unity入门3——脚本基础

一、生命周期函数 ​ 所有继承 MonoBehavior 的脚本&#xff0c;最终都会挂载到 GameObject 游戏对象上 ​ 生命周期函数就是该脚本对象依附的 GameObject 对象从出生到消亡整个生命周期中 ​ 会通过反射自动调用的一些特殊函数 ​ Unity 帮助我们记录了一个 GameObject 对象依…

4.实现csdn暗黑模式-油猴脚本实战1

4.实现csdn暗黑模式-油猴脚本实战1 Start 前面的文章&#xff0c;对油猴脚本做了基础的介绍。今天来我们来实战一下&#xff0c;编写一个有实际作用的油猴脚本。 如果我希望我的csdn是暗黑模式&#xff0c;怎么办&#xff1f; 看我表演&#xff1f; 注意&#xff01;本文仅用…

6. unity之脚本

1. 说明 当整个游戏运行起来之后,我们无法再借助鼠标来控制物体,此时可以使用脚本来更改物体的各种姿态,驱动游戏的整体运动逻辑。 2. 脚本添加 首先在Assets目录中,新创建一个Scripts文件夹,在该文件内右键鼠标选择创建脚本选项,即可创建一个脚本文件,可命名为Sampl…

Unity入门03——Unity脚本

1.脚本基本规则 1.设置编程用工具 2.基本规则 1.创建规则 不在VS中创建脚本了可以放在Assets文件夹下的任何位置&#xff08;建议同一文件夹管理)类名和文件名必须一致,不然不能挂载(因为反射机制创建对象&#xff0c;会通过文件名去找Type)建议不要使用中文名命名没有特殊…

你可能还不知道的暗黑3常用小技巧

以下是上次活动热心坛友发来的游戏小技巧&#xff0c;经过我的搜集和加入一些自己和朋友们分享的经验整合编辑而成。再次感谢大家的热心参与。都非常实用哟&#xff01;&#xff01;&#xff01; 操作篇 1&#xff0c;如果你不希望朋友进入你的游戏时&#xff0c;按ESC&#xf…

jq linux获取数组长度,数组长度用size还是length

数组长度用length属性。length是js的原生方法&#xff0c;可获取元素的个数和对象的长度&#xff1b;而size()函数是jQuery方法&#xff0c;只能作用于对象上&#xff0c;用于返回当前jQuery对象封装的元素个数。获取一个数组的长度或者参数的长度&#xff0c;只能用lenth。 本…

delphi 获取数组长度_数组的介绍及使用

JavaScript 中的数组常用于在单个变量中存储多个值。数组就是一组数据的集合&#xff0c;在内存中表现为一段连续的内存地址(保存在堆内存)。创建数组的目的就是为了保存更多的数据。 数组概念和语法 概念&#xff1a;数组是一个特殊变量&#xff0c;一次可以容纳多个值。 特点…

js 填充数组长度

js 填充的方法有以下三种 const array new Array(100).fill()Array.from(new Array(100).keys())let arr Array.from({length:100}, (_v,k) > k);如果下面有这么一个场景&#xff0c;你在接口中获取了一个数组对象&#xff0c;如下&#xff1a; [{id:1},{id:2},{id:3},{…

c语言中文网 数组的长度,数组的长度如何获取?

获取数组长度的方法&#xff1a; 1、在java与JavaScript中可以使用“数组名.length”方法获取数组长度 javaScriptvar arrnew Array(); arr[0] "a"; arr[1] "b"; var lenarr.length; java 2、c语言中可以使用关键字 sizeof获取数组长度 用 sizeof 可以获…

c语言 json数组长度,js 获取json数组里面数组的长度

作为一个前端页面开发者第一次处理json数据,遇到了‘js 获取json数组里面数组的长度’?竟然不知道 json没有.length属性(真是要嘲讽下自己),少壮不努力老大徒伤悲啊!以前都是去寻求男朋友帮助,但是最近尝试自己去解决遇到的问题。 我遇到的问题是这样的:***.jsp结尾的页面…

vue 获取数组长度_Vue数据响应式

响应式是一种设计模式。 页面响应式布局就是根据页面缩放大小调整布局,数据响应式就是代码根据数据变化作出反应。 深入响应式原理 — Vue.js​cn.vuejs.org 简单来说,当我们把一个 JavaScript 对象传入 Vue 实例作为data选项时,Vue将遍历此对象所有的 property,使用Object…

Javascript 获取数组长度, 对象成员个数, 字符串数

1.应用场景 主要用于获取数组长度, 对象成员个数, 字符串数. 2.学习/操作 Q1.Javascript怎么得到数组长度(也就是数组的元素个数)? Q2.Javascript怎么获取对象的成员个数? Q1 你肯定想到了array.length!? 那么我们来测试一下下面这个例子. <script type"text/jav…

html获取数组最小值,javascript如何获取数组长度?

JavaScript中可以通过length方法来获取字符串的长度。数组的 length 属性总是比数组中定义的最后一个元素的下标大 1。 定义和用法 length 属性可设置或返回数组中元素的数目。 语法arrayObject.length 说明 数组的 length 属性总是比数组中定义的最后一个元素的下标大 1。对于…

JS:数组Array的使用方法及获取数组的长度length

对象分成三种&#xff1a; 内建对象宿主对象自定义对象 数组Array也是一个对象&#xff0c;它和普通的对象功能类似&#xff0c;也是用来存储一些值的。 不同的是普通对象是使用字符串作为属性名的&#xff0c;而数组是使用数字来作为索引操作元素。 数组中的索引是从0开始的…

JavaScript学习1.1

1.注意: 1. JS是区分大小写的&#xff0c;如&#xff1a;classname和ClassName是不一样的。同时注意方法、属性、变量等的大小写吆。 2. JS中的字符、符号等一定要在英文状态下输入吆。 3.var myarrnew Array(); //定义数组 注意&#xff1a; 1.创建的新数组是空数组&#xf…

21 JS数组的基本操作——数组长度

文章目录 1、数组长度1、1 获取数组长度1、2 修改数组长度 2、创建时指定数组长度3、练习&#xff1a;输出数组的长度 1、数组长度 1、1 获取数组长度 数组名.length 1、2 修改数组长度 在利用length属性指定数组长度时&#xff0c;有以下三种情况&#xff1a; &#xff…