示例#1
0
    private IEnumerator MoveToPositionRoutine(Vector3 newPosition)
    {
        float startTime = 0;

        float distance = Vector3.Distance(transform.position, newPosition);

        float totalTime = distance / movingSpeed;

        while (startTime < totalTime)
        {
            transform.position = Vector3.Lerp(transform.position, newPosition, startTime);

            if (transform.position == newPosition)
            {
                isMoving = false;

                yield break;
            }

            startTime += Time.deltaTime;

            yield return(null);
        }

        isMoving = false;
    }
示例#2
0
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.H) && !_launched)
        {
            _launched = true;
            var camWorldPoint = _main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, Distance));
            _destination          = camWorldPoint;
            _shotStart            = Time.time;
            Hook.forward          = (_destination - transform.position).normalized;
            _lineRenderer.enabled = true;
            _lineRenderer.SetPosition(0, transform.position);
        }

        if (_launched)
        {
            var delta = Time.time - _shotStart;
            delta /= _shotduration;
            if (delta > 1)
            {
                delta     = 1;
                _launched = false;
            }
            var distanceToDestination = Vector3.Distance(Hook.position, _destination);
            Hook.position = Vector3.Lerp(Hook.position, _destination, delta / distanceToDestination);
            _lineRenderer.SetPosition(1, Hook.position);
        }
        else
        {
            Hook.position         = transform.position;
            _lineRenderer.enabled = false;
        }
    }
示例#3
0
    private void LateUpdate()
    {
        Vector3 desiredPosition  = focus.position + distance;
        Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, followSpeed * Time.deltaTime);

        transform.position = smoothedPosition;
    }
示例#4
0
 public void Interpolate()
 {
     if (!hasBeenRipped)
     {
         if (!CheckIfSnapOverThreshold() && _customThrowable.getCurrentHandType() == SteamVR_Input_Sources.LeftHand)
         {
             head.transform.position =
                 Vector3.Lerp(leftHand.transform.position, bodySnapPoint.transform.position, 0.5f);
             //head.transform.rotation =
             //UnityEngine.Quaternion.Lerp(leftHand.transform.rotation, bodySnapPoint.transform.rotation, 0.5f);
             vibration.vibrationOfLeftController(0, 1, 1000, 200);
         }
         else if (!CheckIfSnapOverThreshold() &&
                  _customThrowable.getCurrentHandType() == SteamVR_Input_Sources.RightHand)
         {
             head.transform.position =
                 Vector3.Lerp(rightHand.transform.position, bodySnapPoint.transform.position, 0.5f);
             //head.transform.rotation =
             //UnityEngine.Quaternion.Lerp(leftHand.transform.rotation, bodySnapPoint.transform.rotation, 0.5f);
             vibration.vibrationOfRightController(0, 1, 1000, 200);
         }
         else if (CheckIfSnapOverThreshold())
         {
             ResetHeadToOriginalPosition();
         }
     }
 }
 private void FixedUpdate()
 {
     if (canMove)
     {
         rb.velocity = Vector3.Lerp(rb.velocity, new Vector3(tempVel.x * MoveSpeed, rb.velocity.y, tempVel.z * MoveSpeed), 0.2f);
     }
 }
示例#6
0
        private void InterpolateHorizontal() // Interpolates the horizontal x,z position during jump
        {
            _nextPos.y = _rigidBody.position.y;
            var lerp = Vector3.Lerp(_rigidBody.position, _nextPos, _forwardSpeed * Time.deltaTime);

            _rigidBody.position = lerp;
        }
示例#7
0
        private void UpdatePos()
        {
            try
            {
                Vector3 pos = this.m_tank.transform.position;

                Vector3 rot = this.m_tank.transform.eulerAngles;

                float distance = (pos - this.m_nPos).magnitude;

                // 如果服务器位置与本地位置相差不到0.1f,就不进行移动
                if (Mathf.Abs(distance) < 0.1f)
                {
                    return;
                }

                // 从当前位置向预测位置移动
                if (this.m_delta > 0)
                {
                    this.m_tank.transform.position = Vector3.Lerp(pos, this.m_fPos, this.m_delta);
                    this.m_tank.transform.rotation = Quaternion.Lerp(Quaternion.Euler(rot), Quaternion.Euler(this.m_fRot), this.m_delta);
                }
            }
            catch (Exception e)
            {
                Log.Error("Update" + e);
            }
        }
示例#8
0
    void UpdateLine(Vector3 lineBase, Vector3 lineTip)
    {
        tentacleTip  = lineTip;
        tentacleBase = lineBase;

        // finding a point between tip and base (dependent on midOffset) and makes it hang down
        Vector3 targetMid = Vector3.Lerp(lineTip, lineBase, midOffset) + hangAmount * Vector3.down;

        midVel = Vector3.Lerp(midVel, targetMid - tentacleMid, smoothAmount);

        tentacleMid += midVel * moveSpeed; // how fast the tentacle should move
        midVel      *= 1f - drag;          // decrease midVel like a spring

        Vector3 a = tentacleBase;
        Vector3 b = tentacleMid;
        Vector3 c = tentacleTip;

        // iterate every point in the line and updating their positions, lerping to make wobbly line
        float step = 1f / (tentacleLine.positionCount - 1f); // distance between the points in the line; -1f so that tip isn't smoothed out

        for (int i = 0; i < tentacleLine.positionCount; i++)
        {
            float   f            = step * i; // how far along the line we're in; the point we're in
            Vector3 currentPoint = Vector3.Lerp(Vector3.Lerp(a, b, f), Vector3.Lerp(b, c, f), f);
            // first lerp (a, b, f) --> point between base and mid
            // second lerp (b, c, f) --> point between mid to tip
            // lerping between the 2 above points; bezier curve
            tentacleLine.SetPosition(i, currentPoint);
        }
    }
示例#9
0
        private void UpdatePosition()
        {
            if (moveByArc)
            {
                if (count < 1.0f && movingToPoint)
                {
                    count += moveSpeed * Time.deltaTime;

                    Vector3 m1 = Vector2.Lerp(startPosition, middlePoint, count);
                    Vector3 m2 = Vector2.Lerp(middlePoint, targetPosition, count);
                    transform.position = Vector2.Lerp(m1, m2, count);
                    var rotation = Vector2Utils.CalculateFacingToTarget(m1, m2).angle;
                    transform.rotation = rotation;
                }
            }
            else
            {
                if (transform.position != new Vector3(targetPosition.x, targetPosition.y, 0) && movingToPoint)
                {
                    transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * moveSpeed);
                }
                else
                {
                    movingToPoint = true;
                }
            }
        }
示例#10
0
    protected override void Update()
    {
        base.Update();

        //We must have at least 2 moves in the buffer, to calculate the delta time

        if (moves.Count > 1)
        {
            if (ReachedDestination(nextMove.Position))
            {
                AdvanceToNextMove();
            }
        }

        Vector3 velocity  = Vector3.zero;
        var     deltaRate = Time.deltaTime * NetworkConstants.TickRate;

        elapsedLerpTime += deltaRate;

        if (!ReachedDestination(nextMove.Position))
        {
            Vector3 oldPosition = transform.position;
            transform.position = Vector3.Lerp(realStartMovePos, nextMove.Position, elapsedLerpTime);
            velocity           = (oldPosition - transform.position) / Time.deltaTime;
        }
        if (!ReachedRotation(nextMove.Rotation))
        {
            transform.rotation = Quaternion.Lerp(realStartRotation, nextMove.Rotation, elapsedLerpTime);
        }

        movementController.SetPositionRotationAndVelocity(transform.position, transform.rotation, velocity);
    }
示例#11
0
        /** Calculate the AI's next position (one frame in the future).
         * \param direction The tangent of the segment the AI is currently traversing. Not normalized.
         */
        protected virtual Vector3 CalculateNextPosition(out Vector3 direction, float deltaTime)
        {
            if (!interpolator.valid)
            {
                direction = Vector3.zero;
                return(simulatedPosition);
            }

            interpolator.distance += deltaTime * speed;

            if (interpolator.remainingDistance < 0.0001f && !reachedEndOfPath)
            {
                reachedEndOfPath = true;
                OnTargetReached();
            }

            direction = interpolator.tangent;
            pathSwitchInterpolationTime += deltaTime;
            var alpha = switchPathInterpolationSpeed * pathSwitchInterpolationTime;

            if (interpolatePathSwitches && alpha < 1f)
            {
                // Find the approximate position we would be at if we
                // would have continued to follow the previous path
                Vector3 positionAlongPreviousPath = previousMovementOrigin + Vector3.ClampMagnitude(previousMovementDirection, speed * pathSwitchInterpolationTime);

                // Interpolate between the position on the current path and the position
                // we would have had if we would have continued along the previous path.
                return(Vector3.Lerp(positionAlongPreviousPath, interpolator.position, alpha));
            }
            else
            {
                return(interpolator.position);
            }
        }
示例#12
0
    // Update is called once per frame
    void Update()
    {
        if (player)
        {
            int currentX = Mathf.RoundToInt(player.position.x);
            if (currentX > lastX)
            {
                isLeft = false;
            }
            else if (currentX < lastX)
            {
                isLeft = true;
            }
            lastX = Mathf.RoundToInt(player.position.x);

            Vector3 target;

            if (isLeft)
            {
                target = new Vector3(player.position.x - offset.x, player.position.y - offset.y, transform.position.z);
            }
            else
            {
                target = new Vector3(player.position.x + offset.x, player.position.y + offset.y, transform.position.z);
            }
            Vector3 currentPosition = Vector3.Lerp(transform.position, target, dumping * Time.deltaTime);
            transform.position = currentPosition;
        }
    }
示例#13
0
        void Update()
        {
            //Must be the local player, or they cannot move
            if (!isLocalPlayer)
            {
                return;
            }

            //Ignore movement controls when typing in chat
            if (chatRegister.ChatWindow != null && chatRegister.ChatWindow.PlayerIsTyping())
            {
                currentMovement.Set(0, 0);
                return;
            }

            if (Input.GetButtonDown("Toggle Run"))
            {
                isWalking = !isWalking;
            }

            // TODO: Implement gravity and grabbing
            // Calculate next movement
            // The vector is not normalized to allow for the input having potential rise and fall times
            float x = Input.GetAxisRaw("Horizontal");
            float y = Input.GetAxisRaw("Vertical");

            // Smoothly transition to next intended movement
            intendedMovement = new Vector2(x, y).normalized *(isWalking ? walkSpeed : runSpeed);
            currentMovement  = Vector2.MoveTowards(currentMovement, intendedMovement, Time.deltaTime * (Mathf.Pow(ACCELERATION / 5f, 3) / 5));

            absoluteMovement = new Vector3(absoluteMovement.x, 0, absoluteMovement.z);
            // Move the player
            if (currentMovement != Vector2.zero)
            {
                // Determine the absolute movement by aligning input to the camera's looking direction
                Vector3 absoluteMovement =
                    currentMovement.y * Vector3.Cross(mainCamera.transform.right, Vector3.up).normalized +
                    currentMovement.x * Vector3.Cross(Vector3.up, mainCamera.transform.forward).normalized;

                if (intendedMovement != Vector2.zero)
                {
                    // Move (without gravity). Whenever we move we also readjust the player's direction to the direction they are running in.
                    characterController.Move(absoluteMovement * (Time.deltaTime / 3.5f));

                    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(absoluteMovement), Time.deltaTime * 10);
                }
                if (intendedMovement == Vector2.zero)
                {
                    absoluteMovement = Vector3.Lerp(absoluteMovement, Vector3.zero, Time.deltaTime * 5);
                }
                characterController.Move(absoluteMovement * Time.deltaTime);
            }
            // animation Speed is a proportion of maximum runSpeed, and we smoothly transitions the speed with the Lerp
            float currentSpeed = characterAnimator.GetFloat("Speed");
            float newSpeed     = Mathf.LerpUnclamped(currentSpeed, currentMovement.magnitude / runSpeed, Time.deltaTime * (isWalking ? walkSpeed : runSpeed) * 3);

            characterAnimator.SetFloat("Speed", newSpeed);

            ForceHeightLevel();
        }
    // Update is called once per frame
    void Update()
    {
        if (Input.touchCount > 0 && Time.timeScale > 0)
        {
            Touch touch = Input.GetTouch(0);

            if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                Debug.Log("Touched the UI");
                return;
            }

            // touchPos.z = 0;

            // Move Up
            if (touch.position.y > screenHeight / 2 && touch.phase == TouchPhase.Began)
            {
                if (velocity.y < 1)
                {
                    velocity += Vector3.up;
                }
            }

            // Move Down
            else if (touch.position.y < screenHeight / 2 && touch.phase == TouchPhase.Began)
            {
                if (velocity.y > -1)
                {
                    velocity += Vector3.down;
                }
            }

            transform.position = Vector3.Lerp(transform.position, velocity, speed);
        }
    }
示例#15
0
    private void UpdateCockRoach(Vector2 angle)
    {
        for (int i = 0; i < _cockroaches.Count; i++)
        {
            var cockroach = _cockroaches[i];
            if (Time.time - cockroach.TimeBirth > _gameSettings.YoungAge && cockroach.Age == Age.Young)
            {
                cockroach.ChangeStage(Age.Adult);
            }

            if (Time.time - cockroach.TimeBirth > _gameSettings.AdultAge && cockroach.Age == Age.Adult)
            {
                cockroach.ChangeStage(Age.Old);
            }

            if (Time.time - cockroach.TimeBirth > _gameSettings.OldAge && cockroach.Age == Age.Old)
            {
                cockroach.Age = Age.Death;
            }

            if (cockroach.Age == Age.Death)
            {
                cockroach.SetDeath();
                _cockroaches.RemoveAt(i);
                DeathMarker = cockroach.Name + " died of old age";
            }
            else if (cockroach.IsOnBlob)
            {
                cockroach.SetDeath();
                _cockroaches.RemoveAt(i);
                DeathMarker = cockroach.Name + " died of poison";
            }
            else
            {
                cockroach.SetPosition(angle, _mainCamera.transform.position, AveragePos, _gameSettings.Speed);
            }
        }


        AveragePos = Vector2.zero;
        foreach (var cockroach in _cockroaches)
        {
            AveragePos += new Vector2(cockroach.transform.position.x, cockroach.transform.position.y);
        }

        AveragePos /= _cockroaches.Count;

        var transform = _mainCamera.transform;
        var delta     = angle * _gameSettings.Speed;

        if (!Single.IsNaN(angle.x))
        {
            transform.position += new Vector3(delta.x, delta.y);
        }
        if (!Single.IsNaN(AveragePos.x))
        {
            transform.position = Vector3.Lerp(transform.position,
                                              new Vector3(AveragePos.x, AveragePos.y, transform.position.z), 0.01f);
        }
    }
示例#16
0
 void FixedUpdate()
 {
     tailTarget = tailTargetObject.transform.position;
     transform.LookAt(tailTarget);
     transform.position = Vector3.Lerp(transform.position, tailTarget, Time.deltaTime * speed);
     tailTarget.z      -= zOffSet;
 }
示例#17
0
    private void FixedUpdate()
    {
        Vector3 desiredPosition  = target.position + offset;
        Vector3 smoothedPosition = Vector3.Lerp(transform.position,
                                                desiredPosition, smoothSpeed);

        transform.position = smoothedPosition;
    }
示例#18
0
    // Update is called once per frame

    void Update()
    {
        //transform.Rotate();

        /*while (true)
         * {
         *  if (x == 180)
         *      transform.Rotate(Vector3.left, 1, 0);
         *  if (x == 0)
         *      transform.Rotate(Vector3.right, 1, 0);
         * }*/
        //transform.rotation =Quaternion.Euler(Random.Range(0.0f,180.0f),0f,0f);

        if (transform.eulerAngles.x <= 0 || transform.eulerAngles.x <= 90)
        {
            //transform.Rotate(Vector3.right, 1, 0);
            float   degrees = 90;
            Vector3 goUp    = new Vector3(degrees, 0, 0);
            transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, goUp, Time.deltaTime);
        }

        //transform.Rotate(-4,0,0,Space.Self);
        //transform.Rotate(Vector3.right,-1,0);

        else if (transform.eulerAngles.x >= 90)// && transform.eulerAngles.x >= 0)
        {
            //transform.Rotate(Vector3.left, 1, 0);
            //transform.Rotate(Vector3.right,1,0);
            float   degrees = 0;
            Vector3 goUp    = new Vector3(degrees, 0, 0);
            transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, goUp, Time.deltaTime);
        }


        //transform.Rotate(4,0,0,Space.Self);

        //transform.eulerAngles = new Vector3(Mathf.Clamp(angle, 0, 180),0,0); //ClampAngle(angle, 0, 180), 0, 0);

        //float degrees = 90;
        //Vector3 goUp = new Vector3(degrees, 0, 0);
        //transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, goUp, Time.deltaTime);

        //float degrees = 90;
        //Vector3 goDown= new Vector3(degrees, 0, 0);
        //transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, goDown, Time.deltaTime);

        /*
         * if (transform.eulerAngles.x > 180&&Input.GetKey("s"))
         * {
         *  GetComponent<Rigidbody>().angularVelocity=new Vector3(-.5f,0,0);
         * }
         * else if (transform.eulerAngles.x < 0 && Input.GetKey("w") )
         * {
         *  GetComponent<Rigidbody>().angularVelocity=new Vector3(.5f,0,0);
         * }
         */
    }
示例#19
0
        protected virtual void Update()
        {
            // Store
            var oldScale = transform.localPosition;

            if (_localScale.Equals(Vector3.zero))
            {
                _localScale = transform.localScale;                                   //
            }
            // Get the fingers we want to use
            var fingers = Use.GetFingers();

            // Calculate pinch scale, and make sure it's valid
            var pinchScale = LeanGesture.GetPinchScale(fingers);
            var newScale   = transform.localScale * pinchScale;

            if (newScale.x > _localScale.x * MAX_SCALE || newScale.x < _localScale.x * MIN_SCALE)
            {
                pinchScale = 1f;
            }

            if (pinchScale != 1.0f)
            {
                pinchScale = Mathf.Pow(pinchScale, Sensitivity);

                // Perform the translation if this is a relative scale
                if (Relative == true)
                {
                    var pinchScreenCenter = LeanGesture.GetScreenCenter(fingers);

                    if (transform is RectTransform)
                    {
                        TranslateUI(pinchScale, pinchScreenCenter);
                    }
                    else
                    {
                        Translate(pinchScale, pinchScreenCenter);
                    }
                }

                transform.localScale *= pinchScale;

                remainingScale += transform.localPosition - oldScale;
            }

            // Get t value
            var factor = LeanTouch.GetDampenFactor(Dampening, Time.deltaTime);

            // Dampen remainingDelta
            var newRemainingScale = Vector3.Lerp(remainingScale, Vector3.zero, factor);

            // Shift this transform by the change in delta
            transform.localPosition = oldScale + remainingScale - newRemainingScale;

            // Update remainingDelta with the dampened value
            remainingScale = newRemainingScale;
        }
示例#20
0
 void SpreadSignal()
 {
     if (SignalStrength > minStrength)
     {
         CreateSignal(Vector3.Lerp(transform.up, transform.right, angleLerp));
         CreateSignal(Vector3.Lerp(transform.up, transform.right * -1, angleLerp));
     }
     Destroy(gameObject);
 }
示例#21
0
    private void Move()
    {
        if (Vector3.Distance(transform.position, movePos) < .25f)
        {
            moving = false;
        }

        transform.position = Vector3.Lerp(transform.position, movePos, Time.deltaTime * speed);
    }
示例#22
0
 void CalculatePoints()
 {
     for (int i = 0; i < points.GetLength(0); i++)
     {
         for (int j = 0; j < points.GetLength(1); j++)
         {
             pointsReal[i, j] = Vector3.Lerp(points[i, j], pointsSphere[i, j], Lerp);
         }
     }
 }
示例#23
0
    void Update()
    {
        float distance = Vector3.Distance(player.transform.position, this.transform.position);

        if (distance < 5 && player.riskyJump)
        {
            transform.position = Vector3.Lerp(transform.position, player.transform.position, Time.deltaTime * 10);
        }

        transform.Rotate(0, speed * Time.deltaTime, 0, Space.World);
    }
示例#24
0
        public void Update(float dt)
        {
            if (animTime >= 1)
            {
                return;
            }

            animTime          = Mathf.Min(animTime + (dt / animDur), 1);
            scaler.localScale = Vec3.Lerp(
                scaleStart, Vec3.one, AnimUtil.EaseOut(animTime));
        }
示例#25
0
    // Update is called once per frame
    void FixedUpdate()
    {
        Vector3 targetCamPos = target.position + offset;

        transform.position = Vector3.Lerp(transform.position, targetCamPos, smoothing * Time.deltaTime);

        if (transform.position.y < lowY)
        {
            transform.position = new Vector3(transform.position.x, lowY, transform.position.z);
        }
    }
示例#26
0
        public override void Execute()
        {
            base.Execute();
            parent.transform.position = Vector3.Lerp(parent.transform.position,
                                                     (new Vector3(parent.transform.position.x, endPos, parent.transform.position.z)), 5 * Time.deltaTime);
            if (ai.Target != null)
            {
                parent.transform.LookAt(ai.Target.transform);
            }

            rb.useGravity = false;
        }
示例#27
0
    private void OnRenderObject()
    {
        if (!DebugSubmersion)
        {
            return;
        }

        LineMaterial.SetPass(0);
        GL.PushMatrix();
        GL.Begin(GL.LINES);

        //GL.Color(SubmergLineColor);
        //if (SubmergedPoints.Count > 0)
        //{
        //    for (int i = 0; i < SubmergedPoints.Count; i++)
        //    {
        //        if (i != 0)
        //            GL.Vertex(SubmergedPoints[i]);

        //        GL.Vertex(SubmergedPoints[i]);
        //    }
        //    GL.Vertex(SubmergedPoints[0]);
        //}

        GL.Color(OutlineColor);
        GL.Vertex(CornerVectors[0]);
        GL.Vertex(CornerVectors[1]);
        GL.Vertex(CornerVectors[1]);
        GL.Vertex(CornerVectors[2]);
        GL.Vertex(CornerVectors[2]);
        GL.Vertex(CornerVectors[3]);
        GL.Vertex(CornerVectors[3]);
        GL.Vertex(CornerVectors[0]);



        //GL.Vertex(transform.position);
        //GL.Vertex(transform.position - RawForce * .3f);

        GL.Color(VelocityLineColor);

        GL.Vertex(transform.position);

        var newLine = Vec3.Lerp(_prevVelLine, velocityVector, .1f);

        GL.Vertex(transform.position - newLine * .3f);
        _prevVelLine = velocityVector;
        //GL.Vertex(transform.position);
        //GL.Vertex(transform.TransformPoint(BladeNormal));

        GL.End();
        GL.PopMatrix();
    }
示例#28
0
 private void LateUpdate()
 {
     if (_end)
     {
         return;
     }
     transform.position = Vector3.Lerp(transform.position, _player.transform.position + _offset, 3f * Time.deltaTime);
     if (_shake)
     {
         transform.position += new Vector3(Random.Range(-_intensity, _intensity), Random.Range(-_intensity, _intensity), Random.Range(-_intensity, _intensity));
     }
 }
示例#29
0
    IEnumerator SmoothCameraMove(Vector2Int room, float time)
    {
        //Randomize color
        Vector3 startPos = transform.position;
        float   timer    = 0;

        while (timer < time)
        {
            timer += Time.deltaTime;
            transform.position = Vector3.Lerp(startPos, new Vector3(room.x * roomWidth, room.y * roomHeight, camZ), timer / time);
            yield return(null);
        }
    }
示例#30
0
文件: Letter.cs 项目: Xlebypek/Grid
    /// <summary>
    /// Сама анимация перемещения буквы во время shuffle.
    /// </summary>
    IEnumerator ShuffleAnimation(Vector3 target, string newLetter)
    {
        _layoutElement.ignoreLayout = true;
        Vector3 StartPos = transform.position;

        while (t < animationTime)
        {
            transform.position = Vector3.Lerp(StartPos, target, t / animationTime);
            yield return(null);;
        }
        _layoutElement.ignoreLayout = false;
        Value = newLetter;
    }