如何在不同的屏幕分辨率下拥有相同大小的对象?

时间:2016-06-17 23:46:33

标签: unity3d unity3d-2dtools

我正在Unity中开展2D游戏。我正在为Android开发它,它是在纵向模式下。我在屏幕的左侧放置了一面墙,在屏幕的右侧放置了一面墙。问题是这两个墙之间的距离在不同的屏幕分辨率下是不同的。因此,我的角色不能以相同的速度从一个墙跳到另一个墙。 我正在附上一张图片,以明确我的观点。Comparison

我可以做些什么,以便在不同的设备中,这两个墙之间的距离相同?任何帮助将不胜感激。

编辑:这就是我现在正在放置墙壁的方式。

screenLeft = Camera.main.ScreenToWorldPoint (new Vector3 (0f, 0f, 0f)).x;
screenRight = Camera.main.ScreenToWorldPoint (new Vector3 (Screen.width, 0f, 0f)).x;

rightWallSizeX = rightWall.GetComponent<SpriteRenderer> ().bounds.size.x;
leftWallSizeX = leftWall.GetComponent<SpriteRenderer> ().bounds.size.x;

rightWall.transform.position = new Vector3 (screenRight - rightWallSizeX/2, 0f, 0f);
leftWall.transform.position = new Vector3 (screenLeft + leftWallSizeX/2, 0f, 0f);

1 个答案:

答案 0 :(得分:2)

如果您使用编辑器设计关卡:

enter image description here

然后输出方面将是正确的,无论其值如何:

enter image description here

enter image description here

作为奖励,我制作了一些代码,让玩家可以贴墙并跳到另一边:D

using UnityEngine;

namespace Assets
{
    public class PlayerController : MonoBehaviour
    {
        private const string Ground = "Ground";
        private const string Wall = "Wall";

        private Rigidbody2D _body;
        private Vector2 _cNormal;
        private GameObject _cWall;
        private bool _joyAction;
        private float _joyClimb;
        private float _joyMove;
        private State _state;

        public float ForceClimb = 20.0f;
        public float ForceJump = 5.0f;
        public float ForceJumpFromWall = 10.0f;
        public float ForceMove = 10.0f;
        public float MaxMove = 15.0f;

        private void Start()
        {
            _state = State.Air;
        }

        private void OnEnable()
        {
            _body = GetComponent<Rigidbody2D>();
        }

        private void Update()
        {
            _joyMove = Input.GetAxis("Horizontal");
            _joyClimb = Input.GetAxis("Vertical");
            _joyAction = Input.GetButtonDown("Fire1");
        }

        private void FixedUpdate()
        {
            var air = _state == State.Air;
            var ground = _state == State.Ground;
            var wall = _state == State.Wall;

            if (air || ground)
            {
                var canJump = ground && _joyAction;
                if (canJump)
                {
                    var force = new Vector2(0.0f, ForceJump);
                    _body.AddForce(force, ForceMode2D.Impulse);
                    _state = State.Air;
                }

                var move = transform.InverseTransformDirection(_body.velocity).x;
                if (move < MaxMove)
                {
                    var force = new Vector2(_joyMove*ForceMove, 0.0f);
                    _body.AddRelativeForce(force);
                }
            }
            else if (wall)
            {
                var climbing = Mathf.Abs(_joyClimb) > 0.0f;
                if (climbing)
                {
                    _body.AddForce(new Vector2(0, ForceClimb*_joyClimb));
                }
                else
                {
                    var jumpingOut = _joyAction;
                    if (jumpingOut)
                    {
                        TryUnstickFromWall();
                        _body.AddForce(_cNormal*ForceJumpFromWall, ForceMode2D.Impulse);
                    }
                }
            }
        }

        private void OnGUI()
        {
            GUILayout.Label(_state.ToString());
        }

        public void OnCollisionEnter2D(Collision2D collision)
        {
            var c = collision.collider;
            var t = c.tag;
            if (t == Ground)
            {
                _state = State.Ground;
                TryUnstickFromWall(); // fixes wall-sticking
            }
            else if (t == Wall && _state == State.Air) // jumping to wall
            {
                var wall = collision.gameObject;
                var joint2D = wall.AddComponent<FixedJoint2D>();
                var contact = collision.contacts[0];
                var normal = contact.normal;
                Debug.DrawRay(contact.point, normal, Color.white);

                // stick 2 wall
                joint2D.anchor = contact.point;
                joint2D.frequency = 0.0f;
                joint2D.autoConfigureConnectedAnchor = false;
                joint2D.enableCollision = true;
                _body.constraints = RigidbodyConstraints2D.FreezePositionX;
                _body.gravityScale = 0.125f;

                // save these
                _cWall = wall;
                _cNormal = normal;

                // update state
                _state = State.Wall;
            }
        }

        public void OnCollisionExit2D(Collision2D collision)
        {
            if (collision.collider.tag == Ground)
            {
                _state = State.Air;
            }
        }

        private void TryUnstickFromWall()
        {
            if (_cWall != null)
            {
                _body.constraints = RigidbodyConstraints2D.None;
                _body.gravityScale = 1.0f;
                var joint2D = _cWall.GetComponent<FixedJoint2D>();
                if (joint2D != null) Destroy(joint2D);
                _cWall = null;
            }
        }
    }

    internal enum State
    {
        Air,
        Ground,
        Wall
    }
}

试一试:

  • 创建一个类似于图片1中的布局
  • 向所有人添加Rigidbody2DBoxCollider2D
  • 将他们的刚体设置为运动
  • 将此脚本添加到播放器
  • 将墙壁标记设置为Wall
  • 将地面标记设置为Ground

然后调整它以满足您的需求......

修改

你必须将transform.InverseTransformDirection(_body.velocity).xMathf.Abs()包含在一起才能正确,有时碰撞正常会被反转,让玩家卡在墙上,我让你想到这一个:)