Example #1
0
    public void ChangeRoundCenter(FP _joystickAngle)
    {
        FPVector rv = _childObj.right;

        if (_joystickAngle > 90 && _joystickAngle < 270)
        {
            rv *= -1;
        }

        FP RvRate = 1; //这是为了根据角度值,求圆心

        if (_joystickAngle > 180)
        {
            RvRate += FPMath.Sin((_joystickAngle - 180) * FPMath.Deg2Rad);
        }
        else
        {
            RvRate += FPMath.Sin((_joystickAngle) * FPMath.Deg2Rad);
        }

        _center       = rv * Radius * RvRate;
        _center       = _childObj.position + _center;
        RotationSpeed = FPMath.Abs(RotationSpeed);
        if (_joystickAngle > 90 && _joystickAngle < 270)
        {
            RotationSpeed = FPMath.Abs(RotationSpeed) * -1;
        }
    }
Example #2
0
    public void Update()
    {
        if (_destVector != FPVector.zero)
        {
            float disData   = Vector3.Distance(transform.position, _ufpTransform.position.ToVector());
            FP    fixDistan = MoveSpeed * Time.deltaTime;
            if (disData <= fixDistan)
            {
                UpdatePosition(_ufpTransform.position);
                UpdateRotation(_ufpTransform.rotation);
                //   Debug.Log("======>arrived_____arrived_____arrived_____arrived_____arrived:::" + _ufpTransform.position);
            }
            else
            {
                transform.position += (_childObj.forward * fixDistan).ToVector();
                // Debug.Log("======>_ufpTransform.position_OnLine:::"+ _ufpTransform.position);
            }
        }

        if (_destRoundData != 0)
        {
            FP angleData = _destRoundData - _roundData;
            FP _tempData = RotationSpeed * MoveSpeed * Time.deltaTime;

            //Debug.Log("======>angleData:::" + angleData.AsFloat()
            //      + ",_tempData::" + _tempData.AsFloat() + ",_destRoundData::"+ _destRoundData);
            if (FPMath.Abs(angleData) <= FPMath.Abs(_tempData))
            {
                UpdatePosition(_ufpTransform.position);
                UpdateRotation(_ufpTransform.rotation);
                _roundData = _destRoundData;
                //Debug.Log("======>arrived_____round_____arrived_____round_____arrived:::" + _ufpTransform.position
                //      + ",childObj.forward::" + _childObj.forward + ",childObj.forward.toVector3::" + _childObj.forward.ToVector());
            }

            else
            {
                transform.RotateAround(_center.ToVector(), transform.up, _tempData.AsFloat());
                _roundData += _tempData;
                Debug.Log("======>_ufpTransform.round_round_OnLine:::" + _ufpTransform.position + ",_ufpTransform.position.toVector3::" + _ufpTransform.position
                          //    + ", ufpTransform.rotation:::" + _ufpTransform.rotation
                          //    + ",_ufpTransform.rotation.toVector()::" + _ufpTransform.rotation.ToQuaternion()
                          + ",childObj.forward::" + _childObj.forward + ",childObj.forward.toVector3::" + _childObj.forward.ToVector());
            }
        }


        RaycastHit hitInfo;
        bool       bExitBarrier = (RayBarrierInfo(_childObj.forward.ToVector(), out hitInfo));

        RaycastHit _groundHit;
        RaycastHit _hitInfo;

        if (bJumpFlag)         //处理跳跃
        {
            if (!bJumpArtFlag) //表示第一次开始跳跃
            {
                if (!RayGroundInfo(out _groundHit, true))
                {
                    bJumpArtFlag = true;
                }
            }
            else
            {
                if (RayGroundInfo(out _groundHit, true))
                {
                    bJumpFlag    = false;
                    bJumpArtFlag = false;
                    return;
                }
            }
            _jumpSpeed = _jumpSpeed - g * FrameSyncManager.DeltaTime;                                    //垂直上的初速度随时间的改变
            _ufpTransform.Translate(FPVector.up * _jumpSpeed * FrameSyncManager.DeltaTime, Space.World); //垂直上的运动
            UpdateRotation(_ufpTransform.rotation);
            UpdatePosition(_ufpTransform.position);
            //transform.Translate(Vector3.up * _jumpSpeed * FrameSyncManager.DeltaTime, Space.World);//垂直上的运动


            //if (_jumpSpeed < 0 && RayGroundInfo(out _groundHit, true))   //增加防止坠落的操作
            //{
            //    transform/*.parent*/.position = new Vector3(transform/*.parent*/.position.x, _groundHit.point.y, transform/*.parent*/.position.z);
            //    bJumpFlag = false;
            //    bJumpArtFlag = false;
            //    return;
            //}

            if (bMoveFlag)
            {
                _ufpTransform.Translate(_childObj.forward * MoveSpeed * FrameSyncManager.DeltaTime, Space.World);//水平上的运动
                UpdateRotation(_ufpTransform.rotation);
                UpdatePosition(_ufpTransform.position);
                //  transform.Translate(_childObj.forward.ToVector() * (MoveSpeed/** _frameEntityObj.SpeedRate*/).AsFloat() * Time.fixedDeltaTime, Space.World);//水平上的运动
            }
            return;
        }
        else if (!RayGroundInfo(out _groundHit) && !RayBarrierInfo(_childObj.forward.ToVector(), out _hitInfo) && _bHasSpeed)//空中调整角度
        {
            //Debug.Log("_childObj.forward.ToVector():::" + _childObj.forward.ToVector()
            //    + ",,,,data__ufpTransform.up::" + _ufpTransform.up.ToVector() + ",,,,,fff::"+ _ufpTransform.forward.ToVector());
            _verCurSpeed = _verCurSpeed - g * FrameSyncManager.DeltaTime;                                     //垂直上的初速度随时间的改变
            _ufpTransform.Translate(_childObj.forward * MoveSpeed * FrameSyncManager.DeltaTime, Space.World); //水平上的运动
            _ufpTransform.Translate(FPVector.up * _verCurSpeed * FrameSyncManager.DeltaTime, Space.World);    //垂直上的运动
            UpdateRotation(_ufpTransform.rotation);
            UpdatePosition(_ufpTransform.position);

            //  transform.Translate(_childObj.forward.ToVector() * (MoveSpeed/** _frameEntityObj.SpeedRate*/).AsFloat() * Time.fixedDeltaTime, Space.World);//水平上的运动
            //  transform.Translate(Vector3.up * _verCurSpeed.AsFloat() * Time.fixedDeltaTime, Space.World);//垂直上的运动

            FP angleForward = FPVector.Angle(_ufpTransform.up, FPVector.up);
            if (angleForward == 0)
            {
                return;
            }

            FPVector normal = FPVector.Cross(_ufpTransform.up, FPVector.up);
            // int DirctData = FPMath.Sign(FPVector.Dot(normal, _ufpTransform.up));
            float DirctData = Mathf.Sign(Vector3.Dot(normal.ToVector(), _ufpTransform.up.ToVector()));

            //Debug.Log(" angleForward::" + angleForward.AsFloat() + ",DirctData::"+ DirctData + ",_ufpTransform.up::"+ _ufpTransform.up + "  ,"+  _ufpTransform.up.ToVector() + ",FPVector.up::"+ FPVector.up.ToVector()
            //    + ",normal::" + normal + "," + normal.ToVector()  + ", FPVector.Dot(normal, _ufpTransform.up)::" + FPVector.Dot(normal, _ufpTransform.up).AsFloat());
            //if (DirctData == 0) DirctData = 1;
            angleForward = angleForward * DirctData;

            //   Debug.Log(" FPMath.Sign(FPVector.Dot(normal, _ufpTransform.up)::" + FPVector.Dot(new FPVector(0,0,1), new FPVector(1, 0, 0)));
            FPVector forwardVec3    = FPQuaternion.AngleAxis(angleForward, normal) * _ufpTransform.up;
            FPVector forwardForward = FPQuaternion.AngleAxis(angleForward, normal) * _ufpTransform.forward;

            FPQuaternion qur = FPQuaternion.LookRotation(forwardForward, forwardVec3);
            //Debug.Log("forwardForward:::" + forwardForward.ToVector() + ",,forwardVec3::" + forwardVec3.ToVector()
            //    + ",angleForward::"+ angleForward.AsFloat()
            //    + ",_ufpTransform.up::" + _ufpTransform.up.ToVector() + ", _ufpTransform.forward::" + _ufpTransform.forward.ToVector()
            //    + ",normal::" + normal.ToVector());
            UpdateRotation(FPQuaternion.Slerp(_ufpTransform.rotation, qur, 0.1f));
            //_ufpTransform.SetRotation();
            //transform.rotation = FPQuaternion.Slerp(_ufpTransform.rotation, qur, 0.1f);

            //将玩家处于空中的状态事件发射出去
            TriggerEvent(DefineEventId.PlayerInAirEvent);
        }
        else
        {
            FP angle = FPVector.Angle(FPVector.up, _ufpTransform.ChangeVec3ToTSVec(_groundHit.normal));
            if (angle > SlopeAngle)
            {
                if (!bMoveFlag)
                {
                    _ufpTransform.Translate(-1 * (FPVector.up) * g * FrameSyncManager.DeltaTime, Space.World);
                    UpdateRotation(_ufpTransform.rotation);
                    UpdatePosition(_ufpTransform.position);
                }
            }
            else
            {
                // transform.position = new Vector3(transform/*.parent*/.position.x, _groundHit.point.y, transform/*.parent*/.position.z);
                UpdateRotation(_ufpTransform.rotation);
                UpdatePosition(new FPVector(_ufpTransform.position.x, (FP)(_groundHit.point.y), _ufpTransform.position.z));
            }
        }
    }
Example #3
0
    public void ApplyForces(MoveInfo move)
    {
        if (freeze)
        {
            return;
        }

        controlScript.normalizedJumpArc = (Fix64)1 - ((verticalForce + verticalTotalForce) / (verticalTotalForce * 2));


        Fix64 appliedFriction = (moveDirection != 0 || controlScript.myInfo.physics.highMovingFriction) ?
                                UFE.config.selectedStage._groundFriction : controlScript.myInfo.physics._friction;


        if (move != null && move.ignoreFriction)
        {
            appliedFriction = 0;
        }

        if (controlScript.activePullIn != null)
        {
            worldTransform.position = FPVector.Lerp(worldTransform.position,
                                                    controlScript.activePullIn.position,
                                                    UFE.fixedDeltaTime * controlScript.activePullIn.speed);

            if (controlScript.activePullIn.forceStand && !IsGrounded())
            {
                ForceGrounded();
            }

            if (FPVector.Distance(controlScript.activePullIn.position, worldTransform.position) <= controlScript.activePullIn._targetDistance ||
                controlScript.currentSubState != SubStates.Stunned)
            {
                controlScript.activePullIn = null;
            }
        }
        else
        {
            if (!IsGrounded())
            {
                appliedFriction = 0;
                if (verticalForce == 0)
                {
                    verticalForce = -.1;
                }
            }

            if (horizontalForce != 0 && !isTakingOff)
            {
                if (horizontalForce > 0)
                {
                    horizontalForce -= appliedFriction * UFE.fixedDeltaTime;
                    horizontalForce  = FPMath.Max(0, horizontalForce);
                }
                else if (horizontalForce < 0)
                {
                    horizontalForce += appliedFriction * UFE.fixedDeltaTime;
                    horizontalForce  = FPMath.Min(0, horizontalForce);
                }

                Fix64 leftCameraBounds  = opWorldTransform.position.x - (UFE.config.cameraOptions._maxDistance / 2);
                Fix64 rightCameraBounds = opWorldTransform.position.x + (UFE.config.cameraOptions._maxDistance / 2);

                bool bouncingOnCamera = false;
                if (controlScript.currentHit != null &&
                    controlScript.currentHit.bounceOnCameraEdge &&
                    (worldTransform.position.x <= leftCameraBounds ||
                     worldTransform.position.x >= rightCameraBounds))
                {
                    bouncingOnCamera = true;
                }


                if (wallBounceTimes < UFE.config.wallBounceOptions._maximumBounces &&
                    controlScript.currentSubState == SubStates.Stunned &&
                    controlScript.currentState != PossibleStates.Down &&
                    UFE.config.wallBounceOptions.bounceForce != Sizes.None &&
                    FPMath.Abs(horizontalForce) >= UFE.config.wallBounceOptions._minimumBounceForce &&
                    (worldTransform.position.x <= UFE.config.selectedStage._leftBoundary ||
                     worldTransform.position.x >= UFE.config.selectedStage._rightBoundary || bouncingOnCamera) &&
                    controlScript.currentHit != null && controlScript.currentHit.wallBounce &&
                    !isWallBouncing)
                {
                    if (controlScript.currentHit.overrideForcesOnWallBounce)
                    {
                        if (controlScript.currentHit.resetWallBounceHorizontalPush)
                        {
                            horizontalForce = 0;
                        }
                        if (controlScript.currentHit.resetWallBounceVerticalPush)
                        {
                            verticalForce = 0;
                        }

                        Fix64 addedH = -controlScript.currentHit._wallBouncePushForce.x;
                        Fix64 addedV = controlScript.currentHit._wallBouncePushForce.y;

                        AddForce(new FPVector(addedH, addedV, 0), controlScript.mirror);
                    }
                    else
                    {
                        if (UFE.config.wallBounceOptions.bounceForce == Sizes.Small)
                        {
                            horizontalForce /= -1.4;
                        }
                        else if (UFE.config.wallBounceOptions.bounceForce == Sizes.Medium)
                        {
                            horizontalForce /= -1.2;
                        }
                        else if (UFE.config.wallBounceOptions.bounceForce == Sizes.High)
                        {
                            horizontalForce *= -1;
                        }
                    }

                    wallBounceTimes++;

                    if (verticalForce > 0 || !IsGrounded())
                    {
                        if (moveSetScript.basicMoves.airWallBounce.animMap[0].clip != null)
                        {
                            controlScript.currentHitAnimation = moveSetScript.basicMoves.airWallBounce.name;
                        }
                    }
                    else
                    {
                        if (controlScript.currentHit.knockOutOnWallBounce)
                        {
                            moveSetScript.PlayBasicMove(moveSetScript.basicMoves.standingWallBounceKnockdown);
                            controlScript.currentHitAnimation = moveSetScript.basicMoves.standingWallBounceKnockdown.name;
                        }
                        else
                        {
                            moveSetScript.PlayBasicMove(moveSetScript.basicMoves.standingWallBounce);
                            controlScript.currentHitAnimation = moveSetScript.basicMoves.standingWallBounce.name;
                        }
                    }

                    if (UFE.config.wallBounceOptions.bouncePrefab != null)
                    {
                        GameObject pTemp = UFE.SpawnGameObject(UFE.config.wallBounceOptions.bouncePrefab, transform.position, Quaternion.identity, Mathf.RoundToInt(UFE.config.wallBounceOptions.bounceKillTime * UFE.config.fps));
                        pTemp.transform.rotation = UFE.config.wallBounceOptions.bouncePrefab.transform.rotation;
                        if (UFE.config.wallBounceOptions.sticky)
                        {
                            pTemp.transform.parent = transform;
                        }
                        //pTemp.transform.localPosition = Vector3.zero;
                    }

                    if (UFE.config.wallBounceOptions.shakeCamOnBounce)
                    {
                        controlScript.shakeCameraDensity = UFE.config.wallBounceOptions._shakeDensity;
                    }

                    UFE.PlaySound(UFE.config.wallBounceOptions.bounceSound);
                    isWallBouncing = true;
                }

                worldTransform.Translate((horizontalForce * UFE.fixedDeltaTime), 0, 0);
            }

            if (move == null || (move != null && !move.ignoreGravity))
            {
                if ((verticalForce < 0 && !IsGrounded()) || verticalForce > 0)
                {
                    verticalForce -= appliedGravity * UFE.fixedDeltaTime;
                    worldTransform.Translate((moveDirection * UFE.fixedDeltaTime) * controlScript.myInfo.physics._jumpDistance, (verticalForce * UFE.fixedDeltaTime), 0);
                }
                else if (verticalForce < 0 &&
                         IsGrounded() &&
                         controlScript.currentSubState != SubStates.Stunned)
                {
                    verticalForce = 0;
                }
            }
        }

        Fix64 minDist = opWorldTransform.position.x - UFE.config.cameraOptions._maxDistance;
        Fix64 maxDist = opWorldTransform.position.x + UFE.config.cameraOptions._maxDistance;

        worldTransform.position = new FPVector(FPMath.Clamp(worldTransform.position.x, minDist, maxDist), worldTransform.position.y, worldTransform.position.z);

        worldTransform.position = new FPVector(
            FPMath.Clamp(worldTransform.position.x,
                         UFE.config.selectedStage._leftBoundary,
                         UFE.config.selectedStage._rightBoundary),
            FPMath.Max(worldTransform.position.y, UFE.config.selectedStage._groundHeight),
            worldTransform.position.z);

        if (controlScript.currentState == PossibleStates.Down)
        {
            return;
        }

        if (IsGrounded() && controlScript.currentState != PossibleStates.Down)
        {
            if (verticalTotalForce != 0)
            {
                if (groundBounceTimes < UFE.config.groundBounceOptions._maximumBounces &&
                    controlScript.currentSubState == SubStates.Stunned &&
                    UFE.config.groundBounceOptions.bounceForce != Sizes.None &&
                    verticalForce <= -UFE.config.groundBounceOptions._minimumBounceForce &&
                    controlScript.currentHit.groundBounce)
                {
                    if (controlScript.currentHit.overrideForcesOnGroundBounce)
                    {
                        if (controlScript.currentHit.resetGroundBounceHorizontalPush)
                        {
                            horizontalForce = 0;
                        }
                        if (controlScript.currentHit.resetGroundBounceVerticalPush)
                        {
                            verticalForce = 0;
                        }

                        Fix64 addedH = controlScript.currentHit._groundBouncePushForce.x;
                        Fix64 addedV = controlScript.currentHit._groundBouncePushForce.y;

                        AddForce(new FPVector(addedH, addedV, 0), controlScript.mirror);
                    }
                    else
                    {
                        if (UFE.config.groundBounceOptions.bounceForce == Sizes.Small)
                        {
                            AddForce(new FPVector(0, (-verticalForce / 2.4), 0), 1);
                        }
                        else if (UFE.config.groundBounceOptions.bounceForce == Sizes.Medium)
                        {
                            AddForce(new FPVector(0, (-verticalForce / 1.8), 0), 1);
                        }
                        else if (UFE.config.groundBounceOptions.bounceForce == Sizes.High)
                        {
                            AddForce(new FPVector(0, (-verticalForce / 1.2), 0), 1);
                        }
                    }

                    groundBounceTimes++;

                    if (!isGroundBouncing)
                    {
                        controlScript.stunTime += airTime + UFE.config.knockDownOptions.air._knockedOutTime;

                        if (moveSetScript.basicMoves.groundBounce.animMap[0].clip != null)
                        {
                            controlScript.currentHitAnimation = moveSetScript.basicMoves.groundBounce.name;
                            moveSetScript.PlayBasicMove(moveSetScript.basicMoves.groundBounce);
                        }

                        if (UFE.config.groundBounceOptions.bouncePrefab != null)
                        {
                            GameObject pTemp = UFE.SpawnGameObject(UFE.config.groundBounceOptions.bouncePrefab, transform.position, Quaternion.identity, Mathf.RoundToInt(UFE.config.groundBounceOptions.bounceKillTime * UFE.config.fps));
                            pTemp.transform.rotation = UFE.config.groundBounceOptions.bouncePrefab.transform.rotation;
                            if (UFE.config.groundBounceOptions.sticky)
                            {
                                pTemp.transform.parent = transform;
                            }
                            //pTemp.transform.localPosition = Vector3.zero;
                        }
                        if (UFE.config.groundBounceOptions.shakeCamOnBounce)
                        {
                            controlScript.shakeCameraDensity = UFE.config.groundBounceOptions._shakeDensity;
                        }
                        UFE.PlaySound(UFE.config.groundBounceOptions.bounceSound);
                        isGroundBouncing = true;
                    }
                    return;
                }
                verticalTotalForce          = 0;
                airTime                     = 0;
                moveSetScript.totalAirMoves = 0;
                currentAirJumps             = 0;

                BasicMoveInfo airAnimation  = null;
                string        downAnimation = "";

                isGroundBouncing  = false;
                groundBounceTimes = 0;

                Fix64 animationSpeed = 0;
                Fix64 delayTime      = 0;
                if (controlScript.currentMove != null && controlScript.currentMove.hitAnimationOverride)
                {
                    return;
                }
                if (controlScript.currentSubState == SubStates.Stunned)
                {
                    if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.airRecovery.name))
                    {
                        controlScript.stunTime     = 0;
                        controlScript.currentState = PossibleStates.Stand;
                    }
                    else
                    {
                        controlScript.stunTime = UFE.config.knockDownOptions.air._knockedOutTime + UFE.config.knockDownOptions.air._standUpTime;

                        // Hit Clips
                        if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.getHitKnockBack.name) &&
                            moveSetScript.basicMoves.getHitKnockBack.animMap[1].clip != null)
                        {
                            airAnimation  = moveSetScript.basicMoves.getHitKnockBack;
                            downAnimation = moveSetScript.GetAnimationString(airAnimation, 2);
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.getHitHighKnockdown.name) &&
                                 moveSetScript.basicMoves.getHitHighKnockdown.animMap[1].clip != null)
                        {
                            airAnimation           = moveSetScript.basicMoves.getHitHighKnockdown;
                            downAnimation          = moveSetScript.GetAnimationString(airAnimation, 2);
                            controlScript.stunTime = UFE.config.knockDownOptions.high._knockedOutTime + UFE.config.knockDownOptions.high._standUpTime;
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.getHitMidKnockdown.name) &&
                                 moveSetScript.basicMoves.getHitMidKnockdown.animMap[1].clip != null)
                        {
                            airAnimation           = moveSetScript.basicMoves.getHitMidKnockdown;
                            downAnimation          = moveSetScript.GetAnimationString(airAnimation, 2);
                            controlScript.stunTime = UFE.config.knockDownOptions.highLow._knockedOutTime + UFE.config.knockDownOptions.highLow._standUpTime;
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.getHitSweep.name) &&
                                 moveSetScript.basicMoves.getHitSweep.animMap[1].clip != null)
                        {
                            airAnimation           = moveSetScript.basicMoves.getHitSweep;
                            downAnimation          = moveSetScript.GetAnimationString(airAnimation, 2);
                            controlScript.stunTime = UFE.config.knockDownOptions.sweep._knockedOutTime + UFE.config.knockDownOptions.sweep._standUpTime;
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.getHitCrumple.name) &&
                                 moveSetScript.basicMoves.getHitCrumple.animMap[1].clip != null)
                        {
                            airAnimation  = moveSetScript.basicMoves.getHitCrumple;
                            downAnimation = moveSetScript.GetAnimationString(airAnimation, 2);

                            // Stage Clips
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.standingWallBounceKnockdown.name) &&
                                 moveSetScript.basicMoves.standingWallBounceKnockdown.animMap[1].clip != null)
                        {
                            airAnimation           = moveSetScript.basicMoves.standingWallBounceKnockdown;
                            downAnimation          = moveSetScript.GetAnimationString(airAnimation, 2);
                            controlScript.stunTime = UFE.config.knockDownOptions.wallbounce._knockedOutTime + UFE.config.knockDownOptions.wallbounce._standUpTime;
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.airWallBounce.name) &&
                                 moveSetScript.basicMoves.airWallBounce.animMap[1].clip != null)
                        {
                            airAnimation           = moveSetScript.basicMoves.airWallBounce;
                            downAnimation          = moveSetScript.GetAnimationString(airAnimation, 2);
                            controlScript.stunTime = UFE.config.knockDownOptions.wallbounce._knockedOutTime + UFE.config.knockDownOptions.wallbounce._standUpTime;

                            // Fall Clips
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.fallingFromAirHit.name) &&
                                 moveSetScript.basicMoves.fallingFromAirHit.animMap[1].clip != null)
                        {
                            airAnimation  = moveSetScript.basicMoves.fallingFromAirHit;
                            downAnimation = moveSetScript.GetAnimationString(airAnimation, 2);
                        }
                        else if (moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.fallingFromGroundBounce.name) &&
                                 moveSetScript.basicMoves.fallingFromGroundBounce.animMap[1].clip != null)
                        {
                            airAnimation  = moveSetScript.basicMoves.fallingFromGroundBounce;
                            downAnimation = moveSetScript.GetAnimationString(airAnimation, 2);
                        }
                        else
                        {
                            if (moveSetScript.basicMoves.fallDown.animMap[0].clip == null)
                            {
                                Debug.LogError("Fall Down From Air Hit animation not found! Make sure you have it set on Character -> Basic Moves -> Fall Down From Air Hit");
                            }

                            airAnimation  = moveSetScript.basicMoves.fallDown;
                            downAnimation = moveSetScript.GetAnimationString(airAnimation, 1);
                        }

                        controlScript.currentState = PossibleStates.Down;
                    }
                }
                else if (controlScript.currentState != PossibleStates.Stand)
                {
                    if (moveSetScript.basicMoves.landing.animMap[0].clip != null &&
                        (controlScript.currentMove == null ||
                         (controlScript.currentMove != null && controlScript.currentMove.cancelMoveWheLanding)))
                    {
                        controlScript.isAirRecovering = false;
                        airAnimation  = moveSetScript.basicMoves.landing;
                        moveDirection = 0;
                        isLanding     = true;
                        controlScript.KillCurrentMove();
                        delayTime = (Fix64)controlScript.myInfo.physics.landingDelay / (Fix64)UFE.config.fps;
                        UFE.DelaySynchronizedAction(ResetLanding, delayTime);

                        if (airAnimation.autoSpeed)
                        {
                            animationSpeed = moveSetScript.GetAnimationLength(airAnimation.name) / delayTime;
                        }
                    }

                    if (controlScript.currentState != PossibleStates.Crouch)
                    {
                        controlScript.currentState = PossibleStates.Stand;
                    }
                }

                if (airAnimation != null)
                {
                    if (downAnimation != "")
                    {
                        moveSetScript.PlayBasicMove(airAnimation, downAnimation);
                    }
                    else
                    {
                        moveSetScript.PlayBasicMove(airAnimation);
                    }

                    if (animationSpeed != 0)
                    {
                        moveSetScript.SetAnimationSpeed(airAnimation.name, animationSpeed);
                    }
                }
            }

            if (controlScript.currentSubState != SubStates.Stunned &&
                !controlScript.isBlocking && !controlScript.blockStunned &&
                move == null &&
                !isTakingOff &&
                !isLanding &&
                controlScript.currentState == PossibleStates.Stand)
            {
                if (moveDirection > 0 && controlScript.mirror == -1 ||
                    moveDirection < 0 && controlScript.mirror == 1)
                {
                    if (moveSetScript.basicMoves.moveForward.animMap[0].clip == null)
                    {
                        Debug.LogError("Move Forward animation not found! Make sure you have it set on Character -> Basic Moves -> Move Forward");
                    }
                    if (!moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.moveForward.name))
                    {
                        moveSetScript.PlayBasicMove(moveSetScript.basicMoves.moveForward);
                    }
                }
                else if (moveDirection > 0 && controlScript.mirror == 1 ||
                         moveDirection < 0 && controlScript.mirror == -1)
                {
                    if (moveSetScript.basicMoves.moveBack.animMap[0].clip == null)
                    {
                        Debug.LogError("Move Back animation not found! Make sure you have it set on Character -> Basic Moves -> Move Back");
                    }
                    if (!moveSetScript.IsAnimationPlaying(moveSetScript.basicMoves.moveBack.name))
                    {
                        moveSetScript.PlayBasicMove(moveSetScript.basicMoves.moveBack);
                    }
                }
            }
        }
        else if (verticalForce > 0 || !IsGrounded())
        {
            if (move != null && controlScript.currentState == PossibleStates.Stand)
            {
                controlScript.currentState = PossibleStates.NeutralJump;
            }
            if (move == null && verticalForce / verticalTotalForce > 0 && verticalForce / verticalTotalForce <= 1)
            {
                if (isGroundBouncing)
                {
                    return;
                }

                if (moveDirection == 0)
                {
                    controlScript.currentState = PossibleStates.NeutralJump;
                }
                else
                {
                    if (moveDirection > 0 && controlScript.mirror == -1 ||
                        moveDirection < 0 && controlScript.mirror == 1)
                    {
                        controlScript.currentState = PossibleStates.ForwardJump;
                    }

                    if (moveDirection > 0 && controlScript.mirror == 1 ||
                        moveDirection < 0 && controlScript.mirror == -1)
                    {
                        controlScript.currentState = PossibleStates.BackJump;
                    }
                }

                BasicMoveInfo airAnimation = moveSetScript.basicMoves.jumpStraight;
                if (controlScript.currentSubState == SubStates.Stunned)
                {
                    if (isWallBouncing && moveSetScript.basicMoves.airWallBounce.animMap[0].clip != null)
                    {
                        airAnimation = moveSetScript.basicMoves.airWallBounce;
                    }
                    else if (moveSetScript.basicMoves.getHitKnockBack.animMap[0].clip != null &&
                             FPMath.Abs(horizontalForce) > UFE.config.comboOptions._knockBackMinForce &&
                             UFE.config.comboOptions._knockBackMinForce > 0)
                    {
                        airAnimation = moveSetScript.basicMoves.getHitKnockBack;
                        airTime     *= (Fix64)2;
                    }
                    else
                    {
                        if (moveSetScript.basicMoves.getHitAir.animMap[0].clip == null)
                        {
                            Debug.LogError("Get Hit Air animation not found! Make sure you have it set on Character -> Basic Moves -> Get Hit Air");
                        }

                        airAnimation = moveSetScript.basicMoves.getHitAir;
                    }
                    if (overrideStunAnimation != null)
                    {
                        airAnimation = overrideStunAnimation;
                    }
                }
                else if (controlScript.isAirRecovering &&
                         (moveSetScript.basicMoves.airRecovery.animMap[0].clip != null))
                {
                    airAnimation = moveSetScript.basicMoves.airRecovery;
                }
                else
                {
                    if (moveSetScript.basicMoves.jumpForward.animMap[0].clip != null && controlScript.currentState == PossibleStates.ForwardJump)
                    {
                        airAnimation = moveSetScript.basicMoves.jumpForward;
                    }
                    else if (moveSetScript.basicMoves.jumpBack.animMap[0].clip != null && controlScript.currentState == PossibleStates.BackJump)
                    {
                        airAnimation = moveSetScript.basicMoves.jumpBack;
                    }
                    else
                    {
                        if (moveSetScript.basicMoves.jumpStraight.animMap[0].clip == null)
                        {
                            Debug.LogError("Jump animation not found! Make sure you have it set on Character -> Basic Moves -> Jump Straight");
                        }

                        airAnimation = moveSetScript.basicMoves.jumpStraight;
                    }
                }

                if (!overrideAirAnimation && !moveSetScript.IsAnimationPlaying(airAnimation.name))
                {
                    moveSetScript.PlayBasicMove(airAnimation);

                    if (airAnimation.autoSpeed)
                    {
                        moveSetScript.SetAnimationNormalizedSpeed(airAnimation.name, (moveSetScript.GetAnimationLength(airAnimation.name) / airTime));
                    }
                }
            }
            else if (move == null && verticalForce / verticalTotalForce <= 0)
            {
                BasicMoveInfo airAnimation = moveSetScript.basicMoves.fallStraight;
                if (isGroundBouncing && moveSetScript.basicMoves.fallingFromGroundBounce.animMap[0].clip != null)
                {
                    airAnimation = moveSetScript.basicMoves.fallingFromGroundBounce;
                }
                else if (isWallBouncing && moveSetScript.basicMoves.airWallBounce.animMap[0].clip != null)
                {
                    airAnimation = moveSetScript.basicMoves.airWallBounce;
                }
                else
                {
                    if (controlScript.currentSubState == SubStates.Stunned)
                    {
                        if (moveSetScript.basicMoves.getHitKnockBack.animMap[0].clip != null &&
                            FPMath.Abs(horizontalForce) > UFE.config.comboOptions._knockBackMinForce &&
                            UFE.config.comboOptions._knockBackMinForce > 0)
                        {
                            airAnimation = moveSetScript.basicMoves.getHitKnockBack;
                        }
                        else
                        {
                            airAnimation = moveSetScript.basicMoves.getHitAir;
                            if (moveSetScript.basicMoves.fallingFromAirHit.animMap[0].clip != null)
                            {
                                airAnimation = moveSetScript.basicMoves.fallingFromAirHit;
                            }
                            else if (moveSetScript.basicMoves.getHitAir.animMap[0].clip == null)
                            {
                                Debug.LogError("Air Juggle animation not found! Make sure you have it set on Character -> Basic Moves -> Air Juggle");
                            }
                        }
                        if (overrideStunAnimation != null)
                        {
                            airAnimation = overrideStunAnimation;
                        }
                    }
                    else if (controlScript.isAirRecovering &&
                             (moveSetScript.basicMoves.airRecovery.animMap[0].clip != null))
                    {
                        airAnimation = moveSetScript.basicMoves.airRecovery;
                    }
                    else
                    {
                        if (moveSetScript.basicMoves.fallForward.animMap[0].clip != null && controlScript.currentState == PossibleStates.ForwardJump)
                        {
                            airAnimation = moveSetScript.basicMoves.fallForward;
                        }
                        else if (moveSetScript.basicMoves.fallBack.animMap[0].clip != null && controlScript.currentState == PossibleStates.BackJump)
                        {
                            airAnimation = moveSetScript.basicMoves.fallBack;
                        }
                        else
                        {
                            if (moveSetScript.basicMoves.fallStraight.animMap[0].clip == null)
                            {
                                Debug.LogError("Fall animation not found! Make sure you have it set on Character -> Basic Moves -> Fall Straight");
                            }

                            airAnimation = moveSetScript.basicMoves.fallStraight;
                        }
                    }
                }

                if (!overrideAirAnimation && !moveSetScript.IsAnimationPlaying(airAnimation.name))
                {
                    moveSetScript.PlayBasicMove(airAnimation);

                    if (airAnimation.autoSpeed)
                    {
                        moveSetScript.SetAnimationNormalizedSpeed(airAnimation.name, (moveSetScript.GetAnimationLength(airAnimation.name) / airTime));
                    }
                }
            }
        }
        if (horizontalForce == 0 && verticalForce == 0)
        {
            moveDirection = 0;
        }
    }
Example #4
0
    public void DoFixedUpdate()
    {
        //WrapMode emulator
        if (overrideAnimatorUpdate)
        {
            animator.enabled = false;
            animator.Update((float)UFE.fixedDeltaTime);
        }

        if (currentAnimationData == null || currentAnimationData.clip == null)
        {
            return;
        }

        deltaDisplacement += animator.deltaPosition;
        currentAnimationData.secondsPlayed += FPMath.Abs(UFE.fixedDeltaTime * GetSpeed());
        if (currentAnimationData.secondsPlayed > currentAnimationData.length)
        {
            currentAnimationData.secondsPlayed = currentAnimationData.length;
        }
        currentAnimationData.normalizedTime = currentAnimationData.secondsPlayed / currentAnimationData.length;

        if (currentAnimationData.secondsPlayed == currentAnimationData.length)
        {
            if (currentAnimationData.clip.wrapMode == WrapMode.Loop || currentAnimationData.clip.wrapMode == WrapMode.PingPong)
            {
                if (MecanimControl.OnAnimationLoop != null)
                {
                    MecanimControl.OnAnimationLoop(currentAnimationData);
                }
                currentAnimationData.timesPlayed++;

                if (currentAnimationData.clip.wrapMode == WrapMode.Loop)
                {
                    SetCurrentClipPosition(0);
                }

                if (currentAnimationData.clip.wrapMode == WrapMode.PingPong)
                {
                    SetSpeed(currentAnimationData.clipName, -currentAnimationData.speed);
                    SetCurrentClipPosition(0);
                }
            }
            else if (currentAnimationData.timesPlayed == 0)
            {
                if (MecanimControl.OnAnimationEnd != null)
                {
                    MecanimControl.OnAnimationEnd(currentAnimationData);
                }
                currentAnimationData.timesPlayed = 1;

                if ((currentAnimationData.clip.wrapMode == WrapMode.Once ||
                     currentAnimationData.clip.wrapMode == WrapMode.Clamp) &&
                    alwaysPlay)
                {
                    Play(defaultAnimation, currentMirror);
                }
                else if (!alwaysPlay)
                {
                    SetSpeed(0);
                }
            }
        }
    }
Example #5
0
        public static NavMesh BakeNavMesh(MapData data, MapNavMeshDefinition navmeshDefinition)
        {
            try {
                FPMathUtils.LoadLookupTables();

                var vs_array     = navmeshDefinition.Vertices.ToArray();
                var nav_vertices = vs_array.Map(x => new NavMeshVertex {
                    Point = x.Position.ToFPVector2(), Neighbors = new Int32[0], Triangles = new Int32[0], Borders = new Int32[0]
                });
                var nav_triangles = new NavMeshTriangle[0];

                // TRIANGLES
                for (Int32 i = 0; i < navmeshDefinition.Triangles.Length; ++i)
                {
                    Progress("Baking NavMesh '" + navmeshDefinition.name + "': Calculating Triangles", i, navmeshDefinition.Triangles.Length);

                    var t = navmeshDefinition.Triangles[i];

                    var v0 = Array.FindIndex(vs_array, x => x.Id == t.VertexIds[0]);
                    var v1 = Array.FindIndex(vs_array, x => x.Id == t.VertexIds[1]);
                    var v2 = Array.FindIndex(vs_array, x => x.Id == t.VertexIds[2]);

                    ArrayUtils.Add(ref nav_triangles, new NavMeshTriangle {
                        Vertex0 = v0,
                        Vertex1 = v1,
                        Vertex2 = v2,
                        Center  = (nav_vertices[v0].Point + nav_vertices[v1].Point + nav_vertices[v2].Point) / FP._3
                    });
                }


                // TRIANGLE GRID
                var nav_triangles_grid = new NavMeshTriangleNode[data.Asset.Settings.GridSize * data.Asset.Settings.GridSize];

                //for (Int32 i = 0; i < nav_triangles_grid.Length; ++i) {
                //  nav_triangles_grid[i] = i + 1;
                //}

                for (Int32 i = 0; i < nav_triangles.Length; ++i)
                {
                    Progress("Baking NavMesh '" + navmeshDefinition.name + "': Calculating Triangle Grid", i, nav_triangles.Length);

                    var v0 = nav_vertices[nav_triangles[i].Vertex0].Point;
                    var v1 = nav_vertices[nav_triangles[i].Vertex1].Point;
                    var v2 = nav_vertices[nav_triangles[i].Vertex2].Point;

                    for (Int32 z = 0; z < data.Asset.Settings.GridSize; ++z)
                    {
                        for (Int32 x = 0; x < data.Asset.Settings.GridSize; ++x)
                        {
                            var bl = data.Asset.Settings.WorldOffset + new FPVector2(x * data.Asset.Settings.GridNodeSize, z * data.Asset.Settings.GridNodeSize);
                            var br = bl + new FPVector2(data.Asset.Settings.GridNodeSize, 0);
                            var ur = bl + new FPVector2(data.Asset.Settings.GridNodeSize, data.Asset.Settings.GridNodeSize);
                            var ul = bl + new FPVector2(0, data.Asset.Settings.GridNodeSize);

                            if (
                                // if any of the corners are inside the triangle
                                FPCollision.TriangleContainsPoint(bl, v0, v1, v2) ||
                                FPCollision.TriangleContainsPoint(br, v0, v1, v2) ||
                                FPCollision.TriangleContainsPoint(ur, v0, v1, v2) ||
                                FPCollision.TriangleContainsPoint(ul, v0, v1, v2) ||

                                // BL => BR
                                FPCollision.TriangleContainsPoint(v0, v1, bl, br) ||
                                FPCollision.TriangleContainsPoint(v1, v2, bl, br) ||
                                FPCollision.TriangleContainsPoint(v2, v0, bl, br) ||

                                // BR => UR
                                FPCollision.TriangleContainsPoint(v0, v1, br, ur) ||
                                FPCollision.TriangleContainsPoint(v1, v2, br, ur) ||
                                FPCollision.TriangleContainsPoint(v2, v0, br, ur) ||

                                // UR => UL
                                FPCollision.TriangleContainsPoint(v0, v1, ur, ul) ||
                                FPCollision.TriangleContainsPoint(v1, v2, ur, ul) ||
                                FPCollision.TriangleContainsPoint(v2, v0, ur, ul) ||

                                // UL => BL
                                FPCollision.TriangleContainsPoint(v0, v1, ul, bl) ||
                                FPCollision.TriangleContainsPoint(v1, v2, ul, bl) ||
                                FPCollision.TriangleContainsPoint(v2, v0, ul, bl)
                                )
                            {
                                var idx = (z * data.Asset.Settings.GridSize) + x;

                                if (nav_triangles_grid[idx].Triangles == null)
                                {
                                    nav_triangles_grid[idx].Triangles = new Int32[0];
                                }

                                // add triangle to this grid node
                                ArrayUtils.Add(ref nav_triangles_grid[idx].Triangles, i);
                            }
                        }
                    }
                }

                // VERTEX NEIGHBORS

                for (Int32 v = 0; v < nav_vertices.Length; ++v)
                {
                    Progress("Baking NavMesh '" + navmeshDefinition.name + "': Calculating Vertex Neighbors", v, nav_vertices.Length);

                    var triangles = new HashSet <Int32>();
                    var neighbors = new HashSet <Int32>();

                    for (Int32 t = 0; t < nav_triangles.Length; ++t)
                    {
                        var tr = nav_triangles[t];
                        if (tr.Vertex0 == v || tr.Vertex1 == v || tr.Vertex2 == v)
                        {
                            triangles.Add(t);

                            neighbors.Add(tr.Vertex0);
                            neighbors.Add(tr.Vertex1);
                            neighbors.Add(tr.Vertex2);
                        }
                    }

                    // remove itself from neighbors set
                    neighbors.Remove(v);

                    //
                    nav_vertices[v].Triangles = triangles.OrderBy(x => x).ToArray();
                    nav_vertices[v].Neighbors = neighbors.ToArray();
                }

                // BORDER EDGES

                for (Int32 t = 0; t < nav_triangles.Length; ++t)
                {
                    Progress("Baking NavMesh '" + navmeshDefinition.name + "': Calculating Border Edges", t, nav_triangles.Length);

                    var tr = nav_triangles[t];
                    if (IsBorderEdge(nav_triangles, t, tr.Vertex0, tr.Vertex1))
                    {
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex0].Borders, tr.Vertex1);
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex1].Borders, tr.Vertex0);
                    }

                    if (IsBorderEdge(nav_triangles, t, tr.Vertex1, tr.Vertex2))
                    {
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex1].Borders, tr.Vertex2);
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex2].Borders, tr.Vertex1);
                    }

                    if (IsBorderEdge(nav_triangles, t, tr.Vertex2, tr.Vertex0))
                    {
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex2].Borders, tr.Vertex0);
                        ArrayUtils.Add(ref nav_vertices[tr.Vertex0].Borders, tr.Vertex2);
                    }
                }

                // NORMALS

                var pt2 = FP._0_10 * FP._2;
                var pt3 = FP._0_10 * FP._3;

                for (Int32 i = 0; i < nav_vertices.Length; ++i)
                {
                    Progress("Baking NavMesh '" + navmeshDefinition.name + "': Calculating Normals", i, nav_vertices.Length);

                    var v  = nav_vertices[i];
                    var tn = new FPVector2[3];

                    if (v.Borders != null)
                    {
                        // 0. preferred middle of borders
                        var borders = v.Borders.Map(x => FPVector2.Normalize(nav_vertices[x].Point - v.Point));
                        if (borders.Length == 2)
                        {
                            tn[0] = FPVector2.Normalize(FPVector2.Lerp(borders[0], borders[1], FP._0_50));
                        }

                        // 1. second preferred neighbor edge that is furthest away from borders
                        if (v.Neighbors != null)
                        {
                            var neighbors = v.Neighbors.Where(x => !v.Borders.Contains(x)).Select(x =>
                                                                                                  new Neighbor {
                                Direction = FPVector2.Normalize(nav_vertices[x].Point - v.Point),
                                Vertex    = x
                            }
                                                                                                  ).ToArray();

                            var max_dot      = FP.MinValue;
                            var max_neighbor = default(Neighbor);
                            max_neighbor.Vertex = -1;

                            for (Int32 n = 0; n < neighbors.Length; ++n)
                            {
                                var dot = FP._0;

                                for (Int32 b = 0; b < borders.Length; ++b)
                                {
                                    dot += FPVector2.Dot(borders[b], neighbors[n].Direction);
                                }

                                dot = FPMath.Abs(dot);

                                if (dot > max_dot)
                                {
                                    max_dot      = dot;
                                    max_neighbor = neighbors[n];
                                }
                            }

                            if (max_neighbor.Vertex >= 0)
                            {
                                tn[1] = max_neighbor.Direction * pt2;
                            }
                        }
                    }

                    // 2. least preferred, avarage of triangle normals
                    foreach (var tc in v.Triangles.Select(x => FPVector2.Normalize(TriangleCenter(nav_triangles[x], nav_vertices) - v.Point)))
                    {
                        tn[2] += tc;
                    }

                    tn[2] = FPVector2.Normalize(tn[2]);

                    // find normal
                    var failed = true;

                    for (Int32 k = 0; failed && k < tn.Length; ++k)
                    {
                        if (tn[k] != FPVector2.Zero)
                        {
                            if (failed && TriangleContains(nav_triangles, nav_vertices, (v.Point + (tn[k] * pt3))))
                            {
                                nav_vertices[i].Normal = FPVector2.Normalize(tn[k] * pt2);

                                // we're done
                                failed = false;
                            }

                            if (failed && TriangleContains(nav_triangles, nav_vertices, (v.Point + (-tn[k] * pt3))))
                            {
                                nav_vertices[i].Normal = FPVector2.Normalize(-tn[k] * pt2);

                                // we're done
                                failed = false;
                            }
                        }
                    }
                }

                // BORDER SET

                HashSet <Border> border_set = new HashSet <Border>();

                for (Int32 v = 0; v < nav_vertices.Length; ++v)
                {
                    Progress(navmeshDefinition.name + " Baking: Border Set", v, nav_vertices.Length);

                    if (nav_vertices[v].Borders != null)
                    {
                        for (Int32 n = 0; n < nav_vertices[v].Borders.Length; ++n)
                        {
                            border_set.Add(new Border(v, nav_vertices[v].Borders[n], border_set.Count + 1));
                        }
                    }
                }

                // BORDER GRID

                var nav_border_grid = new NavMeshBorderNode[data.Asset.Settings.GridSize * data.Asset.Settings.GridSize];

                for (Int32 z = 0; z < data.Asset.Settings.GridSize; ++z)
                {
                    for (Int32 x = 0; x < data.Asset.Settings.GridSize; ++x)
                    {
                        var idx = (z * data.Asset.Settings.GridSize) + x;

                        Progress("Baking NavMesh '" + navmeshDefinition.name + "': Border Grid", idx, data.Asset.Settings.GridSize * data.Asset.Settings.GridSize);

                        // set index key
                        // nav_border_grid[idx].key = idx + 1;

                        //
                        var zn = (FP)z * data.Asset.Settings.GridNodeSize;
                        var xn = (FP)x * data.Asset.Settings.GridNodeSize;

                        FPVector2 bl = data.Asset.Settings.WorldOffset + new FPVector2(xn, zn);
                        FPVector2 br = data.Asset.Settings.WorldOffset + new FPVector2(xn + data.Asset.Settings.GridNodeSize, zn);
                        FPVector2 ur = data.Asset.Settings.WorldOffset + new FPVector2(xn + data.Asset.Settings.GridNodeSize, zn + data.Asset.Settings.GridNodeSize);
                        FPVector2 ul = data.Asset.Settings.WorldOffset + new FPVector2(xn, zn + data.Asset.Settings.GridNodeSize);

                        foreach (var b in border_set)
                        {
                            var p0 = nav_vertices[b.V0].Point;
                            var p1 = nav_vertices[b.V1].Point;

                            if (
                                FPCollision.LineIntersectsLine(p0, p1, bl, br) ||
                                FPCollision.LineIntersectsLine(p0, p1, br, ur) ||
                                FPCollision.LineIntersectsLine(p0, p1, ur, ul) ||
                                FPCollision.LineIntersectsLine(p0, p1, ul, bl)
                                )
                            {
                                if (nav_border_grid[idx].Borders == null)
                                {
                                    nav_border_grid[idx].Borders = new NavMeshBorder[0];
                                }

                                ArrayUtils.Add(ref nav_border_grid[idx].Borders, new NavMeshBorder {
                                    Key = b.Key,
                                    V0  = p0,
                                    V1  = p1,
                                });
                            }
                        }
                    }
                }

                // TRIANGLE CENTER GRID

                var nav_triangles_center_grid = new Int32[data.Asset.Settings.GridSize * data.Asset.Settings.GridSize];

                for (Int32 z = 0; z < data.Asset.Settings.GridSize; ++z)
                {
                    for (Int32 x = 0; x < data.Asset.Settings.GridSize; ++x)
                    {
                        var idx = (z * data.Asset.Settings.GridSize) + x;

                        Progress("Baking NavMesh '" + navmeshDefinition.name + "': Triangle Center Grid", idx, data.Asset.Settings.GridSize * data.Asset.Settings.GridSize);

                        var zn = (FP)(z * data.Asset.Settings.GridNodeSize);
                        var xn = (FP)(x * data.Asset.Settings.GridNodeSize);
                        var g  = data.Asset.Settings.WorldOffset + new FPVector2(xn, zn) + new FPVector2(FP.FromFloat_UNSAFE(data.Asset.Settings.GridNodeSize * 0.5f), FP.FromFloat_UNSAFE(data.Asset.Settings.GridNodeSize * 0.5f));

                        var d = FP.MaxValue;
                        var t = -1;

                        for (Int32 i = 0; i < nav_triangles.Length; ++i)
                        {
                            var c = nav_triangles[i].Center;

                            if (FPVector2.DistanceSquared(g, c) < d)
                            {
                                d = FPVector2.DistanceSquared(g, c);
                                t = i;
                            }
                        }

                        Assert.Check(t >= 0);

                        nav_triangles_center_grid[idx] = t;
                    }
                }

                NavMesh navmesh;

                navmesh              = new NavMesh();
                navmesh.GridSize     = data.Asset.Settings.GridSize;
                navmesh.GridNodeSize = data.Asset.Settings.GridNodeSize;
                navmesh.WorldOffset  = data.Asset.Settings.WorldOffset;

                navmesh.Name                = navmeshDefinition.name;
                navmesh.Vertices            = nav_vertices;
                navmesh.BorderGrid          = nav_border_grid;
                navmesh.Triangles           = nav_triangles;
                navmesh.TrianglesGrid       = nav_triangles_grid;
                navmesh.TrianglesCenterGrid = nav_triangles_center_grid;

                return(navmesh);
            }
            finally {
#if UNITY_EDITOR
                EditorUtility.ClearProgressBar();
#endif
            }
        }