1
\$\begingroup\$

I have a player object which position is always centered on the main camera's viewport. This object has a Rigidbody 2D, a box and circle collider. The player moves around a level, the level has a polygon collider attached.

I move the camera until the object hits against the collider, which stops the movement of the camera by setting its speed to 0. The problem happens when I want to move the camera / player object away from the collider. As the speed is already at 0, it cannot move away from the collider.

The script attached to the player object, checks for collisions and applies the speed to 0 on the main camera's test script.

using UnityEngine;
using System.Collections;

public class move : MonoBehaviour {
public float speed;
public test testing;
// Use this for initialization
void Start () {
     speed = 10F;
    testing = Camera.main.GetComponent<test>();
}

// Update is called once per frame
void FixedUpdate () {
    Vector3 p = Camera.main.ViewportToWorldPoint(new Vector3(0.5F, 0.5F, Camera.main.nearClipPlane));
    transform.position = new Vector3(p.x, p.y, -1);

}

void OnCollisionEnter2D(Collision2D col) {


    testing.speed = 0;

}
void OnCollisionExit2D(Collision2D col) {


    testing.speed = 10F;

}

}

This is the script attached to the main camera; just a simple script that changes the camera's position.

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {
public float speed;
public float translationY;
public float translationX;
// Use this for initialization
void Start () {

    speed = 10F;
}

void FixedUpdate () {
     translationY = Input.GetAxis("Vertical") * speed * Time.deltaTime;
     translationX = Input.GetAxis("Horizontal") * speed * Time.deltaTime;

    transform.Translate(translationX, translationY, 0);
}

}

The player object isn't kinematic and is a fixed angle, the colliders aren't triggers and the polygon collider isn't a trigger either.

The player is the red square, the collider is the pink area.

enter image description here

-- EDIT --

From the latest change the collider set up for the player

enter image description here

So if the X speed was disabled. It wouldnt move into the side of the polygon colider which is good, but yet you couldnt move away from it. And moving down would move inside the colider.

\$\endgroup\$
2
\$\begingroup\$

Add a flag to determine if the player has been stopped. At that point, stop setting the players position to the camera's, and instead some other input.

public float speed;
public test testing;
bool stopped = false;
// Use this for initialization
void Start () {
    speed = 10f;
    testing = Camera.main.GetComponent<test>();
}

// Update is called once per frame
void FixedUpdate () {
    if (!stopped)
    {
        Vector3 p = Camera.main.ViewportToWorldPoint(new Vector3(0.5F, 0.5F, Camera.main.nearClipPlane));
        transform.position = new Vector3(p.x, p.y, -1);
    }

    else
    {
        //move away here
    }
}

void OnCollisionEnter2D(Collision2D col) {
    stopped = true;
    testing.speed = 0;

}
void OnCollisionExit2D(Collision2D col) {
    stopped = false;
    testing.speed = 10f;
}

Edit

Seeing how you move the camera, in your camera script I would have two different speeds

public float speedX;
public float speedY;
public float translationY;
public float translationX;
// Use this for initialization
void Start () {
    speedX = 10F;
    speedY = 10F;
}

void FixedUpdate () {
     translationY = Input.GetAxis("Vertical") * speedX * Time.deltaTime;
     translationX = Input.GetAxis("Horizontal") * speedY * Time.deltaTime;

    transform.Translate(translationX, translationY, 0);
}

Then you can omit the flag I talked about previously, and only modify speedY so the player can still move to the side.

public float speed;
public test testing;
// Use this for initialization
void Start () {
    speed = 10F;
    testing = Camera.main.GetComponent<test>();
}

// Update is called once per frame
void FixedUpdate () {
    Vector3 p = Camera.main.ViewportToWorldPoint(new Vector3(0.5F, 0.5F, Camera.main.nearClipPlane));
    transform.position = new Vector3(p.x, p.y, -1);
}

void OnCollisionEnter2D(Collision2D col) {
    testing.speedY = 0;

}
void OnCollisionExit2D(Collision2D col) {
    testing.speedY = 10F;

}

Edit 2

Using this SO question we can determine where the collision was. We can then modify our code to be

void OnCollisionEnter2D(Collision2D col) {
    var relativePosition = transform.InverseTransformPoint(col.contacts);
    if (abs(relativePosition.position.x) > abs(relativePosition.position.y))
        testing.speedX = 0;
    else
        testing.speedY = 0;
}

void OnCollisionExit2D(Collision2D col) {
    testing.speedY = 10F;
    testing.speedX = 10F;
}
\$\endgroup\$
  • \$\begingroup\$ It does work but only if it has collided into the side of the player. There must be a more elegant solution to this. \$\endgroup\$ – Matthew Underwood Aug 22 '14 at 20:14
  • \$\begingroup\$ @MatthewUnderwood Check edits \$\endgroup\$ – Liam McInroy Aug 22 '14 at 20:46
  • \$\begingroup\$ I am getting type or namespace name cannot be found 'transform' error on line transform relativePosition = transform.InverseTransformPoint(collision.contacts); \$\endgroup\$ – Matthew Underwood Aug 22 '14 at 21:07
  • \$\begingroup\$ @MatthewUnderwood Sorry I had a few typos... Check edits \$\endgroup\$ – Liam McInroy Aug 23 '14 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.