private static void SetupVehicle() { EditorHelper.SetUndoGroup("Setup Vehicle"); GameObject selected = Selection.activeGameObject; //Create raycast anchor GameObject anchor = EditorHelper.CreateGameObject("Raycast Anchor", selected.transform); //Add AI scripts VehicleAI veAi = EditorHelper.AddComponent <VehicleAI>(selected); WheelDrive wheelDrive = EditorHelper.AddComponent <WheelDrive>(selected); TrafficSystem ts = GameObject.FindObjectOfType <TrafficSystem>(); //Configure the vehicle AI script with created objects anchor.transform.localPosition = Vector3.zero; anchor.transform.localRotation = Quaternion.Euler(Vector3.zero); veAi.raycastAnchor = anchor.transform; if (ts != null) { veAi.trafficSystem = ts; } //Create layer AutonomousVehicle if it doesn't exist EditorHelper.CreateLayer("AutonomousVehicle"); //Set the tag and layer name selected.tag = "AutonomousVehicle"; EditorHelper.SetLayer(selected, LayerMask.NameToLayer("AutonomousVehicle"), true); }
void Start() { wheelDrive = this.GetComponent <WheelDrive>(); if (trafficSystem == null) { return; } initMaxSpeed = wheelDrive.maxSpeed; SetWaypointVehicleIsOn(); }
void MoveVehicle() { //Default, full acceleration, no break and no steering float acc = 1; float brake = 0; float steering = 0; wheelDrive.maxSpeed = initMaxSpeed; //Calculate if there is a planned turn Transform targetTransform = trafficSystem.segments[currentTarget.segment].waypoints[currentTarget.waypoint].transform; Transform futureTargetTransform = trafficSystem.segments[futureTarget.segment].waypoints[futureTarget.waypoint].transform; Vector3 futureVel = futureTargetTransform.position - targetTransform.position; float futureSteering = Mathf.Clamp(this.transform.InverseTransformDirection(futureVel.normalized).x, -1, 1); //Check if the car has to stop if (vehicleStatus == Status.STOP) { acc = 0; brake = 1; wheelDrive.maxSpeed = Mathf.Min(wheelDrive.maxSpeed / 2f, 5f); } else { //Not full acceleration if have to slow down if (vehicleStatus == Status.SLOW_DOWN) { acc = .3f; brake = 0f; } //If planned to steer, decrease the speed if (futureSteering > .3f || futureSteering < -.3f) { wheelDrive.maxSpeed = Mathf.Min(wheelDrive.maxSpeed, wheelDrive.steeringSpeedMax); } //2. Check if there are obstacles which are detected by the radar float hitDist; GameObject obstacle = GetDetectedObstacles(out hitDist); //Check if we hit something if (obstacle != null) { WheelDrive otherVehicle = null; otherVehicle = obstacle.GetComponent <WheelDrive>(); /////////////////////////////////////////////////////////////// //Differenciate between other vehicles AI and generic obstacles (including controlled vehicle, if any) if (otherVehicle != null) { //Check if it's front vehicle float dotFront = Vector3.Dot(this.transform.forward, otherVehicle.transform.forward); //If detected front vehicle max speed is lower than ego vehicle, then decrease ego vehicle max speed if (otherVehicle.maxSpeed < wheelDrive.maxSpeed && dotFront > .8f) { float ms = Mathf.Max(wheelDrive.GetSpeedMS(otherVehicle.maxSpeed) - .5f, .1f); wheelDrive.maxSpeed = wheelDrive.GetSpeedUnit(ms); } //If the two vehicles are too close, and facing the same direction, brake the ego vehicle if (hitDist < emergencyBrakeThresh && dotFront > .8f) { acc = 0; brake = 1; wheelDrive.maxSpeed = Mathf.Max(wheelDrive.maxSpeed / 2f, wheelDrive.minSpeed); } //If the two vehicles are too close, and not facing same direction, slight make the ego vehicle go backward else if (hitDist < emergencyBrakeThresh && dotFront <= .8f) { acc = -.3f; brake = 0f; wheelDrive.maxSpeed = Mathf.Max(wheelDrive.maxSpeed / 2f, wheelDrive.minSpeed); //Check if the vehicle we are close to is located on the right or left then apply according steering to try to make it move float dotRight = Vector3.Dot(this.transform.forward, otherVehicle.transform.right); //Right if (dotRight > 0.1f) { steering = -.3f; } //Left else if (dotRight < -0.1f) { steering = .3f; } //Middle else { steering = -.7f; } } //If the two vehicles are getting close, slow down their speed else if (hitDist < slowDownThresh) { acc = .5f; brake = 0f; //wheelDrive.maxSpeed = Mathf.Max(wheelDrive.maxSpeed / 1.5f, wheelDrive.minSpeed); } } /////////////////////////////////////////////////////////////////// // Generic obstacles else { //Emergency brake if getting too close if (hitDist < emergencyBrakeThresh) { acc = 0; brake = 1; wheelDrive.maxSpeed = Mathf.Max(wheelDrive.maxSpeed / 2f, wheelDrive.minSpeed); } //Otherwise if getting relatively close decrease speed else if (hitDist < slowDownThresh) { acc = .5f; brake = 0f; } } } //Check if we need to steer to follow path if (acc > 0f) { Vector3 desiredVel = trafficSystem.segments[currentTarget.segment].waypoints[currentTarget.waypoint].transform.position - this.transform.position; steering = Mathf.Clamp(this.transform.InverseTransformDirection(desiredVel.normalized).x, -1f, 1f); } } //Move the car wheelDrive.Move(acc, steering, brake); }