根据路线位置瞬时状态模拟运动算法二
本篇基于:根据路线位置瞬时状态模拟运动算法
有了算法后,就是具体的运动模拟了,具体的实现脚本代码如下:
/***************************************************** ** ** 运动模拟实现 ** *****************************************************/ private var roadJs :RoadArithmetic; var prefab :GameObject; var signArrays :Array = new Array(); // A, B, C, D, E, F, G, H, I, J signArrays[0] = new Array(1, 0, 1, 1, 1, 0, 1, 1, 0, 1); signArrays[1] = new Array(1, 1, 1, 0, 1, 1, 0, 1, 0, 0); signArrays[2] = new Array(1, 1, 0, 1, 1, 0, 1, 1, 0, 0); signArrays[3] = new Array(0, 1, 0, 1, 1, 1, 0, 1, 0, 0); signArrays[4] = new Array(0, 1, 0, 1, 0, 1, 0, 0, 1, 0); signArrays[5] = new Array(0, 0, 0, 1, 1, 0, 1, 0, 0, 1); signArrays[6] = new Array(0, 0, 0, 1, 0, 1, 0, 1, 0, 1); signArrays[7] = new Array(0, 0, 0, 1, 0, 0, 1, 0, 1, 1); var acceptedSignIndex :int = 0; function Awake () { roadJs = GetComponent(RoadArithmetic); } /***************************************************** ** 模拟单个移动 ** fromSite 从哪里开始移动 ** toSite 移动到哪里 *****************************************************/ private function moveFromTo(fromSite:String, toSite:String){ print('From=' + fromSite + ' to=' + toSite); var triggerName:String ; var triggerObj:GameObject; var moveObj:GameObject = GameObject.Find("Cube" + fromSite); var fromSitePosition:Vector3 = GameObject.Find(fromSite).transform.position; var toSitePosition:Vector3 = GameObject.Find(toSite).transform.position; var moveDirection:Vector3 = (toSitePosition - fromSitePosition); moveDirection.Normalize(); if(moveDirection == Vector3(1,0,0)){ //向右 triggerName = toSite + "-East"; } else if(moveDirection == Vector3(-1,0,0)){ //向右 triggerName = toSite + "-West"; } else if(moveDirection == Vector3(0,0,1)){ //向右 triggerName = toSite + "-North"; } else if(moveDirection == Vector3(0,0,-1)){ //向右 triggerName = toSite + "-South"; } triggerObj = GameObject.Find(triggerName); triggerObj.GetComponent(SiteTrigger).isWorkFlag = true; triggerObj.GetComponent(SiteTrigger).stopObject = moveObj; moveObj.GetComponent(Move).direction = toSitePosition - fromSitePosition ; } /***************************************************** ** 初始化场景 ** 需要先清空,再初始化 ** 初始化的物体注意命名规则 *****************************************************/ function initObjects(initSign :Array){ for(var i=0; i<initSign.length; i++){ if(initSign[i] == 1){ var siteName:String = roadJs.sites[i]; var gm:GameObject = GameObject.Find(siteName); var pos:Vector3 = gm.transform.position; var clone:GameObject = Instantiate(prefab, Vector3(pos.x,0.3698654,pos.z), gm.transform.rotation); clone.name ="Cube" + siteName; clone.AddComponent(Move); } } } /***************************************************** ** 一次完整运动模拟 ** preSignArr 上一时刻的信号 ** nextSignArr 下一时刻的信号 *****************************************************/ function oneMove(preSignArr:Array, nextSignArr:Array){ roadJs.preSign = preSignArr; roadJs.nextSign = nextSignArr; var moves :Array = roadJs.getAllSiteMoveRoad(); print(moves); if(moves.length==1 && moves[0]=='-1'){ // print('信号异常, 按后一时刻的状态初始化'); // initObjects(nextSignArr); return; } for(var j=0; j<moves.length; j++){ var moveWay:String = moves[j] as String; var index:int = moveWay.IndexOf(" ==> "); var from:String = moveWay.Substring(0,index); var to :String = moveWay.Substring(index+5); if(from == 'Null'){ //生产点 var _gm:GameObject = GameObject.Find(to); var _pos:Vector3 = _gm.transform.position; var _clone:GameObject ; if(to == 'A'){ _clone = Instantiate(prefab, Vector3(_pos.x-1,0.3698654,_pos.z), _gm.transform.rotation); _clone.AddComponent(Move).direction = Vector3(1,0,0); GameObject.Find('A-East').GetComponent(SiteTrigger).isWorkFlag = true; GameObject.Find('A-East').GetComponent(SiteTrigger).stopObject = _clone; } else if(to == 'C'){ _clone = Instantiate(prefab, Vector3(_pos.x,0.3698654,_pos.z-1), _gm.transform.rotation); _clone.AddComponent(Move).direction = Vector3(0,0,1); GameObject.Find('C-Notth').GetComponent(SiteTrigger).isWorkFlag = true; GameObject.Find('C-Notth').GetComponent(SiteTrigger).stopObject = _clone; } } else if(to == 'Null'){ //消费点 var _fromObj:GameObject = GameObject.Find('Cube' + from); if(from == 'H'){ _fromObj.GetComponent(Move).direction = Vector3(1,0,0); } else if(from == 'J'){ _fromObj.GetComponent(Move).direction = Vector3(0,0,1); } } else{//正常移动 moveFromTo(from, to); } } } // Require a RoadArithmetic to be attached to the same game object @script RequireComponent (RoadArithmetic) // //function Start(){ // initObjects(signArrays[0]); // oneMove(signArrays[0], signArrays[1]); // acceptedSignIndex += 1; //} private var interval = 8 ; private var nextTime = 0; function FixedUpdate(){ if((Time.time > nextTime) && (acceptedSignIndex < signArrays.length-1)){ if(nextTime == 0){ //首次 initObjects(signArrays[0]); } nextTime += interval ; print('Time On . . .' + acceptedSignIndex); oneMove(signArrays[acceptedSignIndex], signArrays[acceptedSignIndex+1]); acceptedSignIndex += 1; } }
当然,细心看代码的同学可能已经注意到,里面运动的实现还涉及到其它的一些内容,如触发器,触发器规则等。好吧,再补充触发器脚本:
#pragma strict /******************************************* ** stopObject 需要停止的物体 ** isWorkFlag 触发器是否起作用标识 *******************************************/ var stopObject :GameObject; var isWorkFlag :boolean = false; /******************************************* ** 让物体停止移动 *******************************************/ function OnTriggerEnter (other : Collider) { if(isWorkFlag && other.gameObject==stopObject ){ other.gameObject.GetComponent(Move).direction = Vector3.zero; other.gameObject.name = 'Cube' + this.name.Substring(0,1); isWorkFlag = false; } }
特别注意的是,它停止的时候,要重命名物体。
具体的运动效果模拟请查看附件:http://www.rayfile.com/files/3930aef3-9cfe-11e2-aea8-0015c55db73d/

浙公网安备 33010602011771号