Unity3d实现的十字路口的模拟(三)

好的,下面我们来说一下,小车的创建,怎么实现随机的创建小车,其实在创建小车这里我主要是用来Instantiate函数来克隆prefab物体,当然这个预制物体也是需要设置一番的,看了视频的话我们肯定都已经知道了wheelcollider的创建,其实一个预制物体还有一个引导球包括他的脚本和一个包裹小车的用于感知其他小球碰撞的“保护膜”,

这里有一个层次结构大家可以看一下:


当前选中的那个其实是小车的外壳,他的作用就是在周围包裹一层collider来保证我们的小车不会从我们的场景中掉下去,用于控制我们小车的脚本是在那个父物体Pickup_Truck中,这样在一个预制物体生成的时候就会有相应的函数来执行,下面来看一个放在小车上的另一个脚本也就是控制小车的脚本:

#pragma strict
    var collider_FL:WheelCollider;
	var collider_FR:WheelCollider;
	var collider_BL:WheelCollider;
	var collider_BR:WheelCollider;

	var wheel_FL:Transform;
	var wheel_FR:Transform;
	var wheel_BL:Transform;
	var wheel_BR:Transform;

	private var left_light:GameObject;
	private var right_light:GameObject;
	private var bot_light:GameObject;
	private var top_light:GameObject;

    var target:Transform;	
	private var body:Rigidbody;
	private var motor:float;
	var CenterOfMass:Vector3;
	private var maxangle:float=40f;
	private var brake:float;//右转刹车
	private var go:int ;//是否继续前行的标志
	private var car_front:int ;//if any car in front 
	// Use this for initialization
function Start () {
		go=1;
		brake=0;
		motor=20;
		body=GetComponent("Rigidbody");
		body.centerOfMass=CenterOfMass;//用于重心的控制
		//left_light=GameObject.Find("traffic_lights_left");
		right_light=GameObject.Find("traffic_lights_right");
		bot_light=GameObject.Find("traffic_lights_bot");
		top_light=GameObject.Find("traffic_lights_top");
}

function Update () {
	   //渲染车轮的运动
		wheel_FL.Rotate(collider_FL.rpm/60*360*Time.deltaTime,0,0);
		wheel_FR.Rotate(collider_FR.rpm/60*360*Time.deltaTime,0,0);
		wheel_BL.Rotate(collider_BL.rpm/60*360*Time.deltaTime,0,0);
		wheel_BR.Rotate(collider_BR.rpm/60*360*Time.deltaTime,0,0);
		//渲染前轮的旋转
		wheel_FL.localEulerAngles=wheel_FR.localEulerAngles=new Vector3(wheel_FL.localEulerAngles.x,collider_FL.steerAngle,wheel_FR.localEulerAngles.z);
}

function FixedUpdate(){//表示物理操作的更新
	   //用于更新当前前轮的状态
		var offsetTargetPos:Vector3= target.position;//小球的位置
		var localTarget:Vector3= transform.InverseTransformPoint(offsetTargetPos);
		var targetAngle:float = Mathf.Atan2(localTarget.x, localTarget.z)*Mathf.Rad2Deg;
		var steer:float = Mathf.Clamp(targetAngle*0.05f, -1, 1)*Mathf.Sign(GetComponent.<Rigidbody>().velocity.magnitude);
		collider_FL.steerAngle=collider_FR.steerAngle=steer*maxangle;
		if(go==1&&car_front==0){//go判断前方是否有车是否是红灯
		  
		  brake=0;
		  motor=20;
		}else{//stop
		  motor=0;//动力
		  brake=25000;//刹车
		  var newx:float=body.velocity.x-1>0?body.velocity.x-1:0;
		  body.velocity=new Vector3(newx,0,0);
		  isgoon();//用于红灯时不断地检测当前信号灯的状态
		}
		collider_BL.motorTorque=collider_BR.motorTorque=motor;
		collider_BL.brakeTorque=collider_BR.brakeTorque=brake;
		
	}
function isbrake(a:int){
		brake=a;
		if(a==0){
		motor=20;
		}else{
		motor=0;
		}
		//Debug.Log (transform.name+" brake is "+brake);
	}
function isgo(a:int){
      car_front=a;
      //Debug.Log(transform.name+" car_front:"+car_front);
	}	
function isgoon(){
        var way_name=getway();
		switch(way_name){
		case "left":
			go=lightcontrol.go;
			break;
		case "right":
		    go=lightcontrol.go;
			break;
		case "bottom":
		    go=tblightcontrol.go;
			break;
		case "top":
		    go=tblightcontrol.go;
			break;
		case "notinroad"://包括最右面用于右转的那个车道
		    go=1;
		    break;
		}
	}
function OnTriggerEnter(go:Collider ) {
        if(go.transform.name=="trigger"){
         gameObject.BroadcastMessage("lastcollider",go.transform.name);
         }
		if(go.transform.name=="stop_line"){//也就是在路口前
			isgoon();
		//    Debug.Log("stop");
		}
	}
	
	//用于判断当前在哪条道路上
function getway(){
		var x:float=transform.position.x;
		var z:float=transform.position.z;
		//这里的车道的计算是不包括最右车道的,因为最右车道不是右拐就是紧急车道没有红灯
		if(x>0&&x<89&&z>96&&z<105.5){//left
			return "left";
		}else if(x>107&&x<200&&z>90.5&&z<102.5){//right
			return "right";
		}else if(x>89&&x<101&&z>0&&z<90.5){//bottom
			return "bottom";
		}else if(x>94&&x<107&&z>105.5&&z<200){//top
			return "top";
		}else{
			return "notinroad";
		}
	}

这里的注释也是比较详细,这里要说一下的就是那个控制前车轮的变化角度的计算,这个是我借鉴unity的car_ai的例子写的,主要是计算了一个正切角什么的,具体的时我也没太弄懂...不过可以使用,我就直接拿下来了(看来学好数学还是必须的!)。那个判断当前位置的函数的具体的x,z(y 是垂直的轴)是要大家自己计算的,不同的物理世界肯定是不同,这里只是给出了一个用于判断当前位置的方法~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章