NewN_UAVPlane/Assets/art/bangonglou/dalou/Scripts/TrafficCar.cs

1134 lines
34 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
namespace FCG
{
public class TrafficCar : MonoBehaviour
{
public enum StatusCar
{
transitingNormally,
waitingForAnotherVehicleToPass,
stoppedAtTrafficLights,
bloked, // It's on a dead end street, stand still
Undefined,
crashed,
}
[HideInInspector]
public StatusCar status;
public GameObject BreakLight;
public GameObject LightLeft = null;
public GameObject LightRight = null;
private bool lightDirection = false;
[HideInInspector]
public Transform mRayC1;
[HideInInspector]
public Transform mRayC2;
private Vector3 mRayCenter;
[HideInInspector]
public Transform[] wheel;
public WheelCollider[] wCollider;
private int countWays;
private Transform[] nodes;
[HideInInspector]
public int currentNode = 0;
[HideInInspector]
public float distanceToNode;
private float steer = 0.0f;
private float speed;
private float brake = 0;
private float motorTorque = 0;
private Vector3 steerCurAngle = Vector3.zero;
private Rigidbody myRigidbody;
private Vector3 relativeVector;
public CarWheelsTransform wheelsTransforms;
private float timeStoped;
private Transform myReference;
private float iRC = 0;
private float brake2 = 0;
[HideInInspector]
public Transform atualWay;
[HideInInspector]
public int sideAtual = 0;
[HideInInspector]
public FCGWaypointsContainer atualWayScript;
[HideInInspector]
public bool nodeSteerCarefully = false; //true if I'm turning to the side that has opposite traffic (Right hand and turning left) Or (Left hand and turning right)
[HideInInspector]
public bool nodeSteerCarefully2 = false; // For double line oneway
[HideInInspector]
public Transform myOldWay;
[HideInInspector]
public int myOldSideAtual = 0;
[HideInInspector]
public FCGWaypointsContainer myOldWayScript = null;
private Vector3 _avanceNode = Vector3.zero; //private Position where an additional and momentary node can be added
private float countTimeToSignal = 0;
bool toSignal = false;
private bool toSignalLeft = false;
private bool toSignalRight = false;
private Transform behind = null;
//[HideInInspector]
public Transform player;
//[HideInInspector]
public TrafficSystem tSystem;
//[HideInInspector]
public float distanceToSelfDestroy = 0; //0 = Do not autodestroy with player distance
[System.Serializable]
public class CarWheelsTransform
{
public Transform frontRight;
public Transform frontLeft;
public Transform backRight;
public Transform backLeft;
public Transform backRight2;
public Transform backLeft2;
}
public CarSetting carSetting;
[System.Serializable]
public class CarSetting
{
public Transform carSteer;
[Range(10000, 60000)]
public float springs = 25000.0f;
[Range(1000, 6000)]
public float dampers = 1500.0f;
[Range(60, 200)]
public float carPower = 120f;
[Range(5, 10)]
public float brakePower = 8f;
[Range(20, 30)]
public float limitSpeed = 30.0f;
[Range(30, 72)]
public float maxSteerAngle = 40.0f; //Maximum wheel curvature angle
[Range(-1, 1)]
public float curveAdjustment = 0.0f; // make tighter or more open turns
}
private Vector3 shiftCentre = new Vector3(0.0f, -0.05f, 0.0f);
private Transform GetTransformWheel(string wheelName)
{
GameObject[] wt;
wt = GameObject.FindObjectsOfType(typeof(GameObject)).Select(g => g as GameObject).Where(g => g.name.Equals(wheelName) && g.transform.parent.root == transform).ToArray();
if (wt.Length > 0)
return wt[0].transform;
else
return null;
}
public void Configure()
{
if (!wheelsTransforms.frontRight)
wheelsTransforms.frontRight = GetTransformWheel("FR");
if (!wheelsTransforms.frontLeft)
wheelsTransforms.frontLeft = GetTransformWheel("FL");
if (!wheelsTransforms.backRight)
wheelsTransforms.backRight = GetTransformWheel("BR");
if (!wheelsTransforms.backLeft)
wheelsTransforms.backLeft = GetTransformWheel("BL");
if (!wheelsTransforms.backRight2)
wheelsTransforms.backRight2 = transform.Find("BR2");
if (!wheelsTransforms.backLeft2)
wheelsTransforms.backLeft2 = transform.Find("BL2");
if (!transform.GetComponent<Rigidbody>())
transform.gameObject.AddComponent<Rigidbody>();
if (transform.gameObject.GetComponent<Rigidbody>().mass < 4000f)
transform.gameObject.GetComponent<Rigidbody>().mass = 4000f;
transform.gameObject.GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
if (!wheelsTransforms.frontLeft || !wheelsTransforms.frontRight || !wheelsTransforms.backRight || !wheelsTransforms.backLeft)
{
Debug.LogError("wheelsTransforms absent in inspector");
return;
}
float p = wheelsTransforms.frontRight.localPosition.z + 0.6f;
float l = wheelsTransforms.frontRight.localPosition.x;
//
Transform testC = new GameObject("RayTest").transform;
testC.SetParent(transform);
testC.localPosition = new Vector3(0, 0f, wheelsTransforms.frontRight.localPosition.z + 4f);
testC.LookAt(transform);
testC.position += new Vector3(0, 0.8f, 0);
if (Physics.Raycast(testC.position, testC.forward, out RaycastHit hit, 4))
{
Debug.DrawRay(testC.position, testC.forward * 4, Color.red);
p = ((wheelsTransforms.frontRight.localPosition.z + 4f) - hit.distance) - 0.15f;
}
else
{
Debug.LogError("Adicione um collider e então tente novamente");
}
DestroyImmediate(testC.gameObject);
if (!transform.Find("RayC1"))
{
mRayC1 = new GameObject("RayC1").transform;
mRayC1.SetParent(transform);
}
else if (!mRayC1)
mRayC1 = transform.Find("RayC1");
mRayC1.localRotation = Quaternion.identity;
mRayC1.localPosition = new Vector3(-l, 0.8f, p);
if (!transform.Find("RayC2"))
{
mRayC2 = new GameObject("RayC2").transform;
mRayC2.SetParent(transform);
}
else if (!mRayC1)
mRayC2 = transform.Find("RayC2");
mRayC2.localRotation = Quaternion.identity;
mRayC2.localPosition = new Vector3(l, 0.8f, p);
carSetting.maxSteerAngle = (int)Mathf.Clamp(Vector3.Distance(wheelsTransforms.frontRight.transform.position, wheelsTransforms.backRight.transform.position) * 12, 35, 72);
wheel = new Transform[4];
wCollider = new WheelCollider[4];
GameObject center = new GameObject("Center");
Vector3[] centerPos = new Vector3[4];
Vector3 nCenter = new Vector3(0, 0, 0);
wheel[0] = wheelsTransforms.frontRight;
wheel[1] = wheelsTransforms.frontLeft;
wheel[2] = wheelsTransforms.backRight;
wheel[3] = wheelsTransforms.backLeft;
for (int i = 0; i < 4; i++)
{
wCollider[i] = SetWheelComponent(i);
// Define CenterOfMass
center.transform.SetParent(wheel[i].transform);
center.transform.localPosition = new Vector3(0, 0, 0);
center.transform.SetParent(transform);
centerPos[i] = center.transform.localPosition -= new Vector3(0, wCollider[i].radius, 0);
nCenter += centerPos[i];
}
shiftCentre = (nCenter / 4);
DestroyImmediate(center);
}
private WheelCollider SetWheelComponent(int w)
{
WheelCollider result;
Transform wheelCol = transform.Find(wheel[w].name + " - WheelCollider");
if (wheelCol)
try
{
DestroyImmediate(wheelCol.gameObject);
}
catch { }
if (wheelCol)
return wheelCol.GetComponent<WheelCollider>();
wheelCol = new GameObject(wheel[w].name + " - WheelCollider").transform;
wheelCol.transform.SetParent(transform);
wheelCol.transform.position = wheel[w].position;
wheelCol.transform.eulerAngles = transform.eulerAngles;
WheelCollider col = (WheelCollider)wheelCol.gameObject.AddComponent(typeof(WheelCollider));
result = wheelCol.GetComponent<WheelCollider>();
JointSpring js = col.suspensionSpring;
js.spring = carSetting.springs;
js.damper = carSetting.dampers;
col.suspensionSpring = js;
col.suspensionDistance = 0.05f;
col.radius = (wheel[w].GetComponent<MeshFilter>().sharedMesh.bounds.size.z * wheel[w].transform.localScale.z) * 0.5f * 0.92f;
col.mass = 2000;
return result;
}
void Start()
{
timeStoped = Time.time;
float p = wheelsTransforms.frontRight.localPosition.z + 0.6f;
if (!transform.Find("RayC1"))
{
mRayC1 = new GameObject("RayC1").transform;
mRayC1.SetParent(transform);
mRayC1.localRotation = Quaternion.identity;
mRayC1.localPosition = new Vector3(-0.6f, 0.5f, p);
}
else if (!mRayC1)
mRayC1 = transform.Find("RayC1");
if (!transform.Find("RayC2"))
{
mRayC2 = new GameObject("RayC2").transform;
mRayC2.SetParent(transform);
mRayC2.localRotation = Quaternion.identity;
mRayC2.localPosition = new Vector3(0.6f, 0.5f, p);
}
else if (!mRayC1)
mRayC2 = transform.Find("RayC2");
myReference = new GameObject("myReference").transform;
myReference.SetParent(transform);
myReference.localPosition = new Vector3(0, 0, wheelsTransforms.frontRight.localPosition.z * 0.6f);
myReference.localRotation = Quaternion.identity;
if(player && !FindObjectOfType<TrafficSystem>())
Debug.LogError("The Traffic System.prefab not found in the Hierarchy");
if (atualWay)
Init();
}
public void Init()
{
atualWayScript = atualWay.GetComponent<FCGWaypointsContainer>();
myRigidbody = transform.GetComponent<Rigidbody>();
myRigidbody.centerOfMass = shiftCentre;
DefineNewPath();
if (currentNode == 0) currentNode = 1;
distanceToNode = Vector3.Distance(atualWayScript.Node(sideAtual, currentNode), myReference.position + myReference.forward * (carSetting.curveAdjustment * 0.5f));
InvokeRepeating(nameof(MoveCar), 0.02f, 0.02f);
status = StatusCar.transitingNormally;
lightDirection = (LightLeft && LightRight);
if (BreakLight) BreakLight.SetActive(false);
if (LightLeft) LightLeft.SetActive(false);
if (LightRight) LightRight.SetActive(false);
}
public void ActivateSelfDestructWhenAwayFromThePlayer()
{
if (tSystem && player)
{
if (distanceToSelfDestroy == 0) distanceToSelfDestroy = 200;
InvokeRepeating(nameof(SelfDestructWhenAwayFromThePlayer), 5f, 5f);
}
}
public float GetSpeed()
{
return speed;
}
public bool Get_avanceNode()
{
return (currentNode == 0 && nodeSteerCarefully && _avanceNode != Vector3.zero);
}
public Vector3 GetNodePosition()
{
return atualWayScript.Node(sideAtual, currentNode);
}
bool CheckBookAllPathOptions(FCGWaypointsContainer wayScript, int side)
{
int total;
int wSide;
FCGWaypointsContainer wScript;
total = (side == 0) ? wayScript.nextWay0.Length : wayScript.nextWay1.Length;
for (int i = 0; i < total; i++)
{
if (side == 0)
{
wScript = wayScript.nextWay0[i];
wSide = wayScript.nextWaySide0[i];
}
else
{
wScript = wayScript.nextWay1[i];
wSide = wayScript.nextWaySide1[i];
}
if (wScript)
{
if ((wScript.GetNodeZeroCar(wSide) != null && wScript.GetNodeZeroCar(wSide) != transform) && wScript.GetNodeZeroOldWay(wSide) != myOldWay && (!Get_avanceNode() || !wScript.GetNodeZeroCar(wSide).GetComponent<TrafficCar>().Get_avanceNode()))
return false;
}
else
{
Debug.LogWarning("wScript Error");
}
}
return true;
}
bool BookAllPathOptions(FCGWaypointsContainer wayScript, int side, bool book = true)
{
int total;
int wSide;
FCGWaypointsContainer wScript;
total = (side == 0) ? wayScript.nextWay0.Length : wayScript.nextWay1.Length;
for (int i = 0; i < total; i++)
{
if (side == 0)
{
wScript = wayScript.nextWay0[i];
wSide = wayScript.nextWaySide0[i];
}
else
{
wScript = wayScript.nextWay1[i];
wSide = wayScript.nextWaySide1[i];
}
if (book)
{
bool force = wScript.GetNodeZeroCar(wSide) && wScript.GetNodeZeroCar(wSide).GetComponent<TrafficCar>().Get_avanceNode();
if (!wScript.SetNodeZero(wSide, wayScript.transform, transform, force))
return false;
}
else
{
wScript.UnSetNodeZero(wSide, transform);
}
}
return true;
}
void MoveCar()
{
if (status == StatusCar.bloked)
return;
if (lightDirection)
{
countTimeToSignal++;
if (countTimeToSignal > 16)
{
countTimeToSignal = 0;
toSignal = !toSignal;
if (toSignalLeft)
LightLeft.SetActive(toSignal);
else if (toSignalRight)
LightRight.SetActive(toSignal);
else
{
LightLeft.SetActive(false);
LightRight.SetActive(false);
}
}
}
speed = myRigidbody.velocity.magnitude * 3.6f;
VerificaPoints();
distanceToNode = Vector3.Distance(atualWayScript.Node(sideAtual, currentNode), myReference.position + myReference.forward * (carSetting.curveAdjustment * 0.5f));
if (_avanceNode != Vector3.zero)
{
//Debug.DrawLine(transform.position + Vector3.up * 2f, _avanceNode + Vector3.up * 2f, Color.cyan);
relativeVector = transform.InverseTransformPoint(_avanceNode);
if (Vector3.Distance(_avanceNode, myReference.position) < 4)
_avanceNode = Vector3.zero;
}
else
{
//Debug.DrawLine(transform.position + Vector3.up * 0.2f, atualWayScript.Node(sideAtual, currentNode, (currentNode == 0 && nodeSteerCarefully) ? 3 : 0) + Vector3.up * 0.2f, Color.cyan);
relativeVector = transform.InverseTransformPoint(atualWayScript.Node(sideAtual, currentNode, (currentNode == 0 && nodeSteerCarefully) ? 3 : 0));
}
steer = ((relativeVector.x / relativeVector.magnitude) * carSetting.maxSteerAngle);
bool b1 = true;
bool b2;
iRC++;
if (iRC >= 4)
{
iRC = 0;
//nodeSteerCarefully : true if I'm turning to the side that has opposite traffic (Right hand and turning left) Or (Left hand and turning right)
if (currentNode == 0)
{
// Decide whether I should wait for another car to pass and then proceed
if (behind == null && atualWayScript.BookNodeZero(this))
{
// The way I was was not oneWay, and I'm turning to the side that has opposite traffic
// Decide whether I should wait for another car to pass and then proceed
if ((nodeSteerCarefully && !myOldWayScript.oneway) || (nodeSteerCarefully2))
{
//Reserve the node next to mine in my previous lane, so as not to come by car in the opposite direction.
if (!nodeSteerCarefully2)
b1 = myOldWayScript.SetNodeZero((myOldSideAtual == 1) ? 0 : 1, myOldWay, transform);
b2 = CheckBookAllPathOptions(myOldWayScript, myOldSideAtual) && BookAllPathOptions(myOldWayScript, myOldSideAtual, true);
brake2 = (b1 && b2) ? 0 : 4000;
}
else
brake2 = 0;
}
else
brake2 = 4000;
}
else
brake2 = 0;
if (speed > 2)
status = StatusCar.transitingNormally;
if (brake2 <= 0 || behind)
brake = FixedRaycasts();
else
status = StatusCar.waitingForAnotherVehicleToPass;
if (speed < 2 && (status != StatusCar.stoppedAtTrafficLights || status != StatusCar.waitingForAnotherVehicleToPass))
{
if (Time.time > timeStoped + 50)
{
Destroy(transform.gameObject);
return;
}
}
else
timeStoped = Time.time;
}
brake = (brake2 > brake) ? brake2 : brake;
if (BreakLight) BreakLight.SetActive(brake > 200);
float bk = 0;
if (speed > carSetting.limitSpeed) // Keep the speed at the set limit
bk = Mathf.Lerp(100, 1000, (speed - carSetting.limitSpeed) / 10);
if (bk > brake) brake = bk;
for (int k = 0; k < 4; k++)
{
if (brake == 0)
wCollider[k].brakeTorque = 0;
else
{
wCollider[k].motorTorque = 0;
wCollider[k].brakeTorque = carSetting.brakePower * brake;
}
if (k < 2)
{
motorTorque = Mathf.Lerp(carSetting.carPower * 30, 0, speed / carSetting.limitSpeed);
wCollider[k].motorTorque = motorTorque;
wCollider[k].steerAngle = steer;
}
wCollider[k].GetWorldPose(out Vector3 _pos, out Quaternion _rot);
wheel[k].position = _pos;
wheel[k].rotation = _rot;
}
if (wheelsTransforms.backRight2)
{
wheelsTransforms.backRight2.rotation = wheelsTransforms.backRight.rotation;
wheelsTransforms.backLeft2.rotation = wheelsTransforms.backRight.rotation;
}
//steeringwheel movement
if (carSetting.carSteer)
carSetting.carSteer.localEulerAngles = new Vector3(steerCurAngle.x, steerCurAngle.y, steerCurAngle.z - steer); //carSetting.carSteer.localEulerAngles = new Vector3(steerCurAngle.x, steerCurAngle.y, steerCurAngle.z + ((steer / 180) * -30.0f));
}
private void VerificaPoints()
{
if (distanceToNode < 5)
{
if (currentNode < countWays - 1)
{
currentNode++;
if (currentNode == 1)
{
atualWayScript.UnSetNodeZero(sideAtual, transform); // Release the node so that the cars that were waiting for me to pass can proceed
status = StatusCar.transitingNormally;
if (nodeSteerCarefully || nodeSteerCarefully2)
{
myOldWayScript.UnSetNodeZero((myOldSideAtual == 1) ? 0 : 1, transform);
BookAllPathOptions(myOldWayScript, myOldSideAtual, false); //Release others nodes so that the cars that were waiting for me to pass can proceed
}
nodeSteerCarefully = false;
nodeSteerCarefully2 = false;
if (lightDirection)
{
toSignalRight = false;
toSignalLeft = false;
if (LightLeft) LightLeft.SetActive(false);
if (LightRight) LightRight.SetActive(false);
}
}
}
else
{
int t = TestWay();
//True if the chosen path was the only option
bool verify = (sideAtual == 0) ? atualWayScript.nextWay0.Length == 1 : atualWayScript.nextWay1.Length == 1;
myOldWay = atualWay;
myOldSideAtual = sideAtual;
myOldWayScript = atualWayScript;
if (sideAtual == 0 && (!atualWayScript.oneway || atualWayScript.doubleLine))
{
sideAtual = atualWayScript.nextWaySide0[t];
atualWayScript = atualWayScript.nextWay0[t];
}
else
{
sideAtual = atualWayScript.nextWaySide1[t];
atualWayScript = atualWayScript.nextWay1[t];
}
atualWay = atualWayScript.transform;
//The road I'm on has no exit, so interdict the previous road that had only this road as an option
if (verify && atualWayScript.bloked)
{
myOldWayScript.bloked = true;
brake2 = 6000;
status = StatusCar.bloked;
}
DefineNewPath();
currentNode = 0;
float a = GetAngulo(transform, atualWayScript.Node(sideAtual, 0));
//if (myOldWayScript.oneway)
if (myOldWayScript.oneway && !myOldWayScript.doubleLine)
{
if (myOldWayScript.doubleLine)
nodeSteerCarefully2 = (myOldSideAtual == 0 && a > 20 && a < 90) || (myOldSideAtual == 1 && a < 340 && a > 270);
else
nodeSteerCarefully = false;
}
else
nodeSteerCarefully = (atualWayScript.rightHand == 0 && a < 340 && a > 270) || (atualWayScript.rightHand != 0 && a > 20 && a < 90);
if (lightDirection)
{
toSignalLeft = (a < 340 && a > 270);
toSignalRight = (a > 20 && a < 90);
}
if (nodeSteerCarefully)
{
_avanceNode = myOldWayScript.AvanceNode(myOldSideAtual, myOldWayScript.waypoints.Count - 1, 7);
}
}
}
}
public Transform GetBehind()
{
return behind;
}
float FixedRaycasts()
{
RaycastHit hit;
float wdist = 6;
float wdist2 = (speed < 3) ? (wdist / 1.5f) : wdist;
float rStop;
mRayC1.localRotation = Quaternion.Euler(0, steer, 0);
mRayC2.localRotation = mRayC1.localRotation;
Debug.DrawRay((mRayC1.position + mRayC2.position) * 0.5f, mRayC1.forward * wdist2, Color.yellow);
Debug.DrawRay(mRayC1.position, mRayC1.forward * wdist2, Color.yellow);
Debug.DrawRay(mRayC2.position, mRayC2.forward * wdist2, Color.yellow);
if (Physics.Raycast((mRayC1.position + mRayC2.position) * 0.5f, mRayC1.forward, out hit, wdist2))
{
Debug.DrawRay((mRayC1.position + mRayC2.position) * 0.5f, mRayC1.forward * wdist2, Color.red);
rStop = hit.distance;
}
else if (Physics.Raycast(mRayC1.position, mRayC1.forward, out hit, wdist2))
{
Debug.DrawRay(mRayC1.position, mRayC1.forward * wdist2, Color.red);
rStop = hit.distance;
}
else if (Physics.Raycast(mRayC2.position, mRayC2.forward, out hit, wdist2))
{
Debug.DrawRay(mRayC2.position, mRayC2.forward * wdist2, Color.red);
rStop = hit.distance;
}
else
rStop = 0;
behind = (rStop == 0) ? null : hit.transform;
if (rStop > 0 && speed < 2)
{
if (status == StatusCar.stoppedAtTrafficLights || status == StatusCar.waitingForAnotherVehicleToPass || status == StatusCar.Undefined)
{ }
else if (hit.transform.name == "Stop")
status = StatusCar.stoppedAtTrafficLights;
else if (hit.transform.GetComponent<TrafficCar>())
{
StatusCar st = hit.transform.GetComponent<TrafficCar>().status;
status = (st == StatusCar.stoppedAtTrafficLights || st == StatusCar.waitingForAnotherVehicleToPass) ? st : StatusCar.Undefined;
}
}
if (rStop == 0)
return 0;
else
return (rStop < 1 || speed < 0.5f) ? 20000 : (speed * 6) * ((wdist / rStop) * 6);
}
void DefineNewPath()
{
nodes = new Transform[atualWay.childCount];
int n = 0;
foreach (Transform child in atualWay)
nodes[n++] = child;
countWays = nodes.Length;
}
int TestWay()
{
//Check if the path drawn for me is a good option (based on traffic) "VerifyTraffic"
//Also check if the selected path has been blocked "CheckStoped"
int total = 0;
if (sideAtual == 0)
total = atualWayScript.nextWay0.Length;
else
total = atualWayScript.nextWay1.Length;
int t = Random.Range(0, total); // Sort one of the available paths
if (total > 1) // If there are more path options to choose from
{
if (CheckStoped(t) || VerifyTraffic(t, 30) < 30 || VerifyNodeSteerCarefully2(t))
{
//Test the paths to see which option is best
float maior = 0;
for (int i = 0; i < total; i++)
{
if (!CheckStoped(i)) // && !VerifyNodeSteerCarefully2(i))
{
float vf = VerifyTraffic(i, 30);
if (vf == 30)
return i;
else if (vf < 30)
{
if (vf > maior)
{
maior = vf;
t = i;
}
}
}
}
}
}
return t;
}
private Vector3 GetNodeNextWay(int way, int node = 0)
{
/*
Returns the position of the specified node, from a chosen path that is among the available paths (vlinked to my current path)
*/
if (sideAtual == 0)
return atualWayScript.nextWay0[way].Node(atualWayScript.nextWaySide0[way], node);
else
return atualWayScript.nextWay1[way].Node(atualWayScript.nextWaySide1[way], node);
}
private bool CheckStoped(int way)
{
//Checks if a path is blocked (due to no exit or other reason)
if (sideAtual == 0)
return atualWayScript.nextWay0[way].bloked;
else
return atualWayScript.nextWay1[way].bloked;
}
/*
bool VerifyDoubleOneWayOption(int t)
{
//Vector3 node0 = GetNodeNextWay(t, 0);
//nodeSteerCarefully2 = (myOldSideAtual == 0 && a > 20 && a < 90) || (myOldSideAtual == 1 && a < 340 && a > 270);
return true;
}
*/
bool VerifyNodeSteerCarefully2(int t)
{
if (atualWayScript.oneway && atualWayScript.doubleLine)
{
float a = GetAngulo(transform, GetNodeNextWay(t, 0));
return (sideAtual == 0 && a > 20 && a < 90) || (sideAtual == 1 && a < 340 && a > 270);
}
return false;
}
float VerifyTraffic(int t, float mts = 12)
{
//Checks if the specified path is a good choice, it may be congested
RaycastHit hit2;
Vector3 node0 = GetNodeNextWay(t, 0) + new Vector3(0, 0.5f, 0);
Vector3 node1 = GetNodeNextWay(t, 1) + new Vector3(0, 0.5f, 0);
if (Physics.Raycast(node0, node1 - node0, out hit2, mts))
if (hit2.transform.GetComponent<TrafficCar>())
{
if (hit2.transform.GetComponent<TrafficCar>().GetSpeed() < 8)
return hit2.distance;
else
return mts - 1;
}
return mts;
}
private void Pause(Vector3 position)
{
#if UNITY_EDITOR
if (GameObject.Find("CubePause"))
{
GameObject.Find("CubePause").transform.position = position;
UnityEditor.EditorApplication.isPaused = true;
}
#endif
}
private int countC = 0;
void SelfDestructWhenAwayFromThePlayer()
{
if (speed < 2 && status != StatusCar.stoppedAtTrafficLights && (Time.time > timeStoped + 30) & InTheFieldOfVision(transform.position, player))
{
tSystem.nVehicles--;
Destroy(this.gameObject);
}
else if (Vector3.Distance(transform.position, player.position) < distanceToSelfDestroy || InTheFieldOfVision(transform.position, player))
countC = 0;
else
{
countC++;
if (countC >= 2)
{
tSystem.nVehicles--;
Destroy(this.gameObject);
}
}
}
public void SelfDestructWhenAwayFromThePlayerInit()
{
if (tSystem && player)
if (Vector3.Distance(transform.position, player.position) > distanceToSelfDestroy && !InTheFieldOfVision(transform.position, player))
{
tSystem.nVehicles--;
Destroy(this.gameObject);
}
else
ActivateSelfDestructWhenAwayFromThePlayer();
}
bool InTheFieldOfVision(Vector3 source, Transform target)
{
// the IACar wants to disappear without it being seen by the camera/player
RaycastHit obsRay2;
if (Physics.Linecast(source + Vector3.up * 1f, target.position + Vector3.up * 1f, out obsRay2)) //, ~(1 << LayerMask.NameToLayer("Lattice"))))
{
if (obsRay2.transform == target || obsRay2.transform.root == target)
{
//Debug.DrawLine(source, target.position, Color.red);
return true;
}
else
{
//Debug.DrawLine(source, target.position, Color.green);
return false;
}
}
else
{
//Debug.DrawLine(source, target.position, Color.blue);
return true;
}
}
private float GetAngulo(Transform origem, Vector3 target)
{
float r;
GameObject compass = new GameObject("Compass");
compass.transform.parent = origem;
compass.transform.localPosition = new Vector3(0, 0, 0);
compass.transform.LookAt(target);
r = compass.transform.localEulerAngles.y;
DestroyImmediate(compass);
return r;
}
}
}