Пример #1
0
    protected override void Update()
    {
        base.Update();

        if (!CombatHandler.Instance.DisableMovement && !SelfTank.DisableMovement)
        {
            SelfTank.HandleInput();
        }
    }
Пример #2
0
    protected override void Update()
    {
        base.Update();

        if (CombatDebugHandler.Instance.MoveTestDebugOn)
        {
            Vector2 targetPos = CombatDebugHandler.Instance.TargetPosForMoveTest;

            Vector2 requestDir = targetPos - (Vector2)SelfTank.transform.position;
            requestDir = AvoidWalls(requestDir);
            SelfTank.PerformActuation(requestDir.normalized);
        }
        else
        {
            if (!CombatHandler.Instance.DisableMovement && !SelfTank.DisableMovement)
            {
                //TargetTank.MarkCurPositionAsBlockedOnMap(Map);

                updateGoalsAndPerformActions();
            }

            CombatDebugHandler.Instance.RegisterObject("goal", curGoal);
        }
    }
Пример #3
0
    public Vector2 AvoidWalls(Vector2 desiredDir)
    {
        Vector2 forwardVec = SelfTank.GetForwardVec();
        Vector2 leftVec    = forwardVec.Rotate(-90);
        Vector2 rightVec   = forwardVec.Rotate(90);
        Vector2 backVec    = forwardVec.Rotate(180);

        // If below 90, ray starting points should be in front of tank. Otherwise, behind tank.
        if (Mathf.Abs(Vector2.SignedAngle(forwardVec, desiredDir.normalized)) > 90)
        {
            Vector2 tmpVec = leftVec;
            leftVec  = rightVec;
            rightVec = tmpVec;

            tmpVec     = forwardVec;
            forwardVec = backVec;
            backVec    = tmpVec;
        }

        float   xAdd      = SelfTank.Hull.Schematic.Size.x / 2f;
        float   yAdd      = SelfTank.Hull.Schematic.Size.y / 2f;
        Vector2 TopCenter = (Vector2)SelfTank.transform.position + forwardVec * yAdd;
        Vector2 TLCorner  = (Vector2)SelfTank.transform.position + forwardVec * yAdd + leftVec * xAdd;
        Vector2 TRCorner  = (Vector2)SelfTank.transform.position + forwardVec * yAdd + rightVec * xAdd;

        // If Collision, then take into account desired Dir and see if risk of collision
        const int WallBit   = 8;
        const int PlayerBit = 9;
        const int LayerMask = 1 << WallBit | 1 << PlayerBit;

        const float DiagRatio = 0.8f;
        float       fanRatio  = Mathf.Clamp01((float)successiveCollisions / 100f);

        float maxDistance = Mathf.Max(SelfTank.Body.velocity.magnitude, 150f);

        RaycastHit2D[] hitResult = new RaycastHit2D[5];
        hitResult[0] = Physics2D.Raycast(TopCenter, forwardVec, maxDistance, LayerMask);
        hitResult[1] = Physics2D.Raycast(TLCorner, forwardVec, maxDistance, LayerMask);
        hitResult[2] = Physics2D.Raycast(TRCorner, forwardVec, maxDistance, LayerMask);
        hitResult[3] = Physics2D.Raycast(TLCorner, (forwardVec * (1f - fanRatio) + leftVec * fanRatio).normalized, maxDistance * DiagRatio, LayerMask);
        hitResult[4] = Physics2D.Raycast(TRCorner, (forwardVec * (1f - fanRatio) + rightVec * fanRatio).normalized, maxDistance * DiagRatio, LayerMask);

        if (Application.isEditor && CombatDebugHandler.Instance.AvoidWallsDebugOn)
        {
            Debug.DrawLine(TopCenter, TopCenter + forwardVec.normalized * maxDistance, Color.blue);
            Debug.DrawLine(TLCorner, TLCorner + forwardVec.normalized * maxDistance, Color.blue);
            Debug.DrawLine(TRCorner, TRCorner + forwardVec.normalized * maxDistance, Color.blue);
            Debug.DrawLine(TLCorner, TLCorner + (forwardVec * (1f - fanRatio) + leftVec * fanRatio).normalized * maxDistance * DiagRatio, Color.blue);
            Debug.DrawLine(TRCorner, TRCorner + (forwardVec * (1f - fanRatio) + rightVec * fanRatio).normalized * maxDistance * DiagRatio, Color.blue);
        }

        bool centerHit    = hitResult[0].collider != null;
        bool leftFordHit  = hitResult[1].collider != null;
        bool rightFordHit = hitResult[2].collider != null;
        bool leftDiagHit  = hitResult[3].collider != null;
        bool rightDiagHit = hitResult[4].collider != null;
        bool leftHit      = leftFordHit || leftDiagHit;
        bool rightHit     = rightFordHit || rightDiagHit;

        Vector2 newDesiredDir = desiredDir;

        const float MinBlend = 0.05f;
        const float MaxBlend = 1.0f;

        successiveCollisions += (centerHit || leftHit || rightHit) ? 1 : 0;

        if (leftHit && !rightHit)
        {
            float minHitDist = 9999;
            if (leftFordHit)
            {
                minHitDist = Mathf.Min(hitResult[1].distance, minHitDist);
            }
            if (leftDiagHit)
            {
                minHitDist = Mathf.Min(hitResult[3].distance, minHitDist);
            }

            float   blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend);
            Vector2 dodgeVec   = desiredDir.Rotate(90);
            newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized;
        }
        else if (rightHit && !leftHit)
        {
            float minHitDist = 9999;
            if (rightFordHit)
            {
                minHitDist = Mathf.Min(hitResult[2].distance, minHitDist);
            }
            if (rightDiagHit)
            {
                minHitDist = Mathf.Min(hitResult[4].distance, minHitDist);
            }

            float   blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend);
            Vector2 dodgeVec   = desiredDir.Rotate(-90);
            newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized;
        }
        else if (centerHit)
        {
            Vector2 obstCenterPos = hitResult[0].collider.transform.position;
            Vector2 diffVec       = obstCenterPos - (Vector2)SelfTank.transform.position;

            float angle = Vector2.SignedAngle(forwardVec, diffVec);

            float minHitDist = hitResult[0].distance;
            if (angle > 0)
            {
                float   blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend);
                Vector2 dodgeVec   = desiredDir.Rotate(-90);
                newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized;
            }
            else
            {
                float   blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend);
                Vector2 dodgeVec   = desiredDir.Rotate(90);
                newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized;
            }
        }
        else
        {
            successiveCollisions = 0;
        }

        return(newDesiredDir);
    }