MonoBehavior相关内容
using UnityEngine;
public class Lesson3 : MonoBehaviour
{
void Start()
{
//2.获取依附的GameObject的位置信息
print(this.transform.position);
print(this.transform.eulerAngles);
print(this.transform.lossyScale);
}
}
对应这三个参数
从当前物体通过脚本获取其他物体

通过在当前物体中声明一个类,然后将挂载该类的物体拖拽到这个窗口中,便可以获取该类物体相关信息(例如Transform/挂载组件之类)
获取脚本
获取物体单个脚本
第一种不常用,一般用泛型获取
// 1. 获取脚本的方法
// 如果获取失败,就是没有对应的脚本,会默认返回空
Lesson3_Test t = this.GetComponent("Lesson3_Test") as Lesson3_Test;
print(t);
// 根据 Type 获取
t = this.GetComponent(typeof(Lesson3_Test)) as Lesson3_Test;
print(t);
// 根据泛型获取,建议使用泛型获取,因为不用二次转换
t = this.GetComponent<Lesson3_Test>();
if(t!=null){print(t);}
只要你能得到场景中的对象或者对象依附的脚本
那你就可以获取到它的所有信息
获取自己的多个脚本
一般不会同个脚本放在一个物体上
cs
// 2. 得到自己挂载的多个脚本
//将当前物体中的Lesson3脚本返回到list存储起来
Lesson3[] array = this.GetComponents<Lesson3>();
print(array.Length);
List<Lesson3> list = new List<Lesson3>();
this.GetComponents<Lesson3>(list);
获取自己的子物体的单个脚本/多个脚本
这里也是找脚本Lesson3_Test
cs
// 3. 得到子对象挂载的脚本(它默认也会找自己身上是否挂载该脚本)
// 函数是有一个参数的,默认不传是 false,意思就是:如果子对象失活,是不会去找这个对象上是否有某个脚本的
// 如果传 true,及时失活,也会找
t = this.GetComponentInChildren<Lesson3_Test>(true);
print(t);
// 得到子对象挂载脚本(单个)
Lesson3_Test[] lts = this.GetComponentsInChildren<Lesson3_Test>(true);
print(lts.Length);
// 得到子对象挂载脚本(多个)
List<Lesson3_Test> list2 = new List<Lesson3_Test>();
this.GetComponentsInChildren<Lesson3_Test>(true, list2);
print(list2.Count);
获取自己的父物体的单个脚本/多个脚本
这里不用像子对象一样------需要用true进行判断,因为父对象失活,自身也会失效
cs
// 4. 得到父对象挂载的脚本(它默认也会找自己身上是否挂载该脚本)
t = this.GetComponentInParent<Lesson3_Test>();
print(t);
lts = this.GetComponentsInParent<Lesson3_Test>();
print(lts.Length);
// 它也有list的,省略不写了,和上面是一样的套路
GameObject相关内容
**核心概念:**GameObject是Unity场景中的最小单位,所有脚本都依附在GameObject上
基本属性
cs
// 一些属性:
// 脚本的激活
this.enabled = true;
// gameobj对象的激活
bool isActive = this.gameObject.activeSelf;
// 获取是否静态
bool isStatic = this.gameObject.isStatic;
// 获取标签
string tag = this.gameObject.tag;
// 获取层级
int layer = this.gameObject.layer;
注意:这个Gameobject类也可以用transform
- 物体位置信息有两种获取方式:
- 通过MonoBehaviour:this.transform
- 通过GameObject:this.gameObject.transform
- 等效性: 两种方式获取的是同一个Transform组件
- 位置信息: 可通过.position获取位置坐标,打印时会自动四舍五入显示
静态方法
cs
// 静态方法:
// 创建几何体
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
// 查找对象
// 只能找激活对象,存在多个同名随机找出一个
GameObject obj1=GameObject.Find("otherTest"); // 对象名查找
GameObject obj2=GameObject.FindGameObjectWithTag("Player"); // 标签名查找
if(obj1!=null){}//防止对象没有而报错
// 利用标签名找多个对象(找多个对象只能通过Tag来)
GameObject[] objs = GameObject.FindGameObjectsWithTag("Player");
// 实例化对象(空对象)
GameObject instObj = GameObject.Instantiate(testOBJ);
// 删除对象
GameObject.Destroy(instObj); // 删除实例化对象
GameObject.Destroy(instObj,5); // 延迟删除
GameObject.Destroy(this); // 删除脚本,这里是删除自身这个脚本
GameObject.DontDestroyOnLoad(this.gameObject);//场景切换时,物体会默认移除,所以会使用该方法保留不想切换场景摧毁的物体
Destory相关知识点
- 异步移除:Destroy不会立即移除对象,只是添加移除标识
- 执行时机:一般情况下先标记,然后通常在下一帧才会真正从内存移除
- 设计目的:避免卡顿,统一处理内存释放
- 内存管理:对象移除包含从场景和内存中双重移除
- 该方法是异步的
**方法对比:**DestroyImmediate会立即移除对象并释放内存
- 使用建议:除非特殊需求,否则建议使用普通Destroy
- 性能考量:立即删除可能引起卡顿,特别是在批量操作时
- 应用场景:编辑器扩展等需要即时反馈的特殊情况
Unity中的Object与C#中的Object区别
- 命名空间区别:
- Unity中的Object类位于UnityEngine命名空间
- C#中的Object(万物之父)位于System命名空间
- 继承关系:
- Unity的Object是继承自C#万物之父的自定义类
- 虽然继承但功能不同,Unity的Object特指游戏对象相关功能
成员方法
cs
// 成员方法:
// 创建空对象
GameObject gameObject = new GameObject();
GameObject gameObject2 = new GameObject("Test"); // 初始化对象名
GameObject gameObject3 = new GameObject("TestAddComponent",typeof(otherTest)); // 初始化对象名,并且添加脚本(变长
// 为对象添加脚本------ot是这个脚本实例化的名字
otherTest ot = this.AddComponent<otherTest>();
//得到脚本------Monobeahavior静态方法含有得到脚本相关方法
// 标签比较
if( this.CompareTag("Player"); )
if(this.gameObject.tag == "Player")
// gameobj的激活失活
bool isActive = this.gameObject.activeSelf; // 获得激活还是失活状态
this.gameObject.SetActive(true); // 设置激活还是失活
比较次要的成员方法
了解即可------可能协作时有人会用这段代码,但是这个代码效果非常低下,自己最好不用
cs
// 通知自己 执行什么行为
// 命令自己 去执行这个TestFun这个函数 会在自己身上挂在的所有脚本去找这个名字的函数
// 它会去找到 自己身上所有的脚本 有这个名字的函数去执行
this.gameObject.SendMessage("TestFun");
this.gameObject.SendMessage("TestFun2", 199);
// 广播行为 让自己和自己的子对象执行
// this.gameObject.BroadcastMessage("函数名");
// 向父对象和自己发送消息 并执行
// this.gameObject.SendMessageUpwards("函数名");
Time相关
核心概念: 通过Time类的timeScale属性控制游戏时间流速
cs
// 时间缩放
Time.timeScale = 0; // 0倍
Time.timeScale = 2; // 2倍
帧时间间隔
- 概念: 帧间隔时间指最近一帧完成所用的时间(单位:秒)
- 本质: Unity游戏循环中一次完整循环的耗时
- 60帧游戏的标准帧间隔时间约为16.67ms(1/60秒)
- 120帧游戏约为8.33ms(1/120秒)
后续会学习如何将帧时间间隔控制到16ms------因为太低对Cpu压力也很大
cs
// 帧间隔时间
float deltaTime = Time.deltaTime; // 受scale影响
float unscaleDelatTime = Time.unscaledDeltaTime; // 不受scale影响
当timeScale=0时, Time.deltaTime=0而Time.unscaledDeltaTime依旧有值
帧间隔时间主要用于计算位移------核心公式: 位移 = 时间 × 速度
- 选择原则:
- 常规移动(游戏暂停时不移动的话)使用deltaTime
- 需要无视暂停的效果使用unscaledDeltaTime
游戏开始到现在的时间
cs
// 游戏开始到现在的时间
float time = Time.time; // 受scale影响
float unscaledTime = Time.unscaledTime; //不受scale影响
应用场景
- 单机计时:主要用于单机游戏计时
- 网络游戏限制:网络游戏应使用服务器时间而非本地时间
物理帧间隔
默认值:0.02秒(对应50FPS)------具体配置方法可在生命函数FixedUpdate() 中翻阅
cs
private void FixedUpdate()
{
// 物理帧间隔时间
float fixedDeltaTime = Time.fixedDeltaTime; // 受scale影响
float fixedUnscaledDelateTime = Time.fixedUnscaledDeltaTime; // 受scale影响
}
帧数
本质:帧数表示游戏循环执行的次数,通过Time.frameCount获取
cs
// 游戏开始到现在跑了多少帧
float frameCount = Time.frameCount;
Transform相关
Unity 中的坐标系与 UE 不同,垂直屏幕向里面是 z轴,向上是y轴

Vector相关
cs
// Vector3 可以表示点 或者 向量
Vector3 v1 = new Vector3(1, 2); // 缺省为0
Vector3 v2 = new Vector3(1, 5, 3);
// Vector3的基本计算
Vector3 v1 = new Vector3(1, 1, 1);
Vector3 v2 = new Vector3(2, 2, 2);
// 对应用x+或者-x......
print(v1 + v2); // (3, 3, 3)
print(v1 - v2); // (-1, -1, -1)
print(v1 * 10); // (10, 10, 10)
print(v2 / 2); // (1, 1, 1)
// 零向量 单位向量
Vector3 zero = Vector3.zero; // 零向量
Vector3 right = Vector3.right; // 1 0 0
Vector3 left = Vector3.left; // -1 0 0
Vector3 forward = Vector3.forward; // 0 0 1 (面朝向)
Vector3 back = Vector3.back; // 0 0 -1
Vector3 up = Vector3.up; // 0 1 0
Vector3 down = Vector3.down; // 0 -1 0
// 两点距离
float distance = Vector3.Distance(v1, v2);
美术应在建模软件中将角色正面朝向其软件的'前方向'(通常是 Z+ 或 -Y),而不是强行对齐 Unity 的 Z 轴。
| 软件 | 默认朝上轴 | 默认朝前轴 |
|---|---|---|
| Maya | Y | Z |
| 3ds Max | Z | Y |
| Blender | Z | -Y |
| Cinema 4D | Y | -Z |
Position相关
cs
// 位置 position
Vector3 postiontion = this.transform.position; // 是世界坐标系下的坐标
Vector3 localPosition = this.transform.localPosition; // 本地坐标,相对于父对象的坐标,与面板显示一致
this.transform.position = new Vector3(1, 2, 3); // 不能单独改变position的 x,y,z
修改position
// 如果只想改一个值 x y和z要保持原有坐标一致
// 1. 直接赋值
this.transform.position = new Vector3(19, this.transform.position.y, this.transform.position.z);
// 2. 先取出来 再赋值
// 虽然不能直接改 transform的 xyz 但是 Vector3是可以直接改 xyz的
// 所以可以先取出来改Vector3 再重新赋值
Vector3 vPos = this.transform.localPosition;
vPos.x = 10;
this.transform.localPosition = vPos;
对象朝向
cs
// 本地向量
Vector3 myForward = this.transform.forward;
对象朝向是基于当前旋转状态计算的,如下是俯视图

位移相关
位移 = 速度矢量(速度*方向) × 时间
额外注意点:这种帧变化相关的操作都放在Update函数中
void Update()
{
// 位移
// 三个等价:朝着自己的面朝向前进
//1、自己计算------目标位置=当前位置+在指定方向的位移
//(这里默认速度为1,实际是速度*方向*帧时间间隔,即帧位移)
this.transform.position += this.transform.forward * Time.deltaTime;
//调用Unity自带 API
第一个参数:表示位移多少
第二个参数:参考坐标系,默认该参数是相对自身的坐标系
this.transform.Translate(Vector3.forward *1*Time.deltaTime); // 参考本地坐标系
//如下指的是在世界坐标系下,沿着物体面朝向移动
this.transform.Translate(this.transform.forward * Time.deltaTime, Space.World); // 参考世界坐标系
}
两种坐标系的都是物体面朝向,底层逻辑不同
this.transform.Translate(Vector3.forward * Time.deltaTime); // 等价于: this.transform.Translate(Vector3.forward * Time.deltaTime, Space.Self);
Vector3.forward是(0,0,1)------ 这是一个固定的世界向量。- 但因为用了
Space.Self(本地坐标系),Unity 会 把这个向量解释为"本地 Z 轴方向"。- 所以实际上:不管
Vector3.forward原本是什么,在本地坐标系下它就代表"物体自己的前方" 。
- ✅ 效果:物体沿自身朝向移动。
💡 这就像你说:"我向前走一步"------这个"前"是相对于你自己身体的方向。
this.transform.Translate(this.transform.forward * Time.deltaTime, Space.World);
transform.forward是一个 动态计算出来的世界向量,表示"该物体局部 Z 轴在世界空间中的方向"。- 例如:如果物体旋转了 90° 向右,
transform.forward可能是(1, 0, 0)(世界 X 轴方向)。- 然后你在
Space.World下使用这个向量,就是直接在世界空间中沿那个方向移动。
- ✅ 效果:同样沿自身朝向移动。
💡 这就像别人看着你说:"他现在面朝东,就让他向东走"------这是从外部观察者的视角描述。
如果想控制 相对于物体自身的运动,就用自身坐标系就够了。
角度和旋转
获取方法: 使用this.transform.eulerAngles获取对象相对于世界坐标系的欧拉角
**返回值类型:**返回Vector3类型,对应Inspector面板上显示的X/Y/Z角度值
**注意事项:**不能直接使用rotation属性,因为其返回的是四元数(Quaternion),与界面显示值不一致
cs
Vector3 eulerAngles = this.transform.eulerAngles; // 世界坐标系
Vector3 localEulerAngles = this.transform.localEulerAngles; // 本地坐标系(即受父物体影响的旋转)
// 注意:设置角度和设置位置一样,不能单独设置xyz,要一起设置
this.transform.localEulerAngles = new Vector3(10, 10, 10);
this.transform.eulerAngles = new Vector3(10, 10, 10);
print(this.transform.localEulerAngles);
旋转运动
自转
cs
// API计算
// 自转
// 每个轴(手动写入,这里的10感觉是速度) 具体每帧转多少度
// 第一个参数 相当于是旋转的角度 每一帧
// 第二个参数 默认不填 就是相对于自己坐标系 进行的旋转
this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime);
this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime, Space.World);
// 相对于某个轴 转多少度
// 参数一:是相对哪个轴进行转动
// 参数二:是转动的角度 是多少
// 参数三:默认不填 就是相对于自己的坐标系 进行旋转
// 如果填 可以填写相对于世界坐标系进行旋转
// this.transform.Rotate(Vector3.right, 10 * Time.deltaTime);
this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);
公转
cs
// 相对于某个轴 转多少度
// 参数一:是相对哪个轴进行转动
// 参数二:是转动的角度 是多少
// 参数三:默认不填 就是相对于自己的坐标系 进行旋转
// 如果填 可以填写相对于世界坐标系进行旋转
// this.transform.Rotate(Vector3.right, 10 * Time.deltaTime);
this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);

缩放相关
一般改localScale,相对于父对象的缩放,即相对缩放
cs
// 缩放
//不能单独修改xyz分量,必须同时修改
//特性: 相对世界坐标系大小只能获取不能修改,与位置和旋转不同(位置旋转可修改)
Vector3 lossyScale = this.transform.lossyScale; // 世界坐标系
Vector3 localScale = this.transform.localScale; // 本地坐标系
帧动态缩放
cs
void Update()
{
// 2. Unity没有提供关于缩放的API
// 之前的旋转、位移都提供了对应的API,但是缩放并没有
// 如果你想要让缩放发生变化,只能自己去写(自己算)
this.transform.localScale += Vector3.one * Time.deltaTime;//这里Vector3.one是(1,1,1)
看向
cs
//物体的正前方(z轴)将指向目标点
public Transform lookObject;
void Start()
{
//看向一个点
this.transform.LookAt(Vector3.zero);
//看向一个对象
this.transform.LookAt(lookObject);
}
父子相关API
添加父对象
cs
void Start()
{
// 父对象
print(this.transform.parent); // 获取
this.transform.parent = null; // 取消父对象
this.transform.parent = GameObject.Find("Cube").transform; // 设置父对象
this.transform.SetParent(null); // API的方法修改父对象
// true 会保留世界坐标下的状态 和 父对象 进行计算 得到本地坐标系的信息
// false 不会保留 会直接把世界坐标系下的 位置角度缩放 直接赋值到 本地坐标系下
this.transform.SetParent(GameObject.Find("Cube").transform, true); // 保留面板上的参数
this.transform.SetParent(GameObject.Find("Cube").transform, false); // 保持原本的世界坐标系状态,面板参数根据父对象修改
}
------------------------------------------------

子对象相关操作
cs
// 子对象
this.transform.DetachChildren(); // 取消所有子对象
this.transform.Find("Cube"); // 根据名字查找子对象,失活也可以查找,区别Gameobject
for(int i = 0; i < this.transform.childCount; i++)
{
print(this.transform.GetChild(i)); // 索引号获得子对象
}
son.IsChildOf(this.transform); // 是子对象返回true 否则false
son.GetSiblingIndex(); // 子对象编号
son.SetAsFirstSibling(); // 设置为第一个子对象
son.SetAsLastSibling(); // 设置为最后一个子对象
son.SetSiblingIndex(2); // 自定义编号------如果填的数值超出范围也不会报错
坐标转换
世界坐标转换成本地坐标系
点的坐标系转换
cs
// 世界坐标系的点 转化为 本地坐标系的点
// 受到target缩放大小影响
var pos = target.InverseTransformPoint(Vector.forward);
这就是坐标转换的具体细节
收到缩放影响:当cube放大2倍,转换后的坐标变为(-0.4,0,-0.4)
方向的坐标系转换
cs
// 世界坐标系的方向 转化为 本地坐标系的方向
// 受到target缩放大小影响
var dic = target.InverseTransformDirection(new Vector3(0, 0, 1));
Debug.Log(dic);
// 不受到target缩放大小影响
dic = target.InverseTransformVector(new Vector3(0, 0, 1));
本地坐标系转换成世界坐标系
这个比较常用
cs
// 本地坐标系的点 转化为 世界坐标系的点
print(this.transform.TransformPoint(Vector3.forward)); // 受自身缩放影响
// 本地坐标系的方向 转化为 世界坐标系的方向
print(this.transform.TransformDirection(Vector3.forward)); // 不受自身缩放影响
print(this.transform.TransformVector(Vector3.forward)); // 受自身缩放影响
本地坐标的点转换成世界坐标
本地坐标向量转换成世界坐标向量







