箭头辅助器是什么
想象一下我们在玩一个3D建造游戏或者看一个科学模拟动画。如果想直观地看到:
- 这个物体是朝哪边转的? (比如一个陀螺的旋转轴)
- 这个力是往哪个方向推的? (比如一阵风吹的方向)
- 这个灯光是照向哪里的? (比如手电筒的光束方向)
- 摄像机是看向哪里的? (比如你的第一人称视角方向)
three.js中提供了一个可视化工具
ArrowHelper ,专门用来在3D场景中绘制一个箭头
,方便清楚地标出某个方向。
核心参数
-
方向 (
dir
): 这是最关键 的!你需要用一个THREE.Vector3
向量来表示箭头指向哪里。比如:new THREE.Vector3(1, 0, 0)
表示指向 X 轴正方向 (右边)。new THREE.Vector3(0, 1, 0)
表示指向 Y 轴正方向 (上边)。new THREE.Vector3(0, 0, 1)
表示指向 Z 轴正方向 (屏幕外/前方)。- 也可以是
(0.5, 0.5, 0)
这样指向斜上方的向量。
-
起点 (
origin
): 箭头从 3D 空间的哪个位置开始画?也是用一个THREE.Vector3
表示坐标点。默认通常是世界的中心(0, 0, 0)
。 -
长度 (
length
): 箭头画多长?一个数字。太短看不清,太长可能穿模。默认值通常够用(比如 1)。 -
颜色 (
color
): 箭头涂成什么颜色?可以是0xff0000
(红色),0x00ff00
(绿色),0x0000ff
(蓝色) 等等。默认是红色。
主要作用
- 直观调试: 这是它最主要的目的!让我们在开发 3D 应用时能 亲眼看到 抽象的方向信息。
- 视觉参考: 在场景中提供清晰的方向标识,帮助用户理解朝向。
- 标记位置和朝向: 可以附加到物体上,实时显示该物体的朝向(比如飞船的机头方向)。
- 可视化向量: 物理模拟中的速度、力、加速度等向量,用箭头表示一目了然。
实时改变箭头指示方向的案例
效果如图

需要了解的API
ArrowHelper
可视化方向工具 ,用于在 3D 场景中绘制带箭头的线段,直观展示 方向、力、旋转轴等抽象概念。
参数 | 类型 | 作用 | 默认值/示例 |
---|---|---|---|
dir |
THREE.Vector3 |
箭头指向的方向 | new THREE.Vector3(1, 0, 0) (X轴) |
origin |
THREE.Vector3 |
箭头的起点坐标 | new THREE.Vector3(0, 0, 0) (场景原点) |
length |
Number |
箭头总长度(杆+锥头) | 1 |
color |
Number (十六进制) |
箭头颜色 | 0xff0000 (红色) |
典型问题解决方法
- 箭头不可见?
检查是否添加至场景:scene.add(arrowHelper)
确认相机位置是否覆盖箭头区域。 - 方向相反?
向量定义错误:new THREE.Vector3(-1,0,0)
指向X轴负方向。 - 箭头穿透物体?
调整length
参数或使用Raycaster
检测碰撞点作为起点。
实现思路
js
const arrow = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), 3, "deepskyblue");
scene.add(arrow);
这里在场景中添加了一个长度为3,指向(0,1,0)Y轴方向的蓝色箭头
js
let frame = 0;
const maxFrame = 500;
function animation() {
const per = frame / maxFrame,
rad = Math.PI * 2 * per, // 弧度制,0~2π
x = Math.cos(rad), // 0~1
y = Math.sin(rad); // 0~1
const dir = new THREE.Vector3(x, y, 0).normalize();
arrow.setDirection(dir);
frame++;
frame %= maxFrame;
renderer.render( scene, camera );
requestAnimationFrame( animation );
}
通过arrow.setDirection(dir)
设置方向,从而实现上图效果
沿指定方向移动
效果如图

创建一个球体和箭头辅助器,如下
js
let V = new THREE.Vector3(1,1,0),
DIR = V.normalize(),
LENGTH = 5;
const arrow = new THREE.ArrowHelper(
DIR, // 方向向量
new THREE.Vector3(0, 0, 0),
LENGTH,
'deepskyblue'
)
scene.add(arrow);
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.3, 32, 32),
new THREE.MeshBasicMaterial({color: 'deeppink'})
)
scene.add(sphere);

要想使箭头做运动可参照上一个案例,这里创建一个update方法来更新状态
js
const update = secs => {
const a1 = frame / maxFrame,
a2 = 1 - Math.abs(0.5 - a1) / 0.5; // 0-1
V.z = -5 + 10 * a2;
DIR = V.clone().normalize(); // 归一化
arrow.setDirection(DIR); // 设置方向
}
接下来就是处理球体的运动,无非是不断更新小球的位置
js
const x = DIR.x * LENGTH * a2, // 计算x
y = DIR.y * LENGTH * a2, // 计算y
z = DIR.z * LENGTH * a2; // 计算z
sphere.position.set(x, y, z);
sphere.lookAt(0, 0, 0);
camera.position.z = z + 3;
最后在循环渲染函数中调用update方法,为了方便观察,这里动态的修改了相机的Z轴位置坐标
以上便是本篇的所有内容,自己动手练一练,感受一下实际效果