Unity 2D:如何与屏幕侧面碰撞

时间:2018-05-21 09:42:17

标签: c# android unity3d collider

我目前正在使用Android的2D游戏。我的场景中有一个玩家,如果用户倾斜他的设备,则玩家对象正在地面上移动。但他只是在左侧和右侧移出屏幕。我试图做一个“墙”,但我没有成功。在我的玩家-Gameobject中有一个边缘对撞机。现在我的问题是:我的玩家游戏对象如何与屏幕侧面相撞?

这是我的代码:

public GameObject player;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        Vector3 dir = Vector3.zero;
        dir.y = Input.acceleration.x;

        player.transform.Translate(new Vector2(dir.y, 0) * Time.deltaTime * 2000f);  

    }

非常感谢! :)

编辑:

图像1是我的墙,而图像2是我的播放器。

我正试图用屏幕一侧的墙来解决它。这些是This is the image of my players inspector. Did I add the right things?

的图像

This is the inspector of my player.

解决

解决方案代码:

Vector3 position = player.transform.position;
        translation = Input.acceleration.x * movementSpeed * 50f;

        if (player.transform.position.x + translation < LeftlimitScreen)
        {
            position.x = -LeftlimitScreen;
        } 
        else if(transform.position.x + translation > RightlimitScreen)
        {
            position.x = RightlimitScreen;
        }
        else
        {
            position.x += translation;
            player.transform.position = position;
        }

这段代码对我有用! :)

4 个答案:

答案 0 :(得分:3)

这将在屏幕周围生成边缘碰撞(2d):

void GenerateCollidersAcrossScreen()
    {
     Vector2 lDCorner = camera.ViewportToWorldPoint(new Vector3(0, 0f, camera.nearClipPlane));
     Vector2 rUCorner = camera.ViewportToWorldPoint(new Vector3(1f, 1f, camera.nearClipPlane));
     Vector2[] colliderpoints;

    EdgeCollider2D upperEdge = new GameObject("upperEdge").AddComponent<EdgeCollider2D>();
    colliderpoints = upperEdge.points;
    colliderpoints[0] = new Vector2(lDCorner.x, rUCorner.y);
    colliderpoints[1] = new Vector2(rUCorner.x, rUCorner.y);
    upperEdge.points = colliderpoints;

    EdgeCollider2D lowerEdge = new GameObject("lowerEdge").AddComponent<EdgeCollider2D>();
    colliderpoints = lowerEdge.points;
    colliderpoints[0] = new Vector2(lDCorner.x, lDCorner.y);
    colliderpoints[1] = new Vector2(rUCorner.x, lDCorner.y);
    lowerEdge.points = colliderpoints;

    EdgeCollider2D leftEdge = new GameObject("leftEdge").AddComponent<EdgeCollider2D>();
    colliderpoints = leftEdge.points;
    colliderpoints[0] = new Vector2(lDCorner.x, lDCorner.y);
    colliderpoints[1] = new Vector2(lDCorner.x, rUCorner.y);
    leftEdge.points = colliderpoints;

    EdgeCollider2D rightEdge = new GameObject("rightEdge").AddComponent<EdgeCollider2D>();

    colliderpoints = rightEdge.points;
    colliderpoints[0] = new Vector2(rUCorner.x, rUCorner.y);
    colliderpoints[1] = new Vector2(rUCorner.x, lDCorner.y);
    rightEdge.points = colliderpoints;
}

答案 1 :(得分:1)

你可以放置在场景之外,在你的设备中显示的区域之外2个带有对撞机的空游戏对象,这样玩家就会对它们造成撞击。

您还可以通过代码限制播放器内的边界移动。您可以使用Mathf.Clamp()来应用它,并且您需要在场景的x坐标中设置边界。

您将看到,我们不是使用变换来修改玩家的位置,而是使用刚体。

public class PlayerController : MonoBehaviour
{
    public float speed;
    public float tilt;
    public Boundary boundary;

    void FixedUpdate ()
    {
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
        rigidbody.velocity = movement * speed;

        rigidbody.position = new Vector3 
        (
            Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax), 
            0.0f, 
            5.0f 
        );

    }
}

您可以在此处查看整个教程:https://unity3d.com/earn/tutorials/projects/space-shooter/moving-the-player?playlist=17147

更新其他选项:

//You select here the speed you consider
float speed = 1.0f; 

void Update () {

    Vector3 dir = Vector3.zero;

    float InputValue = Input.acceleration.x * speed;

    //You need to set the values for this limits (max and min) based on your scene
    dir.y = Mathf.Clamp(InputValue, 0.5f, 50.5f);

    player.transform.position = dir;  

}

更新2:

没有Clamp,只需在脚本上设置限制

void Update () {
     Vector3 position = player.transform.position ;
     translation = Input.acceleration.x * speed;
     if( player.transform.position.y + translation < leftLimitScreen )
         position.y = -leftLimitScreen ;
     else if( myTransform.position.x + translation > rightLimitScreen )
         position.y = rightLimitScreen ;
     else
         position.y += translation ;
     player.transform.position = position ;
 }

答案 2 :(得分:0)

在我创建解决方案的原型中,我已经到达的是创建“墙”,边框中没有精灵的对象,并检查Raycast是否有类似这样的脚本:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class PlayerController : MonoBehaviour {
        RaycastHit2D[] hit;
        Vector2[] directions;
        private Vector2 targetPosition;
        private float moveSpeed;
        private float moveHDir;
        private float wallPos;
        private bool hitLeft;
        private bool hitRight;

        // Use this for initialization
        void Start () {
            directions = new Vector2[2] {Vector2.right, Vector2.left};
            hitLeft = false;
            hitRight = false;
        }

        // Update is called once per physics timestamp
        void FixedUpdate () {
            foreach (Vector2 dir in directions) {
                hit = Physics2D.RaycastAll(transform.position, dir);
                Debug.DrawRay(transform.position, dir);

                if (hit[1].collider != null) {

                    // Keyboard control
                    if (Input.GetAxisRaw("Horizontal") != 0) {
                        moveHDir = Input.GetAxisRaw("Horizontal");

                        // I have found that a 5% of the size of the object it's a 
                        // good number to set as a minimal distance from the obj to the borders
                        if (hit[1].distance <= (transform.localScale.x * 0.55f)) {

                            if (dir == Vector2.left) {
                                hitLeft = true;
                            } else {
                                hitRight = true;
                            }

                            wallPos = hit[1].collider.transform.position.x;

                            // Condition that guarantee that the paddle do not pass the borders of the screen
                            // but keeps responding if you try to go to the other side
                            if ((wallPos > this.transform.position.x && moveHDir < 0) ||
                                (wallPos < this.transform.position.x && moveHDir > 0)) {
                                    moveSpeed = gControl.initPlayerSpeed;
                            } else {
                                moveSpeed = 0;
                            }
                        } else {
                            if (dir == Vector2.left) {
                                hitLeft = false;
                            } else {
                                hitRight = false;
                            }

                            if (!hitRight && !hitLeft)
                            {
                                moveSpeed = gControl.initPlayerSpeed;
                            }
                        }
                    }
                }
            }
            targetPosition = new Vector2((transform.position.x + (moveSpeed * moveHDir)), transform.position.y);
        }
    }

也许这不是最好的解决方案,也不是最短的解决方案,但它对我有用。

祝你好运。

答案 3 :(得分:0)

如果你想在画布(2D)的边界上生成碰撞器

将此脚本附加到主画布对象中。

using UnityEngine;

public class BorderCollider: MonoBehaviour 
{
    private EdgeCollider2D _edgeCollider2D;
    private Rigidbody2D _rigidbody2D;
    private Canvas _canvas;
    private float y, x;
    private Vector2 _topLeft, _topRight, _bottomLeft, _bottomRight;

    private void Start() {
        //Adding Edge Collider
        _edgeCollider2D = gameObject.AddComponent<EdgeCollider2D>();
        
        //Adding Rigid body as a kinematic for collision detection
        _rigidbody2D = gameObject.AddComponent<Rigidbody2D>();
        _rigidbody2D.bodyType = RigidbodyType2D.Kinematic;
        
        //Assigning canvas
        _canvas = GetComponent<Canvas>();
        
        GetCanvasDimension(); // Finds height and width fo the canvas
        GetCornerCoordinate(); // Finds co-ordinate of the corners as a Vector2
        DrawCollider(); // Draws Edge collide around the corners of canvas
    }

    public void GetCornerCoordinate() {
        // Assign corners coordinate in the variables
        
        _topLeft = new Vector2(-x,y); // Top Left Corner
        _topRight = new Vector2(x,y); // Top Right Corner
        _bottomLeft = new Vector2(-x,-y); // Bottom Left Corner
        _bottomRight = new Vector2(x,-y); // Bottom Right Corner
        
    }

    void GetCanvasDimension(){
        y = (_canvas.GetComponent<RectTransform>().rect.height) / 2;
        x = (_canvas.GetComponent<RectTransform>().rect.width) / 2;
    }

    void DrawCollider() {
        _edgeCollider2D.points = new[] {_topLeft, _topRight, _bottomRight, _bottomLeft,_topLeft};
    }

}