
1. Vector3游戏开发中的三维空间魔术师第一次接触Unity时我被场景中飞来飞去的小方块彻底迷住了。当时完全不明白为什么修改几个数字就能让物体在3D空间里自由移动直到我遇见了Vector3这个神奇的结构体。现在每次看到新手对着Transform组件里的Position参数发呆就像看到五年前的自己。Vector3本质上就是个装着三个浮点数的容器x、y、z分别对应三维空间的三个轴向。但千万别小看这三个数字的组合它们能表示位置、方向、速度、加速度等各种物理量。比如用(1,0,0)表示向右移动(0,5,0)表示跳起5米高。我在开发跑酷游戏时角色起跳就是简单的rigidbody.velocity new Vector3(0, 5, 0)。最常用的静态变量要数方向常量了Vector3.forward // (0,0,1) 相当于3D世界的前方 Vector3.up // (0,1,0) 永远指向天空 Vector3.right // (1,0,0) 场景的右侧方向这些常量在本地坐标系和世界坐标系转换时特别有用。记得有次做VR手柄交互需要把手柄的本地坐标转换为世界坐标用Transform.TransformDirection(Vector3.forward)就轻松搞定了。2. Vector3的实战技巧从基础到进阶2.1 移动控制的三种姿势让物体移动是游戏开发的基本功但不同场景需要不同策略。最直接的是修改Transform.positiontransform.position Vector3.forward * Time.deltaTime * speed;这种瞬移式移动适合非物理交互的物体。如果需要物理效果就该轮到Rigidbody上场rigidbody.MovePosition(transform.position moveDirection * speed);而最丝滑的移动当属Vector3.Lerp线性插值我在做相机跟随时最爱用这个transform.position Vector3.Lerp(transform.position, targetPos, 0.1f);但要注意Lerp的第三个参数是插值比例不是速度。想要匀速移动应该用MoveTowardstransform.position Vector3.MoveTowards(currentPos, targetPos, speed);2.2 向量运算的妙用点乘(Dot)和叉乘(Cross)这两个大学线性代数课上的噩梦在游戏开发中却异常实用。点乘可以判断两个向量的方向关系float dot Vector3.Dot(transform.forward, target.position); if(dot 0) Debug.Log(目标在我前方);而叉乘则能获得垂直于两个向量的新向量我在制作第三人称相机时就用它来计算相机的环绕方向Vector3 cross Vector3.Cross(player.forward, Vector3.up);反射(Reflect)方法在做弹射物时特别有用。有次做乒乓球游戏球的反弹就用到了velocity Vector3.Reflect(velocity, hit.normal);这样球碰到墙面就会按照入射角等于反射角的物理规律反弹。3. Quaternion破解三维旋转的密码第一次尝试用欧拉角旋转物体时我遇到了著名的万向节死锁问题。当X轴旋转90度后Y轴和Z轴突然失去控制那个瞬间我决定投入四元数的怀抱。Quaternion用四个分量(x,y,z,w)表示旋转虽然不如欧拉角直观但能避免万向锁问题。Unity内部所有旋转都是用四元数存储的我们在Inspector面板看到的欧拉角只是转换后的显示。创建四元数最常用的方法是Quaternion.Eulertransform.rotation Quaternion.Euler(0, 45, 0); // 绕Y轴旋转45度但要注意直接修改欧拉角可能会产生意外旋转应该始终使用四元数进行运算。3.1 LookRotation让物体注视目标制作敌人AI时我需要让怪物始终面朝玩家。LookRotation方法完美解决了这个问题Vector3 dir player.position - enemy.position; enemy.rotation Quaternion.LookRotation(dir);更复杂的场景可以配合Up参数使用比如让炮塔在倾斜的地面上也能正确瞄准Quaternion.LookRotation(dir, groundNormal);3.2 Slerp旋转插值的艺术物体旋转时直接使用Lerp会显得很生硬这时就该Spherical Linear Interpolation(Slerp)出场了transform.rotation Quaternion.Slerp(currentRot, targetRot, Time.deltaTime);Slerp会沿着球面进行插值保持旋转速度恒定。我在制作开门动画时发现用Slerp比用动画系统更灵活可以实时响应玩家的输入。4. 组合应用第一人称控制器实战现在我们把Vector3和Quaternion的知识用到一个实际案例中。以下是简化版的第一人称控制器代码public class FPSController : MonoBehaviour { public float moveSpeed 5f; public float mouseSensitivity 100f; private float xRotation 0f; private CharacterController controller; void Start() { controller GetComponentCharacterController(); Cursor.lockState CursorLockMode.Locked; } void Update() { // 鼠标控制视角旋转 float mouseX Input.GetAxis(Mouse X) * mouseSensitivity; float mouseY Input.GetAxis(Mouse Y) * mouseSensitivity; xRotation - mouseY; xRotation Mathf.Clamp(xRotation, -90f, 90f); transform.localRotation Quaternion.Euler(xRotation, 0f, 0f); transform.Rotate(Vector3.up * mouseX); // 键盘控制移动 float x Input.GetAxis(Horizontal); float z Input.GetAxis(Vertical); Vector3 move transform.right * x transform.forward * z; controller.Move(move * moveSpeed * Time.deltaTime); } }这个控制器完美展示了Vector3和Quaternion的协作使用Quaternion处理视角旋转避免万向锁问题用Vector3组合移动方向使移动与视角方向一致通过CharacterController.Move实现带碰撞的移动在开发过程中我踩过一个坑忘记对xRotation进行Clamp限制结果玩家可以把头完全转到背后画面极其惊悚。所以记住处理旋转时一定要考虑合理的取值范围。