概述(Overview)
TransformExtensions 是一个专注于 Unity Transform 与 GameObject 变换操作 的静态扩展方法集合,位于 PFGameFramework.Library 命名空间。
主要功能包括:
- 子物体查找(按名称)
- 位置、旋转、缩放的快速重置与设置
- 同步 & 异步平滑移动(Lerp/Slerp)
- 异步旋转(自转 / 绕点旋转)
- PingPong 往返运动
- 动画曲线控制的路径移动
- 相对坐标计算
- 天空盒旋转控制
适用于相机跟随、物体展示动画、教学引导、交互物体移动、路径动画等场景。 大量使用 UniTask 实现异步平滑过渡,支持取消令牌(CancellationToken)。
方法一览(API Index)
| 方法名 | 扩展类型 | 异步 | 返回类型 | 主要功能 | 典型用途 |
|---|---|---|---|---|---|
| FindChildByName | Transform | 否 | Transform | 按名称查找直接子物体 | 快速定位子节点 |
| MoveTo | Transform | 否 | void | 立即瞬移到指定世界位置 | 快速设置位置 |
| ResetPosition / ResetRotation | Transform | 否 | void | 重置位置/旋转到零 | 初始化或归位 |
| GetAllChildren | Transform | 否 | Transform[] | 获取所有直接子物体 | 批量处理子级 |
| SetTransformInstant | GameObject | 否 | void | 立即设置位置 + 旋转 | 瞬时跳转 |
| MoveToAsync | GameObject | 是 | UniTask | 异步平滑移动 + 旋转(线性插值) | 相机/物体平滑过渡 |
| SetPosition / SetRotation | GameObject | 否 | void | 只设置位置 / 只设置旋转 | 单独控制变换 |
| RotateSky | static | 否 | void | 每帧旋转天空盒(需在 Update 中调用) | 天空盒动态效果 |
| RotateGo | Transform | 否 | void | 每帧绕自身轴旋转(适合 Update 调用) | 持续自转 |
| MoveTo (重载) | Transform | 是 | UniTask | 从起点到终点平滑移动(Lerp + Slerp) | 步骤引导、物体移动 |
| DoMove (多重载) | GameObject | 是 | UniTask | 异步平滑移动(支持起点/终点、曲线、取消令牌) | 核心移动动画 |
| PingPongMove | static | 是 | UniTask | 在两点间往返运动(PingPong) | 震动、来回演示 |
| DoRotate (多重载) | GameObject | 是 | UniTask | 异步自转(支持速度、时长、取消、恢复) | 旋转展示、转盘效果 |
| DoRotateAround | GameObject | 是 | UniTask | 异步绕点旋转 | 环绕观察、卫星效果 |
| GetPosition | static | 否 | Vector3 | 计算点在目标局部坐标系中的相对位置 | 坐标系转换、机器人基坐标 |
| SetTransform | static | 否 | void | 将一个物体的变换完全复制给另一个 | 相机/物体跟随、瞬间切换 |
| GetMoveTransform | static | 否 | MoveTransform | 从列表中按名称查找移动变换配置 | 配置驱动移动 |
方法详情
查找与重置
FindChildByName
/// <summary>
/// 在当前 Transform 的直接子物体中按名称查找
/// </summary>
public static Transform FindChildByName(this Transform parent, string name)
ResetPosition / ResetRotation
public static void ResetPosition(this Transform transform)
public static void ResetRotation(this Transform transform)
快捷重置:
transform.ResetPosition(); // position = Vector3.zero
transform.ResetRotation(); // rotation = Quaternion.identity
异步平滑移动(核心)
MoveToAsync(推荐)
/// <summary>
/// 异步平滑移动 GameObject 到目标位置 + 旋转(Lerp + Slerp)
/// 支持取消令牌
/// </summary>
public static async UniTask MoveToAsync(this GameObject target, Vector3 targetPosition,
Quaternion targetRotation, float duration, CancellationToken ct = default)
特点:每帧插值,平滑自然,支持中途取消。
DoMove(多重载,最常用)
// 基本版本(起点 → 终点)
public static async UniTask DoMove(this GameObject go, Transform startPos, Transform endPos, float duration, CancellationToken ctk)
// 支持动画曲线版本
public static async UniTask DoMove(this GameObject go, Transform startPos, Transform endPos, float duration,
AnimationCurve animCurve, CancellationToken ctk)
// 多点路径版本
public static async UniTask DoMove(this GameObject go, List<Transform> positions, float duration,
AnimationCurve animCurve, CancellationToken ctk)
推荐用法(带曲线):
await cube.DoMove(start, end, 2f, AnimationCurve.EaseInOut(0,0,1,1), cts.Token);
注意:内部创建临时 GameObject 作为锚点,结束后自动销毁。
旋转相关
DoRotate(自转)
// 基本自转(每帧累加)
public static async UniTask DoRotate(this GameObject obj, Vector3 axis, float speed, float duration, CancellationToken ctk)
// 带恢复初始旋转版本
public static async UniTask DoRotate(this GameObject obj, Vector3 axis, float speed, float duration,
CancellationToken ctk, bool restore = true)
DoRotateAround(绕点旋转)
public static async UniTask DoRotateAround(this GameObject obj, GameObject origin, Vector3 axis, float speed,
float duration)
示例:物体绕中心点旋转 360°:
await cube.DoRotateAround(center, Vector3.up, 90f, 4f); // 90°/s → 4秒转一圈
其他实用方法
PingPongMove
/// <summary>
/// 在左右两点间往返运动 count 次,最后回到原点
/// </summary>
public static async UniTask PingPongMove(GameObject obj, Vector3 leftPos, Vector3 rightPos, float duration, int count)
典型场景:模拟震动、筛子抖动、来回提示。
GetPosition(相对坐标)
/// <summary>
/// 计算 point 在 origin 局部坐标系中的位置
/// </summary>
public static Vector3 GetPosition(GameObject origin, Vector3 pointPosition)
用途:机器人基坐标系转换、相对位置计算。
SetTransform
/// <summary>
/// 将 target 的位置、旋转、缩放完全复制给 player
/// </summary>
public static void SetTransform(GameObject player, GameObject target)
典型场景:相机瞬间切换到预设点。