相机旋转后滚动
scrolling after camera rotation
我正在使用 C# 在 Unity 中编写一种 RTS CameraController。我已经设法实现了基本功能,但现在我面临一个棘手的问题。我设法旋转了相机,然后向正确的方向移动,但是旋转后我的滚动边界不再起作用(当然因为我只是在水平滚动时检查 x,但旋转后我需要检查 y ).对于边界,我的意思是限制滚动直到到达某个位置 (x < 0)。
我对如何轻松解决我的问题有点困惑。一种方法似乎是使用条件并在检查边界之前检查旋转,但这对我来说似乎不是一个好方法,只是解决了问题,但并没有真正解决问题。现在我的问题是:是否有更简单或更好的方法来实现我正在做的事情?我是不是完全错过了什么?
这就是我希望相机在所有 4 个旋转中移动的方式。矩形是我的世界,箭头定义了我的边界。相机应该总是在向后方向超调并在向前方向边界之前停止。:
这是我的更新方法(vertDist 和 horDist 只是定义鼠标滚动应该从什么时候开始):
void LateUpdate() {
//LEFT
if((Input.mousePosition.x < horDist || Input.GetAxis("Horizontal") < 0)
&& transform.position.x > 0)
transform.Translate(-speed, 0, 0);
//RIGHT
if((Input.mousePosition.x > Screen.width - horDist || Input.GetAxis("Horizontal") > 0)
&& transform.position.x < world.worldX)
transform.Translate(speed, 0, 0);
//UP
if((Input.mousePosition.y > Screen.height - vertDist || Input.GetAxis("Vertical") > 0)
&& transform.position.z < world.worldZ - 30) {
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
transform.Translate(0, 0, speed);
transform.eulerAngles = temp;
}
//DOWN
if((Input.mousePosition.y < vertDist || Input.GetAxis("Vertical") < 0)
&& transform.position.z > -10) {
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
transform.Translate(0, 0, -speed);
transform.eulerAngles = temp;
}
//ZOOM
//camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");
//ROTATE
if(Input.GetButtonDown("Rotate")){
Vector3 targetPosition = transform.position;
targetPosition += transform.forward * 27;
//transform.Rotate(new Vector3(0, Mathf.Sign(Input.GetAxis("Rotate")) * 90, 0), Space.World);
transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
}
}
使用
transform.Translate(0, 0, -speed, Space.Self); // For all the Translate, use Space.Self
它只会根据它的本地位置而不是世界位置移动。但你会得到你想要的。
希望对你有帮助。
终于找到解决办法了!我决定根据当前旋转定义一个 Rect,然后检查相机位置是否在 Rect 内。因此我不得不弄乱这些位置,因为我不知道为什么 Rect.Contains() 只采用位置的 x 和 y 坐标。我的相机只是沿着 x 轴和 z 轴移动,所以我在那里做了这个奇怪的坐标交换:
void LateUpdate() {
Rect bounds = DefineBounds();
Vector3 pos = transform.position;
//LEFT
if((/*Input.mousePosition.x < horDist ||*/ Input.GetAxis("Horizontal") < 0)) {
pos += transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
}
//RIGHT
if((/*Input.mousePosition.x > Screen.width - horDist ||*/ Input.GetAxis("Horizontal") > 0)) {
pos += transform.TransformDirection(speed * Time.deltaTime, 0, 0);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(speed * Time.deltaTime, 0, 0);
}
//UP
if((/*Input.mousePosition.y > Screen.height - vertDist ||*/ Input.GetAxis("Vertical") > 0)) {
//Set camera x-angle to 0
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
pos += transform.TransformDirection(0, 0, speed * Time.deltaTime);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(0, 0, speed * Time.deltaTime);
//Reset camera x-angle
transform.eulerAngles = temp;
}
//DOWN
if((/*Input.mousePosition.y < vertDist ||*/ Input.GetAxis("Vertical") < 0)) {
//Set camera x-angle to 0
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
pos += transform.TransformDirection(0, 0, -speed * Time.deltaTime);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(0, 0, -speed * Time.deltaTime);
//Reset camera x-angle
transform.eulerAngles = temp;
}
transform.position = pos;
//ZOOM
//camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");
transform.position = new Vector3(pos.x, pos.y - Input.GetAxis("Mouse ScrollWheel"), pos.z);
//ROTATE
if(Input.GetButtonDown("Rotate")){
Vector3 targetPosition = transform.position;
Vector2 posXZ;
targetPosition += transform.forward * 27;
transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
bounds = DefineBounds();
pos = transform.position;
posXZ = new Vector2(pos.x, pos.z);
while(!bounds.Contains(posXZ)) {
posXZ = Vector2.MoveTowards(posXZ, bounds.center, 1);
pos.x = posXZ.x;
pos.z = posXZ.y;
}
transform.position = pos;
}
}
我正在使用 C# 在 Unity 中编写一种 RTS CameraController。我已经设法实现了基本功能,但现在我面临一个棘手的问题。我设法旋转了相机,然后向正确的方向移动,但是旋转后我的滚动边界不再起作用(当然因为我只是在水平滚动时检查 x,但旋转后我需要检查 y ).对于边界,我的意思是限制滚动直到到达某个位置 (x < 0)。
我对如何轻松解决我的问题有点困惑。一种方法似乎是使用条件并在检查边界之前检查旋转,但这对我来说似乎不是一个好方法,只是解决了问题,但并没有真正解决问题。现在我的问题是:是否有更简单或更好的方法来实现我正在做的事情?我是不是完全错过了什么?
这就是我希望相机在所有 4 个旋转中移动的方式。矩形是我的世界,箭头定义了我的边界。相机应该总是在向后方向超调并在向前方向边界之前停止。:
这是我的更新方法(vertDist 和 horDist 只是定义鼠标滚动应该从什么时候开始):
void LateUpdate() {
//LEFT
if((Input.mousePosition.x < horDist || Input.GetAxis("Horizontal") < 0)
&& transform.position.x > 0)
transform.Translate(-speed, 0, 0);
//RIGHT
if((Input.mousePosition.x > Screen.width - horDist || Input.GetAxis("Horizontal") > 0)
&& transform.position.x < world.worldX)
transform.Translate(speed, 0, 0);
//UP
if((Input.mousePosition.y > Screen.height - vertDist || Input.GetAxis("Vertical") > 0)
&& transform.position.z < world.worldZ - 30) {
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
transform.Translate(0, 0, speed);
transform.eulerAngles = temp;
}
//DOWN
if((Input.mousePosition.y < vertDist || Input.GetAxis("Vertical") < 0)
&& transform.position.z > -10) {
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
transform.Translate(0, 0, -speed);
transform.eulerAngles = temp;
}
//ZOOM
//camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");
//ROTATE
if(Input.GetButtonDown("Rotate")){
Vector3 targetPosition = transform.position;
targetPosition += transform.forward * 27;
//transform.Rotate(new Vector3(0, Mathf.Sign(Input.GetAxis("Rotate")) * 90, 0), Space.World);
transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
}
}
使用
transform.Translate(0, 0, -speed, Space.Self); // For all the Translate, use Space.Self
它只会根据它的本地位置而不是世界位置移动。但你会得到你想要的。 希望对你有帮助。
终于找到解决办法了!我决定根据当前旋转定义一个 Rect,然后检查相机位置是否在 Rect 内。因此我不得不弄乱这些位置,因为我不知道为什么 Rect.Contains() 只采用位置的 x 和 y 坐标。我的相机只是沿着 x 轴和 z 轴移动,所以我在那里做了这个奇怪的坐标交换:
void LateUpdate() {
Rect bounds = DefineBounds();
Vector3 pos = transform.position;
//LEFT
if((/*Input.mousePosition.x < horDist ||*/ Input.GetAxis("Horizontal") < 0)) {
pos += transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(-speed * Time.deltaTime, 0, 0);
}
//RIGHT
if((/*Input.mousePosition.x > Screen.width - horDist ||*/ Input.GetAxis("Horizontal") > 0)) {
pos += transform.TransformDirection(speed * Time.deltaTime, 0, 0);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(speed * Time.deltaTime, 0, 0);
}
//UP
if((/*Input.mousePosition.y > Screen.height - vertDist ||*/ Input.GetAxis("Vertical") > 0)) {
//Set camera x-angle to 0
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
pos += transform.TransformDirection(0, 0, speed * Time.deltaTime);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(0, 0, speed * Time.deltaTime);
//Reset camera x-angle
transform.eulerAngles = temp;
}
//DOWN
if((/*Input.mousePosition.y < vertDist ||*/ Input.GetAxis("Vertical") < 0)) {
//Set camera x-angle to 0
Vector3 temp = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);
pos += transform.TransformDirection(0, 0, -speed * Time.deltaTime);
//reset pos if out of bounds
if(!bounds.Contains(new Vector2(pos.x, pos.z)))
pos -= transform.TransformDirection(0, 0, -speed * Time.deltaTime);
//Reset camera x-angle
transform.eulerAngles = temp;
}
transform.position = pos;
//ZOOM
//camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel");
transform.position = new Vector3(pos.x, pos.y - Input.GetAxis("Mouse ScrollWheel"), pos.z);
//ROTATE
if(Input.GetButtonDown("Rotate")){
Vector3 targetPosition = transform.position;
Vector2 posXZ;
targetPosition += transform.forward * 27;
transform.RotateAround(targetPosition, Vector3.up, Mathf.Sign(Input.GetAxis("Rotate")) * 90);
bounds = DefineBounds();
pos = transform.position;
posXZ = new Vector2(pos.x, pos.z);
while(!bounds.Contains(posXZ)) {
posXZ = Vector2.MoveTowards(posXZ, bounds.center, 1);
pos.x = posXZ.x;
pos.z = posXZ.y;
}
transform.position = pos;
}
}