Search Unity

AI Player Jerky Movement - Overcoming Obstacle

Discussion in 'Physics' started by siddharth3322, Sep 8, 2019.

  1. siddharth3322

    siddharth3322

    Joined:
    Nov 29, 2013
    Posts:
    1,049
    I was working in the 3D war game. So I have written code for the AI player for movement, rotation, overcoming obstacle and shooting.

    When an AI player requires to overcome from the midway obstacle, it is doing continuous jerk in the movement. Jerks mean it is doing continuous left-right rotation and very quickly.

    The following image represents the overall situation that currently exists:
    ai_player_obstacle_detection.png

    AI Player is moving continuously from one place to another and try to find a way from placed obstacles within the environment. So AI player always has one target to reach so when it detects any obstacle it just does some rotation and then after again started moving ahead with already decided target.

    It does not have any problem with bypassing the obstacle but its movement is not smooth that is the main problem.

    Here is the complete code that I am using currently:
    Code (CSharp):
    1.  private void FixedUpdate()
    2.     {
    3.         if (StopMovement)
    4.             return;
    5.  
    6.         myRigidbody.MovePosition(myRigidbody.position + transform.TransformDirection(aiMovement) * movementSpeed * Time.fixedDeltaTime);
    7.  
    8.         TakeTurn();
    9.     }
    10.  
    11.     private void TakeTurn()
    12.     {
    13.         Ray straightRightRay = new Ray(transform.position + Vector3.up * 0.5f + transform.right * 2f, transform.forward);
    14.         Ray straightLeftRay = new Ray(transform.position + Vector3.up * 0.5f - transform.right * 2f, transform.forward);
    15.  
    16.         Debug.DrawRay(straightRightRay.origin, straightRightRay.direction * detectDistance, Color.green);
    17.         Debug.DrawRay(straightLeftRay.origin, straightLeftRay.direction * detectDistance, Color.green);
    18.  
    19.         RaycastHit hit;
    20.  
    21.         // If we detect an obstacle on our right side, swerve to the left
    22.         if (Physics.Raycast(straightRightRay, out hit, detectDistance, obstaclesLayerMask))
    23.         {
    24.             // Rotate left to avoid obstacle
    25.             Rotate(-1);
    26.         }
    27.         else if (Physics.Raycast(straightLeftRay, out hit, detectDistance, obstaclesLayerMask))
    28.         {
    29.             // Otherwise, if we detect an obstacle on our left side, swerve to the right
    30.             // Rotate right to avoid obstacle
    31.             Rotate(1);
    32.         }
    33.         else
    34.         {
    35.             // Rotate the car until it reaches the desired chase angle from either side of the player
    36.             if (Vector3.Angle(transform.forward, targetPoint.position - transform.position) > chaseAngle)
    37.             {
    38.                 followAngle = ChaseAngle(transform.forward, targetPoint.position - transform.position, Vector3.up);
    39.                 Rotate(followAngle);
    40.             }
    41.             else
    42.             {
    43.                 // Otherwise, stop rotating
    44.                 Rotate(0);
    45.             }
    46.         }
    47.     }
    48.  
    49.     // Rotates the car either left or right, and applies the relevant lean and drift effects
    50.     public void Rotate(float rotateDirection)
    51.     {
    52.         // If the car is rotating either left or right, make it drift and lean in the direction its rotating
    53.         if (rotateDirection != 0)
    54.         {      
    55.             // Rotate the car based on the control direction
    56.             myRigidbody.rotation = myRigidbody.rotation * Quaternion.Euler(Vector3.up * rotateDirection * rotationSpeed);
    57.             currentRotation += rotateDirection * rotationSpeed * Time.deltaTime;
    58.  
    59.             if (currentRotation > 360)
    60.                 currentRotation -= 360;
    61.         }
    62.         else
    63.         {
    64.             // Otherwise, if we are no longer rotating, straighten up the car and front wheels
    65.             // Return the base of the car to its 0 angle
    66.             myRigidbody.rotation = myRigidbody.rotation * Quaternion.Euler(Vector3.up * rotateDirection * rotationSpeed);
    67.         }
    68.     }
    69.  
    70.     // Calculates the approach angle of an object towrads another object
    71.     public float ChaseAngle(Vector3 forward, Vector3 targetDirection, Vector3 up)
    72.     {
    73.         // Calculate the approach angle
    74.         approachAngle = Vector3.Dot(Vector3.Cross(up, forward), targetDirection);
    75.  
    76.         // If the angle is higher than 0, we approach from the left ( so we must rotate right )
    77.         if (approachAngle > 0f)
    78.         {
    79.             return 1f;
    80.         }
    81.         else if (approachAngle < 0f)
    82.         {
    83.             //Otherwise, if the angle is lower than 0, we approach from the right ( so we must rotate left )
    84.             return -1f;
    85.         }
    86.         else
    87.         {
    88.             // Otherwise, we are within the angle range so we don't need to rotate
    89.             return 0f;
    90.         }
    91.     }
    Please give me your side suggestion to solve this problem. If you want video recording for jerky player movement then let me know, I will record a short video for you.