上一个篇的最后,我们已经彻底被源码中的计算物体坐标的地方搞晕了,这个真的不太好懂,幸好的断点下的地方比较准确,才促使这个问题得以解决。
可以看到当角色的位置达到了-200之后,再继续走一点,z小于-200,那么此时,currentMove.z=300,而转换之后的pos.z=playerPos.z - currentMove.z
其实呢,pos是目前角色真正的位置,因为一直沿着z的负方向移动,z一直减小,怎么可能突然从-200.2变为99.6了呢?所以在用于计算的时候,pos是角色真正的世界的坐标位置。也就是说这个代码:
public void CheckPositionTiles ()
{
Vector3 pos = player.position; //人物的假距离
pos -= currentMove; //人物真正的距离
int xPosCurrent = (sceneCollection.xSize != 0) ? (int)(Mathf.FloorToInt (pos.x / sceneCollection.xSize)) : 0;
int yPosCurrent = (sceneCollection.ySize != 0) ? (int)(Mathf.FloorToInt (pos.y / sceneCollection.ySize)) : 0;
int zPosCurrent = (sceneCollection.zSize != 0) ? (int)(Mathf.FloorToInt (pos.z / sceneCollection.zSize)) : 0;
用人物真正的距离各个分量,求得当前是在第几块地形。比如上面的当pos.z=-200.2的时候,-200.2/100=-2.002,向下取整,得到-3。
ok,这个我们明白了,那么问题又来了,currentMove是怎么计算的呢?
我们找到脚本Streamer中的这个变量的引用,可以发现在WorldMover中,对其做了赋值操作:
调用的顺序是这样的,Streamer中的CheckPositionTiles-》worldMover.CheckMoverDistance-》MoveWorld
MoveWorld中进行赋值操作。
worldMover.CheckMoverDistance这个传递过去的参数是xPosCurrent, yPosCurrent, zPosCurrent,是当前要加载的地形的索引。
CheckMoverDistance接收这个参数之后,进行判断处理:
第一个判断:Mathf.Abs (xPosCurrent - xCurrentTile) > xTileRange
这里有3个变量,xPosCurrent自不必说,是传入的当前的地块索引x。
xCurrentTile,这个是计算当前所在地块索引,如果不清楚继续往下看。
xTileRange,这个在WorldMover中的有个注释:Frequency distance of world position restarting, distance in is grid elements.
就是说每个多少块,世界坐标就会重置,如果是2,那么则隔2块格子就进行重置世界坐标。
回到上面,如果加上当前的xCurrentTile为3,而xCurrentTile=0,xTileRange=2,那么3-0>2成立,于是进入if里,执行函数MoveWorld。
Vector3 moveVector = new Vector3 (
(xPosCurrent - xCurrentTile) * streamerMajor.sceneCollection.xSize,
(yPosCurrent - yCurrentTile) * streamerMajor.sceneCollection.ySize,
(zPosCurrent - zCurrentTile) * streamerMajor.sceneCollection.zSize
);
moveVector的x分量计算方式为:(xPosCurrent - xCurrentTile) * streamerMajor.sceneCollection.xSize,
(3-0)* 100=300
其他分量类似计算。
接着:
currentMove -= moveVector;
用了一个减号,也就是说,如果世界坐标好过300,那么则将其减去300,回归到初始点在继续走。
再接着:
streamerMajor.player.position -= moveVector;
人物的世界坐标也做同样的处理。
foreach (var item in streamerMajor.loadedScenes) {
if (item.loaded && item.sceneGo != null)
item.sceneGo.transform.position -= moveVector;
}
将所有已经加载的场景,其世界坐标都减去这个moveVector。
将所有跟随地块移动的物体都减去这个moveVector。
foreach (var item in objectsToMove) {
if (item != null) {
//Debug.Log (item.name);
item.position -= moveVector;
}
}
再接着:
xCurrentTile = xPosCurrent;
yCurrentTile = yPosCurrent;
zCurrentTile = zPosCurrent;
streamerMajor.currentMove = currentMove;
更新当前记录值xCurrentTitle,yCurrentTitle,zCurrentTitle。以及streamerMajor中的currentMove。
再接着:
foreach (var item in streamerMinors) {
item.currentMove = currentMove;
foreach (var scene in item.loadedScenes) {
if (scene.loaded && scene.sceneGo != null)
scene.sceneGo.transform.position -= moveVector;
}
}
更新小物件流的中的每个加载场景的世界坐标。
也许你这里看晕了,我们用个图展示下:
不知道上图你能看得懂哇,比如说我们的保持x,y不懂,沿着z轴正向走,那么当走到3的时候,满足了上面的if语句,即3-0=3>2,那么此时将第三块,移动的0的位置,如下图:
再往下走:
再往下走:
ok,你现在应该清楚的知道了,这个是怎样的过程了。
但是还有一个问题,就是AddSceneGO方法中的这个代码是什么意思:
sceneGO.transform.position += currentMove + new Vector3 (scenesArray [posInt].posXLimitMove, scenesArray [posInt].posYLimitMove, scenesArray [posInt].posZLimitMove);
前面的+=currentMove我知道什么意思,但是后面那一坨是什么意思。
不好意思,我好像又懂了,我是多么滴聪明呀,哈哈哈哈。
下面我将一步一步还原这个加载的过程,借助图的方式进行展示。我相信经过和这个图示之后,你们会特别清晰作者的思想是啥。