【问题标题】:How to re-position game object to the left side of the screen when it goes off the right side of the screen?当游戏对象离开屏幕右侧时,如何将其重新定位到屏幕左侧?
【发布时间】:2015-06-10 15:22:29
【问题描述】:

我目前正在开发一款肖像游戏,我正在尝试实现类似游戏 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 纵横比的设备上完美运行,但在其他纵横比的设备上却不行。

无论屏幕纵横比如何,如何检测屏幕边缘以使其正常工作?

谢谢

【问题讨论】:

  • 查看本教程,因为它不使用屏幕边界之外的任何对象来检查其位置。 youtu.be/VAmlb913-jc

标签: unity3d


【解决方案1】:

我制作了 2 个资源来解决这个问题:

对象边缘 2D 和相机边缘

它们允许您简单地编写:

if( player.GetLeftPosition().x > myCamera.GetRightPosition(10))

     player.MoveRightPosition(myCamera.GetLeftPosition(10));
  • 它们适用于任何游戏对象比例、精灵轴、碰撞器大小或偏移量

资产链接:

2D 对象边缘: http://u3d.as/wkF

相机边缘: http://u3d.as/xxB

希望它可以帮助您并节省您的时间。

【讨论】:

    【解决方案2】:

    我更喜欢放置两个标明左右界限的空对象。

    如果角色超出游戏边界(在左边界的左侧,或在右边界的右侧),您可以检查更新(或仅在角色移动以提高性能时)并相应地修复它的位置:

    类似:

    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 个空对象放置在屏幕的左/右边缘而不依赖于设备的屏幕尺寸?你知道,不用目不转睛。对 Unity 来说还是新手,抱歉。
    • 我习惯在 SpriteKit 中进行游戏编程。在那里,我只是使用 0 来获得左边缘和 size.width 来获得右边缘。 Unity中有类似的东西吗?
    • 也许使用Camera 来获得世界积分。看看这个:answers.unity3d.com/questions/537081/…
    【解决方案3】:

    此脚本用于在屏幕边界(视口)内包裹对象。你所做的就是把这个脚本放到你的游戏对象上,剩下的就交给它了。相机外部不需要碰撞器,它只是放置和播放。您还可以设置公共布尔值以确定您是否希望您的游戏对象在宽度、高度或两者上换行。视频教程在这里: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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 2015-03-17
      • 2016-01-03
      • 1970-01-01
      • 2021-07-14
      相关资源
      最近更新 更多