根据路线位置瞬时状态模拟运动算法二

本篇基于:根据路线位置瞬时状态模拟运动算法

 

有了算法后,就是具体的运动模拟了,具体的实现脚本代码如下:

/*****************************************************
**
**   运动模拟实现
**            
*****************************************************/

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/

posted @ 2013-04-04 15:57  寻梦丄天涯  阅读(239)  评论(0)    收藏  举报