文章目录
- 一、前言
- 二、要求和原理
- (一)建立关联机制
- (二)底层工作原理
- 三、使用方法
- (一)创建
- (二)使用
一、前言
在Unity开发中,Transform是一个核心组件,每个物体必有且不可或缺的组件,用于控制游戏对象的位置、旋转和缩放。由于Transform是Unity引擎的核心类,不能直接修改它的源代码,但可以通过扩展方法(Extension Methods)的方式为其添加自定义功能。
拓展:注意这里扩展类只是以Transform为例展开的文章内容,不止Transform可以扩展,只要是Unity中的自带核心组件其实都可以使用这种方式进行扩展。
二、要求和原理
先一句话讲要求,看完想直接上手的话,直接跳到三、使用方法。
扩展类必须是
static静态类,且方法也必须是静态方法,而且还必须带有this关键字的目标实例参数,这样才能链接到你要扩展的Unity类
扩展类虽然没有强制的要求,但是要遵循以下几点要求和注意事项:
- 文件名不得与类名相同,虽然文件名没有特殊命名要求,但是建议采用
[类名]Extensions.cs的命名约定(如TransformExtensions.cs)以提高可读性 - 一个文件可以包含多个扩展类。比如一个文件即包含了
Transform的扩展方法,也包含了GameObject的扩展方法。但通常一个文件只包含一个主要扩展类(遵循单一职责原则) - 扩展方法调用会有微小的间接调用开销,在性能关键代码中慎用
- 如果Transform已有同名方法,扩展方法不会被调用,扩展方法永远低于实例方法的优先级
(一)建立关联机制
扩展方法通过以下三个要素与Transform类建立关联:
static类:
publicstaticclassTransformExtensions{}static方法:
publicstaticvoidReset(thisTransformtransform){}// 关键字↑ ↑目标类型扩展 ↑实例参数this关键字:
- 第一个参数前的
this是关键 - 指定要为哪种类型添加扩展
- 参数名(
transform)将成为方法内的实例引用
- 第一个参数前的
(二)底层工作原理
编译时转换:
// 你写的代码transform.Reset();// 编译器实际处理为TransformExtensions.Reset(transform);方法解析优先级:
- 实例方法 > 扩展方法
- 同一命名空间下的扩展方法优先
三、使用方法
(一)创建
下面的示例是如何创建一个扩展类的示例代码:
usingUnityEngine;publicstaticclassTransformExtensions{// 1. 重置 Transform(位置、旋转、缩放)publicstaticvoidResetTransform(thisTransformtransform){transform.position=Vector3.zero;transform.rotation=Quaternion.identity;transform.localScale=Vector3.one;}// 2. 设置全局缩放(Transform 默认只有 localScale)publicstaticvoidSetGlobalScale(thisTransformtransform,Vector3globalScale){Transformparent=transform.parent;transform.SetParent(null);// 暂时脱离父级transform.localScale=globalScale;transform.SetParent(parent);// 恢复父级}// 3. 面向某个方向(平滑旋转)publicstaticvoidSmoothLookAt(thisTransformtransform,Vector3target,floatspeed=5f){Vector3direction=(target-transform.position).normalized;QuaterniontargetRotation=Quaternion.LookRotation(direction);transform.rotation=Quaternion.Slerp(transform.rotation,targetRotation,speed*Time.deltaTime);}// 4. 获取所有子对象(递归)publicstaticTransform[]GetAllChildren(thisTransformtransform){returntransform.GetComponentsInChildren<Transform>(true).Where(child=>child!=transform).ToArray();}}(二)使用
usingUnityEngine;publicclassExampleUsage:MonoBehaviour{voidStart(){// 重置 Transformtransform.ResetTransform();// 设置全局缩放(不受父级影响)transform.SetGlobalScale(Vector3.one*2f);// 平滑面向某个目标transform.SmoothLookAt(Vector3.forward*10f);// 获取所有子对象Transform[]children=transform.GetAllChildren();foreach(varchildinchildren){Debug.Log(child.name);}}}这篇内容就到这里,下期再见。
有什么问题可以评论区留言或私信。