public void TriggerLaneSwerveNearFront() { //This is rough pick, individual NPC car logic that cause danger to player will be handled separately in each NPC car's logic loop var cols = Physics.OverlapSphere(playerVehicleCtrl.carCenter.position, 20f); TrafAIMotor closestCar = null; float minDist = 1000f; foreach (var c in cols) { var carFound = c.GetComponentInParent <TrafAIMotor>(); if (carFound != null) { var dist = Vector3.Distance(playerVehicleCtrl.carCenter.position, carFound.nose.position); if (dist < minDist) { minDist = dist; closestCar = carFound; } } if (closestCar != null) { closestCar.triggerShiftToPlayer = true; closestCar.playerVehicleCtrl = playerVehicleCtrl; } } }
//deregister a specific one from queue public void DeregisterInterest(TrafAIMotor tm) { registered--; if (isIntersection() && intersection.stopSign && intersection.stopQueue.Count > 0) { if (tm == intersection.stopQueue.Peek()) { intersection.stopQueue.Dequeue(); } else { utilQueue.Clear(); var count = intersection.stopQueue.Count; for (int i = 0; i < count; i++) { var item = intersection.stopQueue.Dequeue(); if (item == tm) { continue; } utilQueue.Enqueue(item); } //swap var temp = intersection.stopQueue; intersection.stopQueue = utilQueue; utilQueue = temp; } } }
public void SpawnFixed() { GameObject prefab = fixedPrefabs[Random.Range(0, fixedPrefabs.Length)]; var pMotor = prefab.GetComponent <TrafAIMotor>(); int index = Random.Range(0, pMotor.fixedPath.Count); int id = pMotor.fixedPath[index].id; int subId = pMotor.fixedPath[index].subId; float distance = Random.value * 0.8f + 0.1f; TrafEntry entry = system.GetEntry(id, subId); if (entry == null) { return; } InterpolatedPosition pos = entry.GetInterpolatedPosition(distance); if (!Physics.CheckSphere(pos.position, checkRadius * 3, 1 << LayerMask.NameToLayer("Traffic"))) { GameObject go = GameObject.Instantiate(prefab, pos.position, Quaternion.identity) as GameObject; TrafAIMotor motor = go.GetComponent <TrafAIMotor>(); motor.currentIndex = pos.targetIndex; motor.currentEntry = entry; go.transform.LookAt(entry.waypoints[pos.targetIndex]); motor.system = system; motor.Init(); motor.currentFixedNode = index; } }
public void TriggerHardBrakingNearFront() { var cols = Physics.OverlapSphere(playerVehicleCtrl.carCenter.position, 20.0f); TrafAIMotor closestCar = null; float minDist = 1000f; foreach (var col in cols) { var carFound = col.GetComponentInParent <TrafAIMotor>(); if (carFound != null) { if (Vector3.Dot(playerVehicleCtrl.carCenter.forward, carFound.nose.forward) > 0.7f && Vector3.Dot(playerVehicleCtrl.carCenter.forward, (carFound.nose.position - playerVehicleCtrl.carCenter.position).normalized) > 0.85f) { var dist = Vector3.Distance(playerVehicleCtrl.carCenter.position, carFound.nose.position); if (dist < minDist) { minDist = dist; closestCar = carFound; } } } } if (closestCar != null) { closestCar.StartCoroutine(closestCar.HoldEmergencyHardBrakeState()); //var carAI = closestCar.GetComponent<CarAIController>(); } }
public void Spawn(int id, int subId) { float distance = Random.value * 0.8f + 0.1f; TrafEntry entry = system.GetEntry(id, subId); if (entry == null) { return; } InterpolatedPosition pos = entry.GetInterpolatedPosition(distance); if (!Physics.CheckSphere(pos.position, checkRadius, 1 << LayerMask.NameToLayer("Traffic"))) { GameObject go = GameObject.Instantiate(prefabs[Random.Range(0, prefabs.Length)], pos.position, Quaternion.identity) as GameObject; TrafAIMotor motor = go.GetComponent <TrafAIMotor>(); go.layer = 16; motor.currentIndex = pos.targetIndex; motor.currentEntry = entry; go.transform.LookAt(entry.waypoints[pos.targetIndex]); motor.system = system; motor.Init(); } }
public void RegisterInterest(TrafAIMotor tm) { registered++; if (isIntersection() && intersection.stopSign) { intersection.stopQueue.Enqueue(tm); } }
public void Init() { if (inited) { return; } inited = true; //Debug.Log("Car " + gameObject.name + " was initiated"); allRenderers = GetComponentsInChildren <Renderer>().ToList <Renderer>(); simUpdateRate = SimUpdateRate.Normal; inAccident = false; if (aiMotor == null) { aiMotor = GetComponentInChildren <TrafAIMotor>(); } aiMotor.rb.velocity = Vector3.zero; aiMotor.rb.angularVelocity = Vector3.zero; if (carColliders == null) { carColliders = GetComponentsInChildren <Collider>().ToList <Collider>(); } if (renderers == null) { renderers = GetComponentsInChildren <Renderer>(); } if (brakeLightControls.Count < 1) { brakeLightControls.AddRange(GetComponentsInChildren <BrakeLightController>()); } turnSignalLeft.ForEach(r => SetLight(r, false)); turnSignalRight.ForEach(r => SetLight(r, false)); SetHeadLights(HeadLightState.Off); CheckTimeOfDayEvents(); var interval = TrafPerfManager.performanceCheckInterval; if (TrafPerfManager.optimizeDistantCarRender && TrafPerfManager.optimizeDistantCarPhysics) { InvokeRepeating(nameof(UpdateCarPerformance), Random.Range(0.0f, interval), interval); } else if (TrafPerfManager.optimizeDistantCarRender) { InvokeRepeating(nameof(UpdateCarPerformanceRenderOnly), Random.Range(0.0f, interval), interval); } else if (TrafPerfManager.optimizeDistantCarPhysics) { InvokeRepeating(nameof(UpdateCarPerformancePhysicsOnly), Random.Range(0.0f, interval), interval); } }
void Awake() { fl = transform.Find("Wheels/PivotFL"); fr = transform.Find("Wheels/PivotFR"); rl = transform.Find("Wheels/PivotRL"); rr = transform.Find("Wheels/PivotRR"); motor = GetComponent <TrafAIMotor>(); var rend = GetComponentInChildren <Renderer>(); visPasser = rend.gameObject.AddComponent <OnBecameVisiblePass>(); visPasser.onVisbilityChange = OnVisibilityChange; }
public TrafAIMotor GetLongestWaitCar() { float maxWait = -10000f; TrafAIMotor longestWaitCar = null; foreach (var car in intersection.stopQueue) { if (car.timeWaitingAtStopSign > maxWait) { maxWait = car.timeWaitingAtStopSign; longestWaitCar = car; } } return(longestWaitCar); }
void SetSpeed() { TrafAIMotor motor = GetComponentInParent <TrafAIMotor>(); float speedToShow = Mathf.RoundToInt(rb.velocity.magnitude * 3.6f); TextMeshProUGUI textMeshProUGUI = speed.GetComponent <TextMeshProUGUI>(); if ((motor != null && speedToShow > motor.limiteVelocita && vehicleController.accellInput != 0)) { //speedToShow = 50f; textMeshProUGUI.color = Color.red; } else { textMeshProUGUI.color = Color.white; } speed.GetComponent <TextMeshProUGUI>().text = speedToShow.ToString(); //speed in kph }
void SetTurnSignal() { TrafAIMotor trafAIMotor = transform.parent.gameObject.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) { if (trafAIMotor.hasNextEntry) { //I am waiting at the intersection float dstToTarget = Vector3.Distance(rayCastPos.position, trafAIMotor.nextEntry.waypoints[0]); if (dstToTarget <= 10f && trafAIMotor.currentFixedNode != 1) //currentFixedNode condition is used to exclude the first road which is the only exception which I cannot exclude by the angle { Vector3 nextRoadWayPoint = trafAIMotor.nextEntry.waypoints[trafAIMotor.nextEntry.waypoints.Count - 1]; //I save the last waypoint of the next road Vector3 heading = (nextRoadWayPoint - rayCastPos.position).normalized; //direction from PlayerCar to the the last waypoint of the next road float angle = Vector3.SignedAngle(rayCastPos.forward, heading, Vector3.up); //angle between heading and direction of PlayerCar //foreach (var s in trafAIMotor.nextEntry.waypoints) //{ // GameObject game = new GameObject("Node"); // game.transform.position = s; // SphereCollider sphereCol = game.AddComponent<SphereCollider>(); //} if (angle < -4f) { turnLeftAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.LEFT; } else if (angle > 4f) { turnRightAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.RIGHT; } } } else if ((!trafAIMotor.hasNextEntry && !trafAIMotor.currentEntry.isIntersection()) && Mathf.Abs(vehicleController.steerInput) <= 0.02f) //With the steerInput condition I assure that the turn signal is set off when steer has more or less angle equal to zero { if (lastTurnSignal.Equals(TurnSignal.LEFT)) { turnLeftAnim.SetBool("Turn", false); } else if (lastTurnSignal.Equals(TurnSignal.RIGHT)) { turnRightAnim.SetBool("Turn", false); } } } }
//ANTONELLO public void Init() { if (_pidPars == null) { _pidPars = Resources.Load <PIDPars>("PIDPars_steeringWheel"); } target = currentEntry.waypoints[currentIndex]; CheckHeight(); inited = true; nextRaycast = 0f; CheckHeight(); if (!this.tag.Equals("Player")) { InvokeRepeating("CheckHeight", 0.2f, 0.2f); } vehicleController = GetComponent <VehicleController>(); PIDControllerSterzata = new PID(_pidPars.p_sterzata, _pidPars.i_sterzata, _pidPars.d_sterzata); PIDControllerAccelerazione = new PID(_pidPars.p_accelerazione, _pidPars.i_accelerazione, _pidPars.d_accelerazione); if (raggioDestra != null) { return; } ///Inizializzazione posizione partenza raggio raycast raggioDestra = new GameObject("raggioDestra"); raggioDestra.transform.SetParent(this.transform); raggioDestra.transform.localPosition = new Vector3(raycastOrigin.localPosition.x + 0.92f, raycastOrigin.localPosition.y, raycastOrigin.localPosition.z); raggioDestra.transform.localRotation = Quaternion.identity; raggioDestra.transform.localScale = Vector3.zero; //raggioDestra.position = new Vector3(raggioDestra.position.x + 0.92f, raggioDestra.position.y, raggioDestra.position.z); raggioSinistra = new GameObject("raggioSinistra"); raggioSinistra.transform.SetParent(this.transform); raggioSinistra.transform.localPosition = new Vector3(raycastOrigin.localPosition.x - 0.92f, raycastOrigin.localPosition.y, raycastOrigin.localPosition.z); raggioSinistra.transform.localRotation = Quaternion.identity; raggioSinistra.transform.localScale = Vector3.zero; TrafAIMotor motor = GetComponent <TrafAIMotor>(); motor.system = system; motor.fixedPath = fixedPath; }
public void PutInfrontQueue(TrafAIMotor tm) { DeregisterInterest(tm); utilQueue.Clear(); utilQueue.Enqueue(tm); var count = intersection.stopQueue.Count; for (int i = 0; i < count; i++) { utilQueue.Enqueue(intersection.stopQueue.Dequeue()); } //swap var temp = intersection.stopQueue; intersection.stopQueue = utilQueue; utilQueue = temp; }
void SetTurnSignal() { TrafAIMotor trafAIMotor = transform.root.gameObject.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) { if (trafAIMotor.hasNextEntry && trafAIMotor.nextEntry.identifier != 1088) //this used to exclude the first road which is the only exception which I cannot exclude by the angle { //I am waiting at the intersection float dstToTarget = Vector3.Distance(nose.position, trafAIMotor.nextEntry.waypoints[0]); if (dstToTarget <= 20f) { Vector3 nextRoadWayPoint = trafAIMotor.nextEntry.waypoints[trafAIMotor.nextEntry.waypoints.Count - 1]; //I save the last waypoint of the next road Vector3 heading = (nextRoadWayPoint - nose.position).normalized; //direction from PlayerCar to the the last waypoint of the next road float angle = Vector3.SignedAngle(nose.forward, heading, Vector3.up); //angle between heading and direction of PlayerCar if (angle < -4f) { turnLeftAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.LEFT; } else if (angle > 4f) { turnRightAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.RIGHT; } } } else if ((!trafAIMotor.hasNextEntry && !trafAIMotor.currentEntry.isIntersection()) && Mathf.Abs(trafAIMotor.currentTurn) <= 1f) //With the steerInput condition I assure that the turn signal is set off when steer has more or less angle equal to zero { if (lastTurnSignal.Equals(TurnSignal.LEFT)) { turnLeftAnim.SetBool("Turn", false); } else if (lastTurnSignal.Equals(TurnSignal.RIGHT)) { turnRightAnim.SetBool("Turn", false); } } } }
private void FixedUpdate() { trafAIMotor = playerCar.GetComponent <TrafAIMotor>(); if (trafAIMotor != null && trafAIMotor.velocitaAttuale >= 0.1f) { for (int i = 0; i < 10; i++) { Vector3 point1 = queue.ElementAt(i); float distToPoint1 = Vector3.Distance(point1, trafAIMotor.transform.position); Vector3 heading = (point1 - trafAIMotor.transform.position).normalized; float dot = Vector3.Dot(trafAIMotor.transform.forward, heading); float normalDist = distToPoint1 * dot; if (normalDist <= soglia) { queue.Dequeue(); } } lineRenderer.positionCount = queue.Count; lineRenderer.SetPositions(queue.ToArray()); } }
public GameObject Spawn(TrafEntry entry, bool unseenArea = false, CarAIController sameCar = null) { if (entry == null) { return(null); } float distance = Random.value * 0.8f + 0.1f; InterpolatedPosition pos = entry.GetInterpolatedPosition(distance); if (!Physics.CheckSphere(pos.position, checkRadius, NPCSpawnCheckBitmask)) { GameObject go; if (sameCar != null) //If it is the same car simply reposition it { go = sameCar.gameObject; go.transform.position = pos.position + Vector3.up; } else { go = GameObject.Instantiate(prefabs[Random.Range(0, prefabs.Length)], pos.position + Vector3.up * 3.5f, Quaternion.identity) as GameObject; } go.transform.LookAt(entry.waypoints[pos.targetIndex]); go.transform.SetParent(this.transform); // Put all spawned cars under this object for better organization var carAI = go.GetComponent <CarAIController>(); if (unseenArea) { if (!CheckSilentRespawnEligibility(carAI, Camera.main)) { if (sameCar == null) { DestroyImmediate(go); } return(null); } } else if (sameCar == null) //If it is a new spawn { //assign userid if (trafInfoManager.freeIdPool.Count == 0) { carAI.carID = trafInfoManager.GeneratePseudoRandomUID(); } else { carAI.carID = trafInfoManager.freeIdPool.Dequeue(); } carAI.RandomSelectCarPaintTexture(); ++totalTrafficCarCount; if (trafPerfManager != null) { trafPerfManager.AddAICar(carAI); } } // Init or Reinit AI motor TrafAIMotor motor = go.GetComponent <TrafAIMotor>(); motor.system = system; motor.Init(pos.targetIndex, entry); // Init or Reinit AI Controller carAI.Init(); return(go); } else { return(null); } }
}//this is for dynamic objects public void BoundingCubeLerperScooterSF(CubesAndTags cubesAndTags, Bounds bounds, float obstacleSpeed, Sprite sprite, Vector3 trasl, int i) { Vector3 targetPoint = new Vector3(cubesAndTags.other.transform.position.x, rayCastPos.transform.position.y, cubesAndTags.other.transform.position.z); float dstToTarget = Vector3.Distance(rayCastPos.position, targetPoint); Vector3 dirToTarget = (targetPoint - rayCastPos.transform.position); Renderer cubeRend = cubesAndTags.boundingCube[i].GetComponent <Renderer>(); Canvas canvas = cubesAndTags.infoTag[i].GetComponent <Canvas>(); cubeRend.enabled = true; canvas.enabled = true; UpdateInfoTag(cubesAndTags, bounds, Mathf.RoundToInt(obstacleSpeed * 3.6f).ToString(), sprite, dstToTarget, trasl, i); Animator anim = cubesAndTags.infoTag[i].GetComponent <Animator>(); AudioSource audio = cubesAndTags.boundingCube[i].GetComponent <AudioSource>(); TrafAIMotor trafAIMotor = cubesAndTags.other.transform.root.GetComponent <TrafAIMotor>(); float viewAngle = 5f; if (dstToTarget <= 8f) { viewAngle = 25f; } if (trafAIMotor.hasNextEntry) { if (Vector3.Angle(rayCastPos.TransformDirection(Vector3.forward), dirToTarget) < viewAngle / 2) //the car is in front of me { if (Physics.Raycast(rayCastPos.position, dirToTarget, dstToTarget, mask)) { float distToWarn = RiskAssessmentFormulaD(rigidbody.velocity.magnitude, obstacleSpeed, 0, dstToTarget, ResourceHandler.instance.visualisationVars.systemAccSF); //velocity component of obstacles is null since they are orthogonal to the playerCar if (dstToTarget <= Mathf.Abs(distToWarn)) { float distToWarnEncoded = Mathf.Pow(distToWarn, 2.5f); float dstToTargetEncoded = Mathf.Pow(dstToTarget, 2.5f); bool blink = false; Color32 topColor = linesUtils.ChangeMatByDistance(dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), ref blink, ref cubesAndTags); topColor.a = 0; Color32 bottomColor = linesUtils.ChangeMatByDistance(dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), ref blink, ref cubesAndTags); bottomColor.a = 0x51; cubeRend.material.SetColor("_Color1", topColor); cubeRend.material.SetColor("_Color2", bottomColor); anim.SetFloat("Multiplier", 3.0f); anim.SetBool("BlinkLoop", blink); PlayAudio(audio, dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), cubesAndTags); } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } return; } if (Vector3.Angle(rayCastPos.TransformDirection(Vector3.forward), dirToTarget) < 75f) { if (dstToTarget <= ResourceHandler.instance.visualisationVars.DangerousCarDistToWarn && vehicleController.CurrentSpeed >= 0.1f) { bool blink = false; Color32 topColor = linesUtils.ChangeMatByDistance(dstToTarget / Mathf.Abs(ResourceHandler.instance.visualisationVars.DangerousCarDistToWarn), ref blink, ref cubesAndTags); topColor.a = 0; Color32 bottomColor = linesUtils.ChangeMatByDistance(dstToTarget / Mathf.Abs(ResourceHandler.instance.visualisationVars.DangerousCarDistToWarn), ref blink, ref cubesAndTags); bottomColor.a = 0x51; cubeRend.material.SetColor("_Color1", topColor); cubeRend.material.SetColor("_Color2", bottomColor); anim.SetFloat("Multiplier", 3.0f); anim.SetBool("BlinkLoop", blink); PlayAudio(audio, dstToTarget / ResourceHandler.instance.visualisationVars.DangerousCarDistToWarn, cubesAndTags); } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } //this is for dynamic objects (scooter)
} //this is for static objects. In order to show a smooth vanishing when exiting the gradient state I can do a fading animation and control it by a bool that is set in the gradient if and reset after the animation has been played public void BoundingCubeLerperSF(CubesAndTags cubesAndTags, Bounds bounds, float obstacleSpeed, float acceleration, Sprite sprite, Vector3 trasl, int i) { TrafAIMotor trafAIMotor = gameObject.transform.parent.GetComponent <TrafAIMotor>(); Vector3 targetPoint = new Vector3(cubesAndTags.other.transform.position.x, rayCastPos.transform.position.y, cubesAndTags.other.transform.position.z); Vector3 dirToTarget = (targetPoint - rayCastPos.transform.position); float dstToTarget = Vector3.Distance(rayCastPos.position, targetPoint); Renderer cubeRend = cubesAndTags.boundingCube[i].GetComponent <Renderer>(); Canvas canvas = cubesAndTags.infoTag[i].GetComponent <Canvas>(); Animator anim = cubesAndTags.infoTag[i].GetComponent <Animator>(); AudioSource audio = cubesAndTags.boundingCube[i].GetComponent <AudioSource>(); UpdateInfoTag(cubesAndTags, bounds, Mathf.RoundToInt(obstacleSpeed * 3.6f).ToString(), sprite, dstToTarget, trasl, i); float viewAngle = 5f; if (dstToTarget <= 8f) { viewAngle = 25f; } if (trafAIMotor.hasNextEntry) //If I am waiting at the intersection { float dist = Vector3.Distance(rayCastPos.position, trafAIMotor.currentEntry.waypoints[trafAIMotor.currentEntry.waypoints.Count - 1]); if (dist <= 6.0f) //and I am located near the line that defines the intersection. This second condition is necessary since hasNextEntry is set earlier, not in correspondence with the line of the crossing. { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; return; } } if (Vector3.Angle(rayCastPos.TransformDirection(Vector3.forward), dirToTarget) < viewAngle / 2) //the car is in front of me { if (Physics.Raycast(rayCastPos.position, dirToTarget, dstToTarget, mask)) { float distToWarn = RiskAssessmentFormulaD(rigidbody.velocity.magnitude, obstacleSpeed, 0, dstToTarget, ResourceHandler.instance.visualisationVars.systemAccSF); //velocity component of obstacles is null since they are orthogonal to the playerCar if (dstToTarget <= Mathf.Abs(distToWarn)) { float distToWarnEncoded = Mathf.Pow(distToWarn, 2.5f); float dstToTargetEncoded = Mathf.Pow(dstToTarget, 2.5f); bool blink = false; Color32 topColor = linesUtils.ChangeMatByDistance(dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), ref blink, ref cubesAndTags); topColor.a = 0; Color32 bottomColor = linesUtils.ChangeMatByDistance(dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), ref blink, ref cubesAndTags); bottomColor.a = 0x51; cubeRend.material.SetColor("_Color1", topColor); cubeRend.material.SetColor("_Color2", bottomColor); anim.SetFloat("Multiplier", 3.0f); anim.SetBool("BlinkLoop", blink); PlayAudio(audio, dstToTargetEncoded / Mathf.Abs(distToWarnEncoded), cubesAndTags); } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } else { cubeRend.material.SetColor("_Color1", new Color32(0x00, 0x80, 0xFF, 0x00)); cubeRend.material.SetColor("_Color2", new Color32(0x00, 0x80, 0xFF, 0x51)); anim.SetBool("BlinkLoop", false); cubesAndTags.dangerState = CubesAndTags.DangerState.NONE; } } //this is for dynamic objects
void Awake() { motor = GetComponent <TrafAIMotor>(); carAIController = GetComponent <CarAIController>(); }
void FixedUpdate() { if (motor == null) { if (gameObject.GetComponent <TrafAIMotor>() == null) { return; } motor = gameObject.GetComponent <TrafAIMotor>(); envSelective = transform.Find("colliderEnv").GetComponent <EnvironmentSensingAltUrbanTriggerSelective>(); //DARIO } if (nuovaAuto != null) { autoTraffico.Add(nuovaAuto); nuovaAuto = null; } //Controllo la lista delle auto del traffico eliminado quelle distrutte nella scena List <int> listaIndici = new List <int>(); int contatore = 0; foreach (TrafAIMotor auto in autoTraffico) { if (auto == null) { listaIndici.Add(contatore); } contatore++; } for (int i = listaIndici.Count - 1; i >= 0; i--) { autoTraffico.RemoveAt(listaIndici[i]); } //cONTROLLO AUTO DAVANTI foreach (TrafAIMotor auto in autoTraffico) { bool controlloStessoCurrentEntry = auto.currentEntry.identifier == motor.currentEntry.identifier && auto.currentEntry.subIdentifier == motor.currentEntry.subIdentifier; bool controlloNextEntry = (motor.nextEntry != null && auto.currentEntry.identifier == motor.nextEntry.identifier && auto.currentEntry.subIdentifier == motor.nextEntry.subIdentifier); bool controlloProssimoNode = (auto.currentEntry.identifier == motor.fixedPath[motor.currentFixedNode].id && auto.currentEntry.subIdentifier == motor.fixedPath[motor.currentFixedNode].subId); bool controlloProssimoNode2 = ((motor.currentFixedNode + 1) < motor.fixedPath.Count && auto.currentEntry.identifier == motor.fixedPath[motor.currentFixedNode + 1].id && auto.currentEntry.subIdentifier == motor.fixedPath[motor.currentFixedNode + 1].subId); if (controlloProssimoNode) { Vector3 heading = (motor.system.GetEntry(motor.fixedPath[motor.currentFixedNode].id, 0).waypoints[motor.system.GetEntry(motor.fixedPath[motor.currentFixedNode].id, 0).waypoints.Count - 1] - motor.nose.transform.position).normalized; if ((Mathf.Abs(Vector3.SignedAngle(motor.nose.transform.forward, heading, Vector3.up))) > 30) { //la prossima strada da percorrere non è davanti a me (si tratta di un incrocio a T o a X controlloProssimoNode = false; } } if (controlloProssimoNode2) { Vector3 heading = (motor.system.GetEntry(motor.fixedPath[motor.currentFixedNode + 1].id, 0).waypoints[motor.system.GetEntry(motor.fixedPath[motor.currentFixedNode + 1].id, 0).waypoints.Count - 1] - motor.nose.transform.position).normalized; float angolo = Mathf.Abs(Vector3.SignedAngle(motor.nose.transform.forward, heading, Vector3.up)); if (angolo > 30) { //la prossima strada da percorrere non è davanti a me (si tratta di un incrocio a T o a X controlloProssimoNode2 = false; } } bool controlloStessoStartIncrocio = false; if (auto.currentEntry.identifier > 1000 && (motor.currentEntry.identifier > 1000 || (motor.nextEntry != null && motor.nextEntry.identifier > 1000))) { //entrambe le macchine sono in un'incrocio o si apprestano ad entrarci int id, subId = 0; if (motor.currentEntry.identifier > 1000) { id = motor.currentEntry.identifier; subId = motor.currentEntry.subIdentifier; } else { id = motor.nextEntry.identifier; subId = motor.nextEntry.subIdentifier; } if (auto.system.GetEntry(auto.currentEntry.identifier, auto.currentEntry.subIdentifier).path.start == motor.system.GetEntry(id, subId).path.start) { controlloStessoStartIncrocio = true; } } if (Vector3.Distance(motor.gameObject.transform.position, auto.gameObject.transform.position) < 150f && (controlloStessoCurrentEntry || (!motor.hasStopTarget && (controlloNextEntry || controlloProssimoNode || controlloProssimoNode2 || controlloStessoStartIncrocio)))) { //anche quando hanno lo stesso punto d'ingresso negli incroci if (!autoVisualizzate.Contains(auto.gameObject)) { ///CASO PARTICOLARE -> SCOOTER if (auto.gameObject.CompareTag("TrafficScooter")) { AggiungiBoxLinea(auto.gameObject); StartCoroutine(AttesaRimuoviLinea(auto.gameObject)); } else { //caso normale AggiungiBox(auto.gameObject); } autoVisualizzate.Add(auto.gameObject); } } else { if (autoVisualizzate.Contains(auto.gameObject)) { StartCoroutine(AttesaRimuoviBox(auto.gameObject)); //RimuoviBoxLinea(auto.gameObject); autoVisualizzate.Remove(auto.gameObject); } } } //CONTROLLO INCROCI if (motor.currentEntry.identifier > 1000 || (motor.nextEntry != null && motor.nextEntry.identifier > 1000)) { //sono in un incrocio o sto per entrarci int id, subId = 0; if (motor.currentEntry.identifier > 1000) { id = motor.currentEntry.identifier; subId = motor.currentEntry.subIdentifier; } else { id = motor.nextEntry.identifier; subId = motor.nextEntry.subIdentifier; } int myPathsubId = motor.system.GetEntry(id, subId).path.subId; //Controllo se devo dar precedenza List <int> listaPrecedenze = motor.system.GetEntry(id, subId).path.giveWayTo; if (listaPrecedenze.Count != 0) { //devo dare precedenza a qualcuno //controllo che ci sia qualcuno in quella strada foreach (TrafAIMotor motorTraffico in autoTraffico) { if (motorTraffico.currentEntry.identifier == id || (motorTraffico.nextEntry != null && motorTraffico.nextEntry.identifier == id)) { //la macchina del traffico è nello stesso incrocio di dove sono io //controllo se è lei che deve ricevere precedenza int trafficSubId = 0; if (motorTraffico.currentEntry.identifier == id) { trafficSubId = motorTraffico.currentEntry.subIdentifier; } else { trafficSubId = motorTraffico.nextEntry.subIdentifier; } int trafficPathsubId = motor.system.GetEntry(id, trafficSubId).path.subId; if (listaPrecedenze.Contains(trafficPathsubId)) { //questa macchina deve ricevere precedenza if (!autoIncrocio.Contains(motorTraffico.gameObject)) { //devo visualizzare il box e la linea di navigazione AggiungiBoxLinea(motorTraffico.gameObject); autoIncrocio.Add(motorTraffico.gameObject); } } } } } //controllo se altri devono dare precedenza a me foreach (TrafAIMotor motorTraffico in autoTraffico) { if ((motorTraffico.currentEntry != null && motorTraffico.currentEntry.identifier == id) || (motorTraffico.nextEntry != null && motorTraffico.nextEntry.identifier == id)) { //la macchina del traffico è nello stesso incrocio di dove sono io //controllo se deve darmi precedenza int trafficSubId = 0; if (motorTraffico.currentEntry.identifier == id) { trafficSubId = motorTraffico.currentEntry.subIdentifier; } else { trafficSubId = motorTraffico.nextEntry.subIdentifier; } if (motorTraffico.system.GetEntry(id, trafficSubId).path.giveWayTo.Contains(myPathsubId)) { //deve darmi precedenza if (!autoIncrocio.Contains(motorTraffico.gameObject)) { //devo visualizzare il box e la linea di navigazione AggiungiBoxLinea(motorTraffico.gameObject); autoIncrocio.Add(motorTraffico.gameObject); } } } } } else { //sono uscito dall'incrocio if (autoIncrocio.Count != 0) { foreach (GameObject autoTraffico in autoIncrocio) { if (autoTraffico != null) { //devo rimuovere il box e la linea di navigazione StartCoroutine(AttesaRimuoviBox(autoTraffico)); } } autoIncrocio.RemoveRange(0, autoIncrocio.Count - 1); //elimina tutti glie elementi } } }
} //NavigationLine of PlayerCar and TrafficCar in PCH public void DrawLine(GameObject car) { List <Vector3> initialList = new List <Vector3>(); TrafAIMotor trafAIMotor = car.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) { bool hasNextEntryOk; TrafEntry nextEntryOk; int index; if (car.CompareTag("Player")) { //tesla hasNextEntryOk = trafAIMotor.hasNextEntry50; nextEntryOk = trafAIMotor.nextEntry50; if (trafAIMotor.hasNextEntry) { index = trafAIMotor.currentFixedNode; } else { index = trafAIMotor.currentFixedNode + 1; } } else { hasNextEntryOk = trafAIMotor.hasNextEntry; nextEntryOk = trafAIMotor.nextEntry; index = trafAIMotor.currentFixedNode; } if (hasNextEntryOk) { //I am waiting at the intersection TrafEntry nextRoadWaypoints = trafAIMotor.system.GetEntry(trafAIMotor.fixedPath[index].id, trafAIMotor.fixedPath[index].subId); //points of the next piece of road if (nextRoadWaypoints.waypoints.Count == 2) { LinePoints.Add(car.transform.position); List <Vector3> smoothedPoints = ChaikinCurve(nextEntryOk.waypoints.ToArray(), 4); //intersection points initialList.AddRange(smoothedPoints); initialList.Add(nextRoadWaypoints.waypoints[nextRoadWaypoints.waypoints.Count - 1]); } else if (nextRoadWaypoints.waypoints.Count > 2) { List <Vector3> smoothedPoints = new List <Vector3>(); smoothedPoints.Add(car.transform.position); smoothedPoints.Add(nextEntryOk.waypoints[0]); //intersection points smoothedPoints.AddRange(nextRoadWaypoints.waypoints); initialList.AddRange(ChaikinCurve(smoothedPoints.ToArray(), 2)); } } else if (!hasNextEntryOk && trafAIMotor.currentEntry.isIntersection()) { //I am crossing the intersection TrafEntry nextRoadWaypoints = trafAIMotor.system.GetEntry(trafAIMotor.fixedPath[trafAIMotor.currentFixedNode].id, trafAIMotor.fixedPath[trafAIMotor.currentFixedNode].subId); //points of the next piece of road if (nextRoadWaypoints.waypoints.Count == 2) { LinePoints.Add(car.transform.position); List <Vector3> smoothedPoints = ChaikinCurve(trafAIMotor.currentEntry.waypoints.ToArray(), 4); int nearest = CalculatePointDistance(smoothedPoints, car); Vector3 heading = smoothedPoints[nearest] - car.transform.position; if (Vector3.Dot(heading, car.transform.forward) > 0) { for (int i = nearest; i < smoothedPoints.Count; i++) { initialList.Add(smoothedPoints[i]); } } else { for (int i = nearest + 1; i < smoothedPoints.Count; i++) { initialList.Add(smoothedPoints[i]); } } initialList.Add(nextRoadWaypoints.waypoints[nextRoadWaypoints.waypoints.Count - 1]); } else if (nextRoadWaypoints.waypoints.Count > 2) //if more than 2, smooth and add all of them { List <Vector3> smoothedPoints = new List <Vector3>(); smoothedPoints.Add(car.transform.position); smoothedPoints.Add(trafAIMotor.currentEntry.waypoints[0]); //intersection points smoothedPoints.AddRange(nextRoadWaypoints.waypoints); smoothedPoints = ChaikinCurve(smoothedPoints.ToArray(), 2); int nearest = CalculatePointDistance(smoothedPoints, car); Vector3 heading = smoothedPoints[nearest] - car.transform.position; if (Vector3.Dot(heading, car.transform.forward) > 0) { for (int i = nearest; i < smoothedPoints.Count; i++) { initialList.Add(smoothedPoints[i]); } } else { for (int i = nearest + 1; i < smoothedPoints.Count; i++) { initialList.Add(smoothedPoints[i]); } } //initialList.AddRange(smoothedPoints); } } else if (!hasNextEntryOk && !trafAIMotor.currentEntry.isIntersection()) {//I am on curves or on straight lines LinePoints.Add(car.transform.position); if (trafAIMotor.currentEntry.waypoints.Count == 2) { initialList.Add(trafAIMotor.currentEntry.waypoints[trafAIMotor.currentEntry.waypoints.Count - 1]); } else if (trafAIMotor.currentEntry.waypoints.Count > 2) { List <Vector3> pointsToSmooth = ChaikinCurve(trafAIMotor.currentEntry.waypoints.ToArray(), 2); int nearest = CalculatePointDistance(pointsToSmooth, car); Vector3 heading = pointsToSmooth[nearest] - car.transform.position; if (Vector3.Dot(heading, car.transform.forward) > 0) { for (int i = nearest; i < pointsToSmooth.Count; i++) { initialList.Add(pointsToSmooth[i]); } } else { for (int i = nearest + 1; i < pointsToSmooth.Count; i++) { initialList.Add(pointsToSmooth[i]); } } } } foreach (var p in initialList) { Vector3 currentSpot = p; RaycastHit hit; Physics.Raycast(currentSpot + Vector3.up * 5, -Vector3.up, out hit, 100f, (1 << LayerMask.NameToLayer("EnvironmentProp"))); //the layer is EnvironmentProp and not Roads since there is a hidden mesh before roads! Vector3 correctedPoint = new Vector3(currentSpot.x, hit.point.y + 0.05f, currentSpot.z); LinePoints.Add(correctedPoint); } lineRenderer.positionCount = LinePoints.Count; lineRenderer.SetPositions(LinePoints.ToArray()); LinePoints.Clear(); } } //NavigationLine of PlayerCar and TrafficCar in SF
void EnvironmentDetect() { List <CubesAndTags> objectsList = new List <CubesAndTags>(IDsAndGos.Values); for (int i = 0; i < objectsList.Count; i++) { if (objectsList[i].other != null) { float dist = CalculateDistance(rayCastPos.position, objectsList[i].other.transform.position); //this distance does not include bounds since it cannot always be precomputed, for example, this is the case of moving objects switch (objectsList[i].other.gameObject.layer) { case 17: //Signage { float dotProduct = Vector3.Dot(gameObject.transform.TransformDirection(Vector3.forward), objectsList[i].other.transform.TransformDirection(Vector3.up)); Animator anim = objectsList[i].infoTag[0].GetComponent <Animator>(); if (dotProduct >= -1 && dotProduct <= -0.707f) { if ((objectsList[i].other.transform.name.Equals("StopSign") || objectsList[i].other.transform.name.Equals("RoadWork") || objectsList[i].other.transform.name.Equals("Speed_Limit_40") || objectsList[i].other.transform.name.Equals("Speed_Limit_50") || objectsList[i].other.transform.name.Equals("End_Limit_40") || objectsList[i].other.transform.name.Equals("Speed_Limit_60")) && dist <= 40) { Bounds bounds = objectsList[i].bounds[0]; int spriteIndex = CSVSignDictionary[objectsList[i].other.name]; objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = true; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = true; RiskAssessmentSelective.UpdateInfoTag(objectsList[i], bounds, "", ResourceHandler.instance.sprites[spriteIndex], dist, Vector3.zero, 0); anim.SetBool("Blink", true); float dotproduct2 = Vector3.Dot(gameObject.transform.TransformDirection(Vector3.forward), objectsList[i].other.transform.position - transform.position); //play audio only if sign is in front of me if (dotproduct2 > 0) { objectsList[i].infoTag[0].GetComponent <PlaySignSignal>().PlayAudio(); //DARIO } } else { objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = false; anim.SetBool("Blink", false); } } else { if (objectsList[i].other.transform.name.Equals("StopSign") || objectsList[i].other.transform.name.Equals("RoadWork") || objectsList[i].other.transform.name.Equals("Speed_Limit_40") || objectsList[i].other.transform.name.Equals("Speed_Limit_50") || objectsList[i].other.transform.name.Equals("End_Limit_40") || objectsList[i].other.transform.name.Equals("Speed_Limit_60")) { anim.SetBool("Blink", false); } } } break; case 12: { Bounds bounds = objectsList[i].bounds[0]; Sprite sprite = objectsList[i].other.GetComponent <Image>().sprite; if (objectsList[i].other.CompareTag("Obstacle")) { RiskAssessmentSelective.BoundingCubeLerperObstacleDefSF(objectsList[i], bounds, CalculateObstacleSpeed(objectsList[i]), 0, sprite, Vector3.zero, 0); } else if (objectsList[i].other.CompareTag("Stop")) { RiskAssessmentSelective.BoundingCubeLerperManSF(objectsList[i], bounds, CalculateObstacleSpeed(objectsList[i]), 0, sprite, Vector3.zero, 0); } } break; case 8: { Debug.DrawLine(objectsList[i].other.transform.position, rayCastPos.position, Color.green); Bounds bounds = objectsList[i].bounds[0]; TrafAIMotor trafAIMotor = objectsList[i].other.transform.root.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) { float speed = trafAIMotor.currentSpeed; float acceleration = trafAIMotor.accelerazione; Sprite sprite = objectsList[i].other.GetComponent <Image>().sprite; if (objectsList[i].other.transform.root.CompareTag("TrafficCar")) { RiskAssessmentSelective.BoundingCubeLerperSF(objectsList[i], bounds, speed, acceleration, sprite, Vector3.zero, 0); } else { RiskAssessmentSelective.BoundingCubeLerperScooterSF(objectsList[i], bounds, speed, sprite, Vector3.zero, 0); } } } break; case 18: //Roads { if (objectsList[i].bounds.Count == 3) { float dotProduct = Vector3.Dot(gameObject.transform.TransformDirection(Vector3.forward), objectsList[i].other.transform.TransformDirection(Vector3.right)); if (dotProduct >= -1 && dotProduct <= -0.707f) { TrafAIMotor trafAIMotor = transform.root.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) //Among the various potential trafficLights which can be traced by OnTriggerEnter I am sure by this test that I Am considering the next one and not the others { if (trafAIMotor.nextEntry50 != null) { trafLight = trafAIMotor.nextEntry50.light; } if (trafLight != null && trafLight.gameObject.GetInstanceID().Equals(objectsList[i].other.gameObject.GetInstanceID())) { Transform Panel = objectsList[i].infoTag[0].transform.GetChild(0); Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().fontSize = 110; TrafLightState currentState = trafLight.State; Animator anim = objectsList[i].infoTag[0].GetComponent <Animator>(); if (currentState.Equals(TrafLightState.GREEN)) { Panel.transform.GetChild(3).GetComponent <Image>().sprite = ResourceHandler.instance.sprites[30]; Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().text = "GO"; Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().color = new Color32(0x3B, 0xAA, 0x34, 0xFF); anim.SetInteger("trafLightState", (int)TrafLightState.GREEN); } else if (currentState.Equals(TrafLightState.YELLOW)) { Panel.transform.GetChild(3).GetComponent <Image>().sprite = ResourceHandler.instance.sprites[31]; Vector3 offset = trafLight.transform.position - rayCastPos.position; float mag = offset.sqrMagnitude; if (mag >= 1600 || trafAIMotor.hasStopTarget) //40m { Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().text = "STOP"; } //else if () //{ // Panel.transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "STOP"; //} else { Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().text = "GO"; } Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().color = new Color32(0xFE, 0xED, 0x01, 0xFF); anim.SetInteger("trafLightState", (int)TrafLightState.YELLOW); } else { Panel.transform.GetChild(3).GetComponent <Image>().sprite = ResourceHandler.instance.sprites[32]; Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().text = "STOP"; Panel.transform.GetChild(2).GetComponent <TextMeshProUGUI>().color = new Color32(0xE3, 0x07, 0x13, 0xFF); anim.SetInteger("trafLightState", (int)TrafLightState.RED); } //IDsAndGos[other.gameObject.GetInstanceID()].infoTag[i].transform.rotation = Quaternion.Euler(0f, 90f, 0f) * IDsAndGos[other.gameObject.GetInstanceID()].boundingCube[0].transform.rotation; float infoTagOffset = Vector3.Distance(objectsList[i].boundingCube[0].transform.position, objectsList[i].boundingCube[1].transform.position); objectsList[i].infoTag[0].transform.position = objectsList[i].boundingCube[0].transform.position + objectsList[i].infoTag[0].transform.TransformDirection(-Vector3.right.x * (infoTagOffset / 2), -Vector3.up.y * 1.5f, -Vector3.forward.z); float distMax = 150f; float distMin = 5.5f; float scaleMax = (infoTagStartScale.x * distMax) / distMin; float offset2 = Vector3.Distance(objectsList[i].infoTag[0].transform.position, driverCam.transform.position); float newScale = infoTagResize.Evaluate(offset2 / distMax) * scaleMax; objectsList[i].infoTag[0].transform.localScale = new Vector3(newScale, newScale, newScale); objectsList[i].infoTag[0].transform.LookAt((2 * objectsList[i].infoTag[0].transform.position - driverCam.transform.position)); objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = objectsList[i].boundingCube[1].GetComponent <Renderer>().enabled = true; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = true; } else { objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = false; objectsList[i].boundingCube[1].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[1].GetComponent <Canvas>().enabled = false; } } else { objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = false; objectsList[i].boundingCube[1].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[1].GetComponent <Canvas>().enabled = false; } } else { objectsList[i].boundingCube[0].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[0].GetComponent <Canvas>().enabled = false; objectsList[i].boundingCube[1].GetComponent <Renderer>().enabled = false; objectsList[i].infoTag[1].GetComponent <Canvas>().enabled = false; } Bounds boundsPost = objectsList[i].bounds[2]; Sprite sprite = objectsList[i].other.GetComponent <Image>().sprite; RiskAssessmentSelective.BoundingCubeLerperSF(objectsList[i], boundsPost, sprite, ReturnTrasl(boundsPost, objectsList[i].other), 2); } else { Bounds boundsPost = objectsList[i].bounds[0]; Sprite sprite = objectsList[i].other.GetComponent <Image>().sprite; RiskAssessmentSelective.BoundingCubeLerperSF(objectsList[i], boundsPost, sprite, ReturnTrasl(boundsPost, objectsList[i].other), 0); } } break; } } } }
void Guida() { if (!inited) { return; } if (inchiodata) { inchioda(); return; } if (evitare) { evita(); return; } if (this.tag.Equals("Player")) { velocitaAttuale = GetComponent <Rigidbody>().velocity.magnitude; } else { velocitaAttuale = currentSpeed; } accelerazione = (velocitaAttuale - velocitaPrecedente) / Time.deltaTime; velocitaPrecedente = velocitaAttuale; TrafAIMotor motor = GetComponent <TrafAIMotor>(); motor.currentSpeed = currentSpeed; motor.hasStopTarget = hasStopTarget; motor.frenata = frenata; motor.luceStop = luceStop; motor.hasNextEntry = hasNextEntry; motor.currentEntry = currentEntry; motor.nextEntry = nextEntry; if (!currentEntry.isIntersection() && currentIndex > 0 && !hasNextEntry) { if (Vector3.Distance(nose.transform.position, currentEntry.waypoints[currentEntry.waypoints.Count - 1]) <= 60f && this.tag.Equals("Player")) //piu è alto e piu inizia prima la valutazione dell'intersezione (es. semaforo) { if (semaforo != currentEntry.identifier) { Semaforo = "" + currentEntry.identifier; //Setto la proprietà quando inizio a valutare il semaforo } } //last waypoint in this entry, grab the next path when we are in range //ANTONELLO //if(Vector3.Distance(nose.transform.position, currentEntry.waypoints[currentEntry.waypoints.Count - 1]) <= giveWayRegisterDistance) if (Vector3.Distance(nose.transform.position, currentEntry.waypoints[currentEntry.waypoints.Count - 1]) <= 40f) //era a 20 { var node = system.roadGraph.GetNode(currentEntry.identifier, currentEntry.subIdentifier); RoadGraphEdge newNode; if (fixedRoute) { if (++currentFixedNode >= fixedPath.Count) { currentFixedNode = 0; } newNode = system.FindJoiningIntersection(node, fixedPath[currentFixedNode]); } else { newNode = node.SelectRandom(); } if (newNode == null) { Debug.Log("no edges on " + currentEntry.identifier + "_" + currentEntry.subIdentifier); //ANTONELLO if (!this.tag.Equals("Player")) { Destroy(gameObject); } else { Property = "9999"; inchioda(); return; } inited = false; return; } nextEntry = system.GetEntry(newNode.id, newNode.subId); nextTarget = nextEntry.waypoints[0]; hasNextEntry = true; nextEntry.RegisterInterest(gameObject.GetComponent <TrafAIMotor>()); //see if we need to slow down for this intersection intersectionCornerSpeed = Mathf.Clamp(1 - Vector3.Angle(nextEntry.path.start.transform.forward, nextEntry.path.end.transform.forward) / 90f, 0.4f, 1f); } } if (hasNextEntry && !inizioValutazioneSemaforo && Vector3.Distance(nose.transform.position, nextTarget) <= 30f) { inizioValutazioneSemaforo = true; } float distanzaWaypointFramePrecedente = distanzaWaypoint; distanzaWaypoint = Vector3.Distance(nose.transform.position, target); //check if we have reached the target waypoint if (distanzaWaypoint <= waypointThreshold)// && !hasStopTarget && !hasGiveWayTarget) { distanzaWaypoint = 0; modificaTarget(false); //Debug.Log("Target = " + target.x + " " + target.y + " " + target.z); numeroWaypointSaltati = 0; } else { if (distanzaWaypointFramePrecedente != 0 && (distanzaWaypoint - distanzaWaypointFramePrecedente) > 0) { contatore++; if (contatore >= 3) { //abbiamo saltato il waypoint if ((numeroWaypointSaltati++) >= 7) { Destroy(gameObject); } Debug.Log("waypoint saltato"); distanzaWaypoint = 0; contatore = 0; modificaTarget(true); //Debug.Log("Target = " + target.x + " " + target.y + " " + target.z); //hasStopTarget = false; //hasGiveWayTarget = false; } } else { contatore = 0; } } Debug.DrawLine(this.transform.position, target); //SteerCar(); if (hasNextEntry && inizioValutazioneSemaforo && nextEntry.isIntersection() && nextEntry.intersection.stopSign && !autoScorretta) { if (stopEnd == 0f) { hasStopTarget = true; velocitaInizialeFrenata = velocitaAttuale; stopTarget = nextTarget; calcolaDistanzaIniziale(); stopEnd = Time.time + stopLength; } else if (Time.time > stopEnd) { if (nextEntry.intersection.stopQueue.Peek() == this) { hasGiveWayTarget = false; hasStopTarget = false; stopEnd = 0f; float distanza = Vector3.Distance(this.transform.position, stopTarget); if (distanza < 10f) { //evita che quando ci fermiamo a uno stop (un pochino prima dello stopTarget), riparte e si riferma allo stopTarget effettivo //nextEntry.intersection.stopSign = false; currentEntry = nextEntry; nextEntry = null; hasNextEntry = false; inizioValutazioneSemaforo = false; } } } } if (hasNextEntry && !hasGiveWayTarget && inizioValutazioneSemaforo && nextEntry.isIntersection() && !nextEntry.intersection.stopSign) { //check next entry for stop needed if (nextEntry.MustGiveWay()) { hasGiveWayTarget = true; velocitaInizialeFrenata = velocitaAttuale; stopTarget = nextTarget; calcolaDistanzaIniziale(); } else { hasGiveWayTarget = false; } } else { if (hasGiveWayTarget && !nextEntry.MustGiveWay()) { hasGiveWayTarget = false; } } if (!hasGiveWayTarget && hasNextEntry && inizioValutazioneSemaforo && nextEntry.light != null) { if (!hasStopTarget && nextEntry.light.State == TrafLightState.RED) { //light is red, stop here //ANTONELLO if (!autoScorretta) { hasStopTarget = true; velocitaInizialeFrenata = velocitaAttuale; stopTarget = nextTarget; calcolaDistanzaIniziale(); } //else autoScorretta = true, non rispetta i semafori rossi e passacomunque } else if (hasStopTarget && nextEntry.light.State == TrafLightState.GREEN) { //green light, go! //ANTONELLO hasStopTarget = false; } else if (!hasStopTarget && nextEntry.light.State == TrafLightState.YELLOW) { //yellow, stop if we aren't zooming on through //TODO: carry on if we are too fast/close if (Vector3.Distance(nextTarget, nose.transform.position) > yellowLightGoDistance) { //ANTONELLO hasStopTarget = true; velocitaInizialeFrenata = velocitaAttuale; stopTarget = nextTarget; calcolaDistanzaIniziale(); } //altrimenti non riesco a fermarmi, continuo } } float targetSpeed = maxSpeed; //float targetSpeed = Mathf.MoveTowards(currentSpeed, maxSpeed, 100f * Time.deltaTime); //lancio il raggio per vedere cosa ho davanti if (Time.time > nextRaycast) { hitInfo = new RaycastHit(); somethingInFront = CheckFrontBlocked(out hitInfo); nextRaycast = NextRaycastTime(); } if (somethingInFront) { if (hitInfo.collider.gameObject.tag.Equals("Player")) { currentSpeed = 0; return; } } if (frenata) { //ANTONELLO //se ho come target quello di fermarmi, diminuisco la velocità proporzionalmente fino al punto in cui devo fermarmi Vector3 vettoreDifferenza = frenataTarget - transform.position; float distanzaCorrente = 0; if (Math.Abs(vettoreDifferenza.x) > Math.Abs(vettoreDifferenza.z)) { distanzaCorrente = Math.Abs(vettoreDifferenza.x); } else { distanzaCorrente = Math.Abs(vettoreDifferenza.z); } if (this.tag.Equals("Player")) { distanzaCorrente -= 5f; } else { distanzaCorrente -= 6f; } Debug.DrawLine(frenataTarget, transform.position); //if (velocitaInizialeFrenata >= 6f) //{ targetSpeed = velocitaInizialeFrenata * distanzaCorrente / distanzaInizialeInchiodata; /*} else * { * targetSpeed = 6f * distanzaCorrente / distanzaInizialeInchiodata; * }*/ if (targetSpeed <= _pidPars.sogliaFermata) { targetSpeed = 0; //Debug.Log("target < 2"); } //else //Debug.Log("distanza Iniziale Inchiodata = " + distanzaInizialeInchiodata + "; distanzaCorrente = " + distanzaCorrente + "; targetSpeed: " + targetSpeed); } if (!frenata && !autoDavantiFrenata && (hasStopTarget || hasGiveWayTarget)) { /*Vector3 targetVec = (stopTarget - nose.transform.position); * * float stopSpeed = Mathf.Clamp(targetVec.magnitude * (Vector3.Dot(targetVec, nose.transform.forward) > 0 ? 1f : 0f) / 3f, 0f, maxSpeed); * if(stopSpeed < 0.24f) * stopSpeed = 0f; * * targetSpeed = Mathf.Min(targetSpeed, stopSpeed); * //Debug.Log("hasStopTarget true; targetSpeed: " + targetSpeed);*/ //ANTONELLO //se ho come target quello di fermarmi, diminuisco la velocità proporzionalmente fino al punto in cui devo fermarmi Vector3 vettoreDifferenza = stopTarget - transform.position; float distanzaCorrente = 0; if (Math.Abs(vettoreDifferenza.x) > Math.Abs(vettoreDifferenza.z)) { distanzaCorrente = Math.Abs(vettoreDifferenza.x); } else { distanzaCorrente = Math.Abs(vettoreDifferenza.z); } distanzaCorrente -= 2f; Debug.DrawLine(stopTarget, transform.position); targetSpeed = velocitaInizialeFrenata * distanzaCorrente / distanzaIniziale; /*if (velocitaInizialeFrenata >= 6f) * { * targetSpeed = velocitaInizialeFrenata * distanzaCorrente / distanzaIniziale; * } * else * { * targetSpeed = 6f * distanzaCorrente / distanzaIniziale; * }*/ if (targetSpeed <= _pidPars.sogliaFermata) { targetSpeed = 0; //Debug.Log("target < 2"); } //else //Debug.Log("distanza Iniziale = " + distanzaIniziale + "; distanzaCorrente = " + distanzaCorrente + "; targetSpeed: " + targetSpeed); } //slow down if we need to turn //if(currentEntry.isIntersection() || hasNextEntry) //ANTONELLO //if ((currentEntry.isIntersection() || hasNextEntry) && !hasStopTarget && !frenata) if ((currentEntry.isIntersection() || inizioValutazioneSemaforo) && !hasStopTarget && !hasGiveWayTarget && !frenata) { float min = 4; if (targetSpeed <= 4) { min = targetSpeed; } targetSpeed = Mathf.Clamp(targetSpeed * intersectionCornerSpeed, min, maxSpeed); /*targetSpeed = Mathf.MoveTowards(targetSpeed, targetSpeed * intersectionCornerSpeed, Time.fixedDeltaTime * 5f); * if (this.tag.Equals("Player")) * { * Debug.Log("IntersectionCornerSpeed: " + intersectionCornerSpeed + "; targetSpeed: " + targetSpeed); * }*/ } else { //DA TESTARE - ANTONELLO if (currentTurn > 5f || currentTurn < -5f) { //targetSpeed = targetSpeed * Mathf.Clamp(1 - (currentTurn / maxTurn), 0.1f, 1f); targetSpeed = targetSpeed * Mathf.Clamp(1 - (Math.Abs(currentTurn) / maxTurn), 0.2f, 1f); } } float targetSpeedIniziale = targetSpeed; if (targetSpeed > currentSpeed) { float distanzaCorrente = 0; if (hasStopTarget || hasGiveWayTarget) { Vector3 vettoreDifferenza = stopTarget - transform.position; if (Math.Abs(vettoreDifferenza.x) > Math.Abs(vettoreDifferenza.z)) { distanzaCorrente = Math.Abs(vettoreDifferenza.x); } else { distanzaCorrente = Math.Abs(vettoreDifferenza.z); } } //Debug.Log("distanza corrente ripartenza: " + distanzaCorrente + "; targetSpee:" +targetSpeed); //if ((targetSpeed - currentSpeed) < 1 && (hasStopTarget || frenata) && distanzaCorrente < 3f) if ((hasStopTarget || hasGiveWayTarget) && distanzaCorrente < 6f) { //fa si che quando ci fermiamo allo stop o per via di una inchiodata la macchina rimanga ferma //currentSpeed = 0; } else { //currentSpeed += Mathf.Min(maxAccell * Time.deltaTime, targetSpeed - currentSpeed); currentSpeed = targetSpeed; } //currentSpeed = Mathf.MoveTowards(currentSpeed, targetSpeed, Time.fixedDeltaTime * _pidPars.velocitaFrenata); } else { //ANTONELLO if (hasStopTarget || hasGiveWayTarget || frenata || autoDavanti || autoDavantiFrenata) { if (targetSpeed > currentSpeed) { //serve questa condizione perchè evita di accelerare quando sono in fase di fermata targetSpeed = currentSpeed; } //currentSpeed = targetSpeed; } else { //targetSpeed -= Mathf.Min(maxBrake * Time.deltaTime, currentSpeed - targetSpeed); //Per fare in modo che arriva a targetSpeed dalla velocità corrente non troppo immediatamente targetSpeed = Mathf.MoveTowards(currentSpeed, targetSpeed, Time.fixedDeltaTime * _pidPars.velocitaFrenata); } if (targetSpeed < _pidPars.sogliaFermata) { currentSpeed = 0; } else { currentSpeed = targetSpeed; } //Debug.Log("CurrentSpeed: " + currentSpeed); //if (this.tag.Equals("Player")) //{ // Debug.Log("TargetSpeedIniziale: " + targetSpeedIniziale + "; currentSpeed impsotato: " + currentSpeed); //} } controllaAccensioneLuceStop(targetSpeedIniziale); }
//ANTONELLO private void guidaAutomaticaSF() { //Vector3 tempPos = transform.position; int id = Random.Range(0, maxIdent); int subId = Random.Range(0, maxSub); //float distance = Random.value * 0.8f + 0.1f; GameObject go = ottieniRiferimentoPlayer(); TrackController trackController = TrackController.Instance; TrafEntry entry = trackController.GetCurrentTrafEntry(); //-> ottengo la entry corrente //TrafEntry entryOk = null; //lo scopo della funziona calcolaDistanza è settare la variabile distance che farà si che verrà settato correttamente il waypoint target float distance = calcolaDistanza(entry, go); //entry = system.GetEntry(id, subId); //-> serve a ottenere la entry di un determinato punto, bisogna indicare il giusto id e subid if (entry == null) { Debug.Log("Entry = null"); return; } InterpolatedPosition pos = entry.GetInterpolatedPosition(distance); if (!Physics.CheckSphere(pos.position, checkRadius, 1 << LayerMask.NameToLayer("Traffic"))) { GameObject nose = new GameObject("nose"); nose.transform.SetParent(go.transform); nose.transform.localPosition = new Vector3(0, 0.5f, 2f); nose.transform.localRotation = Quaternion.identity; nose.transform.localScale = new Vector3(2f, 2f, 2f); TrafAIMotor motor = go.AddComponent <TrafAIMotor>(); GameObject colliderOstacoli = new GameObject("colliderOstacoli"); colliderOstacoli.transform.SetParent(go.transform); BoxCollider boxColliderOstacoli = colliderOstacoli.AddComponent <BoxCollider>(); boxColliderOstacoli.isTrigger = true; colliderOstacoli.transform.localPosition = new Vector3(0f, 0.65f, 7f); colliderOstacoli.transform.localScale = new Vector3(1f, 1f, 1f); colliderOstacoli.transform.localRotation = Quaternion.identity; boxColliderOstacoli.size = new Vector3(3f, 0.75f, 10f); TrafAIMotor.GestoreCollisioni gestore = colliderOstacoli.AddComponent <TrafAIMotor.GestoreCollisioni>(); gestore.setMotor(motor); //L'ISTRUZIONE SOTTO FA TELETRASPORTARE L'AUTO NELLA POSIZIONE pos.position //go.transform.position = pos.position; //go.AddComponent<TrafWheels>(); motor.currentIndex = pos.targetIndex; motor.currentEntry = entry; //L'istruzione sotto ruota la macchina in direzione del waypoint target //go.transform.LookAt(entry.waypoints[pos.targetIndex]); motor.system = system; motor.nose = nose; motor.raycastOrigin = nose.transform; motor.targetHeight = 0f; motor.waypointThreshold = 3f; guidaAutomatica = true; /*motor.fixedRoute = true; * * //RoadGraphEdge edge = new RoadGraphEdge(); * //edge.id = 5; edge.subId = 0; * RoadGraphEdge edge1 = new RoadGraphEdge(); * edge1.id = 1003; edge1.subId = 4; * RoadGraphEdge edge2 = new RoadGraphEdge(); * edge2.id = 3; edge2.subId = 1; * //RoadGraphEdge edge3 = new RoadGraphEdge(); * //edge3.id = 4; edge3.subId = 3; * * List<RoadGraphEdge> listaEdge = new List<RoadGraphEdge>(); * //listaEdge.Add(edge); * listaEdge.Add(edge1); * listaEdge.Add(edge2); * //listaEdge.Add(edge3); * motor.fixedPath = listaEdge;*/ motor.Init(); } else { guidaAutomaticaSF(); //è una ricorsione, fa si che si ripete la funzione finchè tutto vada bene } }
void SetTurnSignal() { TrafAIMotor trafAIMotor = transform.parent.gameObject.GetComponent <TrafAIMotor>(); if (trafAIMotor != null) { if (trafAIMotor.hasNextEntry) //this used to exclude the first road which is the only exception which I cannot exclude by the angle { //I am waiting at the intersection float dstToTarget = Vector3.Distance(rayCastPos.position, trafAIMotor.nextEntry.waypoints[0]); if (dstToTarget <= 20f) { TrafEntry nextRoadWaypoints = trafAIMotor.system.GetEntry(trafAIMotor.fixedPath[trafAIMotor.currentFixedNode].id, trafAIMotor.fixedPath[trafAIMotor.currentFixedNode].subId); //points of the next piece of road Vector3 heading = (nextRoadWaypoints.waypoints[nextRoadWaypoints.waypoints.Count - 1] - rayCastPos.position).normalized; float angle = Vector3.SignedAngle(rayCastPos.forward, heading, Vector3.up); //angle between heading and direction of PlayerCar if (angle < -20f) { if (!hasPlayedON) { turnLeftAudioSource.PlayOneShot(ResourceHandler.instance.audioClips[7]); hasPlayedON = true; } turnLeftAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.LEFT; hasPlayedOFF = false; } else if (angle > 20f) { if (!hasPlayedON) { turnRightAudioSource.PlayOneShot(ResourceHandler.instance.audioClips[7]); hasPlayedON = true; } turnRightAnim.SetBool("Turn", true); lastTurnSignal = TurnSignal.RIGHT; hasPlayedOFF = false; } } } else if ((!trafAIMotor.hasNextEntry && !trafAIMotor.currentEntry.isIntersection()) && Mathf.Abs(vehicleController.steerInput) <= 0.02f) //With the steerInput condition I assure that the turn signal is set off when steer has more or less angle equal to zero { if (lastTurnSignal.Equals(TurnSignal.LEFT)) { turnLeftAnim.SetBool("Turn", false); hasPlayedON = false; if (!hasPlayedOFF) { turnLeftAudioSource.PlayOneShot(ResourceHandler.instance.audioClips[6]); hasPlayedOFF = true; } } else if (lastTurnSignal.Equals(TurnSignal.RIGHT)) { turnRightAnim.SetBool("Turn", false); hasPlayedON = false; if (!hasPlayedOFF) { turnRightAudioSource.PlayOneShot(ResourceHandler.instance.audioClips[6]); hasPlayedOFF = true; } } } } }
public void setMotor(TrafAIMotor motor) { this.motor = motor; }
// Use this for initialization void Start() { motor = gameObject.GetComponentInParent <TrafAIMotor>(); angoloPrecedente = transform.rotation.eulerAngles.y; }