Unity GameAI-(2)Steering---WallAvoidance

操控行为--------避墙

1. 操控行为基本概念

  • 操控行为是指操纵控制角色,让它们能以模拟真实的方式在游戏世界中移动。
  • 工作方式
    • 通过产生一定大小和方向的操控力,使角色以某种方式运动。

2. Wall Avoidance实现方式

  • 完全受力操控
    • Wall Avoidance避免与墙碰撞
    • 一堵墙可以看做是一个多边形,墙的法线为墙的朝向
Unity GameAI-(2)Steering---WallAvoidance_第1张图片
Paste_Image.png
  • 操控力计算: 大小与触须前端穿透墙的长度成正比方向为墙的法线方向。
  • 首先给准备好的墙添加上Tag,并且把它标记为Wall的层
Unity GameAI-(2)Steering---WallAvoidance_第2张图片
Paste_Image.png
  • Wall为第八层
Unity GameAI-(2)Steering---WallAvoidance_第3张图片
Paste_Image.png
  • 接着给Cube添加上WallAvoidance的代码控制
    public class WallAvoidance : MonoBehaviour {

     public Vector3 volocity;
     public float spinLength;
     void Start()
     {
      spinLength = 4;
     }
    
     void Update()
    {
      Vector3 steeringForce = new Vector3(0, 0, 0);
      RaycastHit hitForward, hitLeft, hitRight;
      Vector3 offset = new Vector3(0, 1, 0);
      Vector3 newPosition = transform.position + offset;
      Debug.DrawLine(newPosition, newPosition + spinLength * transform.forward, Color.green);
      Debug.DrawLine(newPosition, newPosition + spinLength * (transform.forward - transform.right), Color.green);
      Debug.DrawLine(newPosition, newPosition + spinLength * (transform.forward + transform.right), Color.green);
    
      if (Physics.Raycast(newPosition, transform.forward, out hitForward, spinLength, 1 << 8))
      {
          steeringForce += (spinLength - (newPosition - hitForward.point).magnitude) * hitForward.normal;
      }
      if (Physics.Raycast(newPosition, transform.forward - transform.right, out hitLeft, spinLength, 1 << 8))
      {
          steeringForce += (spinLength - (newPosition - hitLeft.point).magnitude) * hitLeft.normal;
      }
      if (Physics.Raycast(newPosition, transform.forward + transform.right, out hitRight, spinLength, 1 << 8))
      {
          steeringForce += (spinLength - (newPosition - hitRight.point).magnitude) * hitRight.normal;
      }
    
      Vector3 acc = steeringForce / 1;
      volocity += acc * Time.deltaTime;
    
      transform.position += volocity * Time.deltaTime;
    
      if (volocity.magnitude > 0.01)
      {
          Vector3 newForward = Vector3.Slerp(transform.forward, volocity, Time.deltaTime);
          newForward.y = 0;
          transform.forward = newForward;
      }
    }
        }
    
    • 实现的效果:

    • Cube的碰撞检测

Unity GameAI-(2)Steering---WallAvoidance_第4张图片
Paste_Image.png
  • 遇墙以后进行转向
Unity GameAI-(2)Steering---WallAvoidance_第5张图片
Paste_Image.png
  • 逐步转向
Unity GameAI-(2)Steering---WallAvoidance_第6张图片
Paste_Image.png

源码来自蛮牛“寒江独钓9527”老师,谢谢。

你可能感兴趣的:(Unity GameAI-(2)Steering---WallAvoidance)