예제 #1
0
        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);
        }