How do you surround the enemy evenly?

  • A* version: [5.2.4]
  • Unity version: [2024.3.40]

Sometimes players are well surrounded, but sometimes only one side.
image

        _rvoController.locked = distanceToPlayer <= enemyDataSO.attackRadius && angleToPlayer <= enemyDataSO.attackAngle / 2;

Locked when the enemy is able to attack.

Maybe it’s when the speed is small.
or
Maybe it happens when it’s all already clumped together.
Maybe not, but I think it happens a little better in both cases.

How can I solve it?

Also, is there a way to make it evenly surrounded without going to one side?

@aron_granberg

rvocontroller & richai setting

Would you be able to get any video footage of this so I can see a bit better how they’re moving? Also out of curiosity, did you go with RichAI for any specific reason?

I don’t know how to program ECS, so I chose RichAI.

I noticed that the current logic is twisted. animator.deltaposition.x shouldn’t have been multiplied by Time.deltaTime, but I was only moving to _rvocontroller.calculateMovementDelta (transform.position, Time.deltaTime). I fixed it and it’s moving too fast. How do I solve it? I want to get it to work with root motion.

private void OnAnimatorMove()
    {
        if (!IsAnimatorMove) return;

        // var desiredSpeed = (animator.deltaPosition / Time.deltaTime).magnitude;
        // var newSpeed = Mathf.Lerp(_lastSpeed, desiredSpeed, 0.5f);
        // AI.maxSpeed = newSpeed;
        // _lastSpeed = newSpeed;

        Vector3 nextPosition = transform.position;
        Quaternion nextRotation = transform.rotation;

        AI.MovementUpdate(Time.deltaTime, out nextPosition, out nextRotation);

        if (!_isSpecialAttack)
        {
            nextRotation = animator.rootRotation;
        }

        nextPosition.x = transform.position.x + (animator.deltaPosition.x);
        nextPosition.z = transform.position.z + (animator.deltaPosition.z);
        // nextPosition.x += animator.deltaPosition.x * Time.deltaTime;
        // nextPosition.z += animator.deltaPosition.z * Time.deltaTime;

        transform.rotation = nextRotation;
        // Vector3 velocity = animator.deltaPosition / Time.deltaTime;
        // velocity.y = nextPosition.y;

        if (_rvoController.enabled && !_rvoController.locked)
        {
            var delta = _rvoController.CalculateMovementDelta(transform.position, Time.deltaTime);
            nextPosition += delta;

            // _rvoController.priorityMultiplier = delta.magnitude;
            // print(delta);
        }
        // else if (_rvoController.enabled)
        // {
        //     _rvoController.SetTarget(transform.position, 0f, AI.maxSpeed, transform.position);
        // }

        // _rvoController.velocity = animator.velocity; //+ _rvoController.CalculateMovementDelta(transform.position, Time.deltaTime);
        AI.maxSpeed = (animator.deltaPosition / Time.deltaTime).magnitude;

        // transform.position = nextPosition;
        AI.FinalizeMovement(nextPosition, nextRotation);
    }
private void OnAnimatorMove()
    {
        if (!IsAnimatorMove) return;

        // var desiredSpeed = (animator.deltaPosition / Time.deltaTime).magnitude;
        // var newSpeed = Mathf.Lerp(_lastSpeed, desiredSpeed, 0.5f);
        // AI.maxSpeed = newSpeed;
        // _lastSpeed = newSpeed;

        Vector3 nextPosition = transform.position;
        Quaternion nextRotation = transform.rotation;

        AI.MovementUpdate(Time.deltaTime, out nextPosition, out nextRotation);

        if (!_isSpecialAttack)
        {
            nextRotation = animator.rootRotation;
        }

        nextPosition.x = transform.position.x + (animator.deltaPosition.x);
        nextPosition.z = transform.position.z + (animator.deltaPosition.z);
        // nextPosition.x += animator.deltaPosition.x * Time.deltaTime;
        // nextPosition.z += animator.deltaPosition.z * Time.deltaTime;

        transform.rotation = nextRotation;
        // Vector3 velocity = animator.deltaPosition / Time.deltaTime;
        // velocity.y = nextPosition.y;

        if (_rvoController.enabled && !_rvoController.locked)
        {
            _rvoController.SetTarget(nextPosition, 0F, AI.maxSpeed, Vector3.positiveInfinity);
            var delta = _rvoController.CalculateMovementDelta(AI.position, Time.deltaTime);
            nextPosition += delta;

            // _rvoController.priorityMultiplier = delta.magnitude;
            // print(delta);
        }

        // _rvoController.velocity = (nextPosition - AI.position);
        // _rvoController.velocity = animator.velocity; //+ _rvoController.CalculateMovementDelta(transform.position, Time.deltaTime);
        // AI.maxSpeed = (animator.deltaPosition / Time.deltaTime).magnitude;

        // transform.position = nextPosition;
        AI.FinalizeMovement(nextPosition, nextRotation);
    }

I implemented local avoidance when moving in this way, but I don’t consider locked.

  Vector3 directionToPlayer = player.position - transform.position;
        directionToPlayer.y = 0f;
        float angleToPlayer = Vector3.Angle(transform.forward, directionToPlayer);
        float distanceToPlayer = directionToPlayer.magnitude;
        _rvoController.locked = distanceToPlayer <= enemyDataSO.attackRadius && angleToPlayer <= enemyDataSO.attackAngle / 2;

If you turn on locked, it overlaps, and if you don’t, it pushes each other. How can I fix it?