public bool SetDest(Vector3 position, bool randomizeLane = false, float initialSpeed = 0f) { Road endRoad; Debug.Assert(startRoad != null); Vector3 modifiedPosition = drawing.roadManager.approxNodeToExistingRoad(position, out endRoad); if (endRoad == null) { return(false); } float?endParam = endRoad.curve.paramOf(modifiedPosition); if (endParam == null) { return(false); } pathOn = drawing.roadManager.findPath(startRoad, startParam, endRoad, endParam.Value); if (pathOn == null) { Debug.LogWarning("Dest not reachable !"); Destroy(gameObject); return(false); } laneOn = randomizeLane ? Random.Range(0, roadOfCurrentSeg.directionalLaneCount(headingOfCurrentSeg)) : 0; VhCtrlOfCurrentSeg.VehicleEnter(this, laneOn); speed = initialSpeed; return(true); }
// 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); } }