我目前正在制作一个肖像游戏,我试图实现类似游戏Doodle Jump或Radical的屏幕外动作逻辑。
当游戏对象离开屏幕右侧时,如何将游戏对象重新定位到屏幕左侧,反之亦然,而不依赖于屏幕尺寸/宽高比?
这是我现在拥有的一段代码:
void CheckBounds()
{
if (this.transform.position.x < -3.2f)
{
this.transform.position = new Vector3(3.2f, this.transform.position.y, this.transform.position.z);
}
if (this.transform.position.x > 3.2f)
{
this.transform.position = new Vector3(-3.2f, this.transform.position.y, this.transform.position.z);
}
}
void MovePlayer()
{
if (isFacingLeft)
{
this.transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
}
else
{
this.transform.position += new Vector3(speed * Time.deltaTime, 0, 0);
}
}
现在这可行,但它是一个肮脏的解决方案。正如您所看到的,当对象离开屏幕时,我对边界进行了硬编码,即+/- 3.2f。
这适用于16:9宽高比设备,但不适用于其他宽高比设备。
无论屏幕宽高比如何,如何检测屏幕边缘以使其工作?
由于
答案 0 :(得分:1)
我已经有2个资产来解决这个问题:
对象边缘2D&amp;相机边缘
他们允许你简单地写:
if( player.GetLeftPosition().x > myCamera.GetRightPosition(10))
player.MoveRightPosition(myCamera.GetLeftPosition(10));
资产链接:
对象边缘2D: http://u3d.as/wkF
相机边缘: http://u3d.as/xxB
希望你帮助你&amp;节省你的时间。
答案 1 :(得分:0)
我更喜欢放置两个标记左右限制的空对象。
如果角色超出游戏范围(左边界限左侧或右边界限右侧),你可以登记更新(或者只是当角色移动以提高性能时)并相应地修复它的位置:
类似的东西:
if(character.position.x < leftLimit.position.x - MARGIN) {
character.position.x = rightLimit.position.x - MARGIN;
}
if(character.position.x > rightLimit.position.x + MARGIN) {
character.position.x = leftLimit.position.x + MARGIN;
}
MARGIN增加了一个小容差以避免闪烁。
答案 2 :(得分:0)
此脚本用于在屏幕边界(视口)内屏幕包装对象。你所要做的就是将这个脚本放在你的游戏对象上,它将完成剩下的工作。你的相机外面不需要对撞机,它只是放置和播放。您还可以设置公共布尔值,以确定您是否希望您的游戏对象包裹宽度,高度或两者。视频教程:https://youtu.be/VAmlb913-jc
前往this website获取一系列Unity3D教程。
using UnityEngine;
using System.Collections;
public class ScreenWrap : MonoBehaviour
{
public bool wrapWidth = true;
public bool wrapHeight = true;
private Renderer _renderer;
private Transform _transform;
private Camera _camera;
private Vector2 _viewportPosition;
private bool isWrappingWidth;
private bool isWrappingHeight;
private Vector2 _newPosition;
void Start ()
{
_renderer = GetComponent <Renderer> ();
_transform = transform;
_camera = Camera.main;
_viewportPosition = Vector2.zero;
isWrappingWidth = false;
isWrappingHeight = false;
_newPosition = _transform.position;
}
void LateUpdate ()
{
Wrap ();
}
private void Wrap ()
{
bool isVisible = IsBeingRendered ();
if (isVisible)
{
isWrappingWidth = false;
isWrappingHeight = false;
}
_newPosition = _transform.position;
_viewportPosition = _camera.WorldToViewportPoint (_newPosition);
if (wrapWidth)
{
if (!isWrappingWidth)
{
if (_viewportPosition.x > 1)
{
_newPosition.x = _camera.ViewportToWorldPoint (Vector2.zero).x;
isWrappingWidth = true;
}
else if (_viewportPosition.x < 0)
{
_newPosition.x = _camera.ViewportToWorldPoint (Vector2.one).x;
isWrappingWidth = true;
}
}
}
if (wrapHeight)
{
if (!isWrappingHeight)
{
if (_viewportPosition.y > 1)
{
_newPosition.y = _camera.ViewportToWorldPoint (Vector2.zero).y;
isWrappingHeight = true;
}
else if (_viewportPosition.y < 0)
{
_newPosition.y = _camera.ViewportToWorldPoint (Vector2.one).y;
isWrappingHeight = true;
}
}
}
_transform.position = _newPosition;
}
private bool IsBeingRendered ()
{
if (_renderer.isVisible)
return true;
return false;
}
}