You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

THREE.js实现鲨鱼随机游动及获取移动方向的技术问询

实现Three.js中鲨鱼随机游动与边界掉头的方案

嘿,这个海洋鲨鱼动画的需求我之前做类似项目时碰过,给你整理一套可行的实现思路和代码示例,应该能直接用上!

核心思路拆解

  • 给鲨鱼设置随机初始移动方向,限定在X-Z平面(海洋水平面)
  • 每一帧根据方向向量更新鲨鱼位置,同时加入随机转向逻辑让游动更自然
  • 实时检测鲨鱼位置是否超出设定的边界范围,触发时反转方向并让鲨鱼掉头
  • 直接通过方向向量或鲨鱼的世界朝向获取当前移动方向

具体代码实现

初始化变量与模型

首先假设你已经加载好鲨鱼模型(这里用THREE.Group代替实际模型),先定义核心参数:

// 鲨鱼模型容器(替换成你实际加载的模型)
const sharkGroup = new THREE.Group();
scene.add(sharkGroup);

// 游动参数配置
let directionVector = new THREE.Vector3(); // 当前移动方向向量
const swimSpeed = 0.15; // 游动速度,可根据场景大小调整
const boundaryX = 120; // X轴边界:[-120, 120]
const boundaryZ = 120; // Z轴边界:[-120, 120]
let randomTurnInterval = Math.random() * 4000 + 3000; // 随机转向间隔(3-7秒)
let lastTimestamp = Date.now();

生成随机游动方向

写一个函数用来生成随机方向,并让鲨鱼朝向该方向:

function setRandomSwimDirection() {
  // 生成0-360度的随机角度,计算X-Z平面的方向向量
  const randomAngle = Math.random() * Math.PI * 2;
  directionVector.x = Math.cos(randomAngle);
  directionVector.z = Math.sin(randomAngle);
  directionVector.y = 0; // 保持水平面游动,如需上下起伏可加小波动
  directionVector.normalize(); // 转为单位向量,保证移动速度均匀

  // 让鲨鱼朝向移动方向(如果模型初始朝向不对,可先调整模型自身旋转)
  sharkGroup.lookAt(sharkGroup.position.clone().add(directionVector));
}

// 初始化时设置第一个随机方向
setRandomSwimDirection();

动画循环中的位置更新与边界处理

在Three.js的动画循环里处理移动、随机转向和边界检测:

function animate() {
  requestAnimationFrame(animate);

  const currentTime = Date.now();
  const delta = currentTime - lastTimestamp;
  lastTimestamp = currentTime;

  // 处理随机转向
  randomTurnInterval -= delta;
  if (randomTurnInterval <= 0) {
    setRandomSwimDirection();
    randomTurnInterval = Math.random() * 5000 + 3000; // 重置随机间隔
  }

  // 更新鲨鱼位置
  sharkGroup.position.add(directionVector.clone().multiplyScalar(swimSpeed));

  // 边界检测与掉头逻辑
  let needTurnAround = false;
  // X轴边界检测
  if (Math.abs(sharkGroup.position.x) >= boundaryX) {
    directionVector.x *= -1;
    needTurnAround = true;
  }
  // Z轴边界检测
  if (Math.abs(sharkGroup.position.z) >= boundaryZ) {
    directionVector.z *= -1;
    needTurnAround = true;
  }

  // 触发掉头:让鲨鱼朝向新的移动方向
  if (needTurnAround) {
    sharkGroup.lookAt(sharkGroup.position.clone().add(directionVector));
    // 如果你更倾向于直接旋转Y轴180度,也可以用下面的代码(但lookAt更准确)
    // sharkGroup.rotation.y += Math.PI;
  }

  // 可选:给鲨鱼添加轻微上下起伏,模拟真实游动
  sharkGroup.position.y = Math.sin(currentTime * 0.0008) * 1.5;

  renderer.render(scene, camera);
}

animate();

获取鲨鱼当前移动方向

有两种简单的方式获取移动方向:

  • 直接使用方向向量:directionVector就是当前的单位移动方向向量,X和Z分量对应水平面上的移动方向
  • 获取世界空间朝向:如果需要考虑模型在场景中的层级旋转,用这个方法更准确:
    const worldDirection = new THREE.Vector3();
    sharkGroup.getWorldDirection(worldDirection);
    // worldDirection就是鲨鱼在世界坐标系下的朝向(即移动方向)
    

优化小技巧

  • 如果鲨鱼模型的初始朝向不是Z轴正方向,建议先调整模型的自身旋转(比如sharkGroup.rotation.y = Math.PI/2),避免lookAt时方向错误
  • 随机转向时可以加入平滑过渡,比如用THREE.MathUtils.lerp让方向向量逐步变化,减少生硬感
  • 可以根据鲨鱼的移动速度调整边界检测的阈值,比如在接近边界时提前减速掉头,更符合真实生物行为

内容的提问来源于stack exchange,提问作者Gomi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:45:45