我正在制作一款游戏,它有多达4个正交摄影机(最多4个玩家),根据玩家的数量占据不同数量的屏幕 .
我有一个控制所有摄像机的脚本,设置相对于他们正在观看的玩家的位置 .
我想要实现的是一种简单的头顶 - 跑步运动风格,相机将跟随玩家,但不会超出 Map 的范围 .
当摄像机为“方形”时(如在4人游戏布局中),我已设法在左上角的相机中工作 . 但是,其他相机根本没有正确跟踪,而在矩形双人模式下,顶部相机仍然左右移动太远 . 我很确定我确切地知道导致问题的代码行...但我不知道我需要做些什么来修复它...
SpriteRenderer spriteBounds = GameObject.Find("Map").GetComponentInChildren<SpriteRenderer>();
float leftBound =0;
float rightBound =0;
float bottomBound =0;
float topBound = 0;
if((trackPlayer1 == null))
{
camPlayer1.transform.position = this.transform.position;
}
else
{
float vertExtent = camPlayer1.orthographicSize;
float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??
leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);
camPlayer1.transform.position = new Vector3(Mathf.Clamp(trackPlayer1.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer1.transform.position.y, bottomBound, topBound), camPlayer1.transform.position.z);
}
if((trackPlayer2 == null))
{
camPlayer2.transform.position = this.transform.position;
}
else
{
float vertExtent = camPlayer2.orthographicSize ;
float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??
leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);
camPlayer2.transform.position = new Vector3(Mathf.Clamp(trackPlayer2.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer2.transform.position.y, topBound, bottomBound), camPlayer2.transform.position.z);
}
if((trackPlayer3 == null))
{
camPlayer3.transform.position = this.transform.position;
}
else
{
float vertExtent = camPlayer3.orthographicSize;
float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??
leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);
camPlayer3.transform.position = new Vector3(Mathf.Clamp(trackPlayer3.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer3.transform.position.y, topBound, bottomBound), camPlayer3.transform.position.z);
}
if((trackPlayer4 == null))
{
camPlayer4.transform.position = this.transform.position;
}
else
{
float vertExtent = camPlayer4.orthographicSize;
float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??
leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);
camPlayer4.transform.position = new Vector3(Mathf.Clamp(trackPlayer4.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer4.transform.position.y, topBound, bottomBound), camPlayer4.transform.position.z);
}
所以我很确定我需要检查屏幕上的摄像机大小和相对位置,但我完全失去了我需要做的事情 .
(编辑) Script explanation:
-
脚本是附加到主摄像机对象的全局脚本,玩家从未看到过该脚本
-
四个播放器凸轮(camPlayer1 - camPlayer4)是公共变量并分配给设计器中的脚本
-
trackPlayer1-trackPlayer4是公共游戏对象,在设计器中分配 - 它们被分配给玩家对象
-
玩家跟踪适用于所有凸轮...例如,如果我更改camPlayer2.transform.position = new Vector3(Mathf.Clamp(trackPlayer2.transform.position.x,leftBound,rightBound),Mathf.Clamp(trackPlayer2.transform.position) .y,topBound,bottomBound),camPlayer2.transform.position.z);到camPlayer2.transform.position = trackPlayer2.transform.position;,代码具有预期的效果,摄像机跟随播放器 . 只是夹在 Map 的边界上我遇到了问题
-
相机的正交尺寸设置为2
在启动时将摄像机定位在屏幕上的代码:
switch (playerCount)
{
case 1:
camPlayer1.enabled = true;
camPlayer2.enabled = false;
camPlayer3.enabled = false;
camPlayer4.enabled = false;
camPlayer1.rect = new Rect(0, 0, 1, 1);
camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer2.rect = new Rect(0, 0, 0, 0);
camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer3.rect = new Rect(0, 0, 0, 0);
camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer4.rect = new Rect(0, 0, 0, 0);
camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;
break;
case 2:
camPlayer1.enabled = true;
camPlayer2.enabled = true;
camPlayer3.enabled = false;
camPlayer4.enabled = false;
camPlayer1.rect = new Rect(0, 0.5f, 0.7f, 0.5f);
camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer2.rect = new Rect(0.3f, 0, 0.7f, 0.5f);
camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer3.rect = new Rect(0, 0, 0, 0);
camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer4.rect = new Rect(0, 0, 0, 0);
camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;
Destroy(play3);
Destroy(play4);
break;
case 3:
camPlayer1.enabled = true;
camPlayer2.enabled = true;
camPlayer3.enabled = true;
camPlayer4.enabled = false;
camPlayer1.rect = new Rect(0, 0.5f, 0.5f, 0.5f);
camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer2.rect = new Rect(0.5f, 0.5f, 0.5f, 0.5f);
camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer3.rect = new Rect(0.25f, 0, 0.5f, 0.5f);
camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer4.rect = new Rect(0, 0, 0, 0);
camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;
Destroy(play4);
break;
case 4:
camPlayer1.enabled = true;
camPlayer2.enabled = true;
camPlayer3.enabled = true;
camPlayer4.enabled = true;
camPlayer1.rect = new Rect(0, 0.5f, 0.5f, 0.5f);
camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer2.rect = new Rect(0.5f, 0.5f, 0.5f, 0.5f);
camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer3.rect = new Rect(0, 0, 0.5f, 0.5f);
camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;
camPlayer4.rect = new Rect(0.5f, 0, 0.5f, 0.5f);
camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;
break;
}
}
编辑,所以无论形状如何,我都能得到第一台相机(所以在双人模式中,使用矩形相机,玩家-1的凸轮将尊重 Map 的边界),使用下面的代码 . 我猜那时我需要对leftBound,rightBound,topBound和bottomBound应用一些偏移,这取决于其他凸轮的部分 . 如何 Build 和计算这些我不知道
if((trackPlayer1 == null))
{
camPlayer1.transform.position = this.transform.position;
}
else
{
float vertExtent = camPlayer1.orthographicSize;
float horzExtent = vertExtent * (Screen.width * (camPlayer1.rect.width * 2)) / Screen.height; //I guess the problem is here... but how do I fix this??
4 回答
您的计算有几个问题 . 我想这只是运气,它适用于某些情况 . 虽然您的一般想法是正确的,但您使用错误的属性进行计算 . 基本上,您需要了解摄像机的纵横比, Map 的边界框以及摄像机在边界处的行为方式 .
我们需要相机的纵横比来计算其宽度或范围 .
正如你在图片中看到的那样,
Screen.width
和Screen.height
指的是游戏's window or the monitor resolution in case you'重新运行全屏游戏 . 您还可以看到,与游戏窗口相比,相机可能具有不同的宽高比 . 好消息是Unity提供了获取相机宽高比的属性 .现在我们有了相机's extents, let',看看你的 Map 及其边界框 .
您尝试使用
bounds.size
进行计算,但正如您所见,bounds.size.x
是边界框的宽度 . 只有当 Map 的左下角从世界空间的(0,0)开始时,才能使用该大小 . 更好的方法是使用已经返回世界空间坐标的bounds.min
和bounds.max
.您的最终目标是摄像机应保持在 Map 的范围内,即其位置受以下四个条件的限制:
现在您只需要取得玩家位置并将相机限制在以下条件:
如果所有相机具有相同的大小和宽高比,则可以对所有玩家相机使用相同的边界,并且仅为每个玩家计算
camX
和camY
.我想建议你另一种方法来解决你的问题 .
您是否可以在 Map 的边界添加高对撞机,以及相机的对撞机?然后你可以让相机跟随播放器(使用物理!),当玩家到达边界时,由于对撞机,相机不会翻过来 .
然后,您可以轻松分割屏幕,了解您拥有多少玩家 . 一个球员? - >所有屏幕尺寸两名球员? - >摄像头1结束广告屏幕高度/ 2,摄像头2以屏幕高度/ 2 1开始,依此类推
大家好,对于一些需要完整代码的人来说,需要完成游戏对象的代码,并将许多儿童精灵带入Empty Gameobject,如:
这段代码将循环到Background对象中并占据所有儿童精灵的界限:D,由于@Stefan Hoffmann的解释,我制作了一个Frankestein代码hahhaa . 我希望这会对别人有所帮助,对不起我的英文不好:(
你应该使用这个简单但有用的unity 2d camera follow script
也可以在github上找到 . https://gist.github.com/unity3diy/5aa0b098cb06b3ccbe47