예제 #1
0
 public void Abort()
 {
     VhCtrlOfCurrentSeg.VehicleLeave(this, LaneOn);
 }
예제 #2
0
    // Update is called once per frame
    void Update()
    {
        if (pathOn != null)
        {
            float distToTravel;
            if (acceleration < 0f && speed < (-acceleration) * Time.deltaTime)
            {
                distToTravel = speed * speed / (2 * (-acceleration));
            }
            else
            {
                distToTravel = speed * Time.deltaTime + 0.5f * acceleration * Time.deltaTime * Time.deltaTime;
            }
            speed += Time.deltaTime * acceleration;
            speed  = Mathf.Max(0f, speed);

            distTraveledOnSeg += distToTravel;
            bool termination;
            int  nextSeg, nextLane;
            Pair <Road, float> nextInfo = pathOn.travelAlong(currentSeg, currentParam, distToTravel, laneOn, out nextSeg, out nextLane, out termination);

            if (termination)
            {
                VhCtrlOfCurrentSeg.VehicleLeave(this, laneOn);

                stopEvent.Invoke();

                Reset();
                return;
            }

            Road roadOn = nextInfo.First;
            currentParam = nextInfo.Second;

            if (currentSeg != nextSeg)
            {
                VhCtrlOfCurrentSeg.VehicleLeave(this, laneOn);
                distTraveledOnSeg = distToTravel;
                laneOn            = nextLane;
                currentSeg        = nextSeg;

                VhCtrlOfCurrentSeg.VehicleEnter(this, laneOn);
            }

            if (!Algebra.isclose(rightOffset, 0f))
            {
                float lateralAcc = (lateralSpeedMagnitude * lateralSpeedMagnitude > 2 * lateralMaxAcc * Mathf.Abs(rightOffset)) ?
                                   -0.98f * lateralMaxAcc : lateralMaxAcc;

                lateralSpeedMagnitude = Mathf.Max(lateralSpeedMagnitude + lateralAcc * Time.deltaTime, 0f);

                rightOffset = Mathf.Sign(rightOffset) * Mathf.Max(Mathf.Abs(rightOffset) - lateralSpeedMagnitude * Time.deltaTime, 0f);
            }
            else
            {
                lateralSpeedMagnitude = 0f;
            }

            transform.position = roadOn.at(currentParam, usebuff: true) +
                                 roadOn.rightNormal(currentParam, usebuff: true) * (roadOn.getLaneCenterOffset(laneOn, headingOfCurrentSeg) + rightOffset);

            transform.rotation = headingOfCurrentSeg ?
                                 Quaternion.LookRotation(roadOn.frontNormal(currentParam, usebuff: true), roadOn.upNormal(currentParam, usebuff: true)) :
                                 Quaternion.LookRotation(-roadOn.frontNormal(currentParam, usebuff: true), roadOn.upNormal(currentParam, usebuff: true));

            if (rightOffset != 0f)
            {
                if (headingOfCurrentSeg)
                {
                    transform.Rotate(roadOn.upNormal(currentParam, usebuff: true), -Mathf.Sign(rightOffset) * Mathf.Atan(lateralSpeedMagnitude / Mathf.Max(speed, 0.2f)) * Mathf.Rad2Deg);
                }
                else
                {
                    transform.Rotate(roadOn.upNormal(currentParam, usebuff: true), Mathf.Sign(rightOffset) * Mathf.Atan(lateralSpeedMagnitude / Mathf.Max(speed, 0.2f)) * Mathf.Rad2Deg);
                }
            }

            wheelRotation = (wheelRotation + distToTravel / wheeRadius * Mathf.Rad2Deg) % 360;
            /*TODO: calculate wheel radius*/
            transform.GetChild(0).GetChild(1).localRotation     = transform.GetChild(0).GetChild(2).localRotation =
                transform.GetChild(0).GetChild(3).localRotation = transform.GetChild(0).GetChild(4).localRotation =
                    Quaternion.Euler(wheelRotation, 0f, 0f);
        }
    }