public bool GetSteering(out KinematicSteeringOutput output) { //注意这里是不设上限的,但是,随着距离减小,速度会越来越慢, //当Velocity 小于 max_speed 之后,也就是实现Arrive的效果 output.velocity = target.position - character.position; //待定:这里是不是要想Raycast一样,用bool做返回值呢? //接受上面的重构建议:这样使用方就能方便的知道,Steering是否终止。 if (output.velocity.magnitude < satisfaction_radius) { output = default(KinematicSteeringOutput); return(false); } //控制速度衰变开始的时机,如果C_TIME_TO_TARGET 大于一,则增大衰变开始 //反之,则减少衰变开始的时间。 output.velocity /= C_TIME_TO_TARGET; //这里会统一Clip一下,防止速度超标。 if (output.velocity.magnitude > max_speed) { output.velocity = output.velocity.normalized; output.velocity *= max_speed; } character.orientation = SteerUtils.GetNewOrientation(character.orientation, output.velocity); output.rotation = 0; return(true); }
/// <summary> /// 这样做并不是很好,后面的处理碰撞预测,和碰墙预测,就搞不好了。 /// 建议还是改成,将Target作为结构体出现,并且,增加GetTargetFormGameObject和ApplyTargetToGameObject两个方法 /// 用来驱动Unity的GameObject行动,这样还可以做到,完全的,游戏逻辑和显示层分离。先不写了,整理代码的时候,在搞这块 /// 我要丰富一下Apex和BehaviorDesigner的算法 /// </summary> /// <returns></returns> protected override float CalculateOrientation() { //更新蜿蜒朝向 wanderOrientation = SteerUtils.RandomBinomial() * wanderRate; //计算蜿蜒方向,相对于当前朝向的方向。 target_orientation = wanderOrientation + character.orientation * Mathf.Deg2Rad; return(target_orientation); }
public bool GetSteering(out KinematicSteeringOutput output) { //get Velocity form orientation output.velocity = max_speed * SteerUtils.OrientationToVector3_XZ(character.orientation); //Q:每帧都变吗,不会有问题吗?GetSteering不是应该每帧都调用的吗啊?还是可以隔一段时间调用过一次? output.rotation = SteerUtils.RandomBinomial() * max_rotation; return(true); }
//在这个最简单的算法里面,速度是恒定的。 public bool GetSteering(out KinematicSteeringOutput steering) { steering.velocity = (target.position - owner.position) * flee; steering.velocity = steering.velocity.normalized * max_speed; //这样合适嘛,你直接就在这里把朝向给改了?作者你也太不负责任了。 owner.orientation = SteerUtils.GetNewOrientation(owner.orientation, steering.velocity); steering.rotation = 0; return(true); }
public override bool GetSteering(out SteeringOutput output) { //计算直线Offset Vector3 target = character.position + wanderOffset * SteerUtils.OrientationToVector3_XZ(character.orientation); //计算小圆半径Offset target += wanderRadius * SteerUtils.OrientationToVector3_XZ(target_orientation); base.GetSteering(out output); output.linearAccerlation = maxAccerlation * SteerUtils.OrientationToVector3_XZ(character.orientation); return(true); }
virtual public bool GetSteering(out SteeringOutput output) { //第一步计算朝向差值 float rotation = CalculateOrientation(); //映射到-Pi到Pi区间 rotation = SteerUtils.MapToRange(rotation); float rotationSize = Mathf.Abs(rotation); if (rotationSize < satisfiedRadius) { output = default(SteeringOutput); return(false);//不再需要Steering了 } float targetRotationSpeed; //如果没到最大值。那么取得最大值 if (rotationSize > slowDownRadius) { targetRotationSpeed = maxSpeedAngular; } else { targetRotationSpeed = maxSpeedAngular * rotationSize / slowDownRadius; } //确定方向 targetRotationSpeed *= rotation / rotationSize; output.angularAccerlation = targetRotationSpeed - character.angular; output.angularAccerlation /= timeToTargetSpeed; //Clip if (output.angularAccerlation > maxAccelerationgAngular) { output.angularAccerlation /= Mathf.Abs(output.angularAccerlation); output.angularAccerlation *= maxAccelerationgAngular; } output.linearAccerlation = Vector3.zero; return(true); }