0
\$\begingroup\$

The program is in a top down view, with Y going up (or forward depending upon how you see it), and X going from left to right based on the camera view. I am attempting to set the minimum and maximum values of my main character's x/y-axis movement through the float "clamp", under the struct "Mathf".

When my ship passes the minimum/maximum value on either axis, it doesn't stop it. If you release the movement key after passing the point, the character will appear directly on the minimum/maximum point that was passed. See the gif below.

Gif here http://gph.is/22fdHv4

Below is the current script running for both player movement and the boundary, attached to the main character.

using UnityEngine;
using System.Collections;

public class ShipMovement : MonoBehaviour {

public float xMin;
public float xMax;
public float yMin;
public float yMax;
public float speed = 2f;
public float shotSpeed = 4f;
public float nextFire1;
public float nextFire2;
//Animator anim;
public GameObject shot;
public Transform shotSpawn;
public float fireRate = 0.25f;

void Start () {

//anim = GetComponent<Animator> ();
}

void FixedUpdate () {

        GetComponent<Rigidbody> ().position = new Vector3 (
            Mathf.Clamp (transform.position.x, xMin, xMax ),
            Mathf.Clamp (transform.position.y, yMin, yMax),
            0.0f
        );

        if (Input.GetKey (KeyCode.W)) {
        transform.Translate (Vector2.up * speed * Time.deltaTime);
        //anim.SetBool ("moving", true);
    } 
        if (Input.GetKey (KeyCode.S)) {
        transform.Translate (Vector2.down * speed * Time.deltaTime);
        //anim.SetBool ("moving", true);
    }
        if (Input.GetKey (KeyCode.A)) {
        transform.Translate (Vector2.left * speed * Time.deltaTime);
        //anim.SetBool ("moving", true);
    } 
        if (Input.GetKey (KeyCode.D)) {
        transform.Translate (Vector2.right * speed * Time.deltaTime);
        //anim.SetBool ("moving", true);
    } else {
        //anim.SetBool ("moving", false);
    }

    if (Input.GetKey (KeyCode.Space) && Time.time > nextFire1)
    {
        nextFire1 = Time.time + fireRate;
        Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
    }

    if (Input.GetKey (KeyCode.X) && Time.time > nextFire2) {
        nextFire2 = Time.time + fireRate;
        Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
    }

    if (gameObject == null) {
        Application.Quit ();
      }
   }
}

Although I am not sure, I suspect it may have something to with the way I am controlling the movement. I have had issues with what I have written in the past, especially with animations and moving left/right while also moving up/down. (Hence why I have all of the animation code commented out, and I am using a Capsule instead of a ship).

If anything else is needed, I can provide it.

\$\endgroup\$
1
\$\begingroup\$

Set the position after you calculate that it is inside your bounds. This will also account for pressing multiple keys at the same time.

Vector3 newPosition;

if (Input.GetKey (KeyCode.W)) {
    newPosition = transform.position + Vector2.up * speed * Time.deltaTime;
    //anim.SetBool ("moving", true);
} 

GetComponent<Rigidbody> ().position = new Vector3 (
    Mathf.Clamp (newPosition.x, xMin, xMax ),
    Mathf.Clamp (newPosition.y, yMin, yMax),
        0.0f
);
\$\endgroup\$
  • \$\begingroup\$ sorry for the late response - will test when i get home \$\endgroup\$ – AspiringGenious Dec 21 '15 at 12:15
  • \$\begingroup\$ Well it has been a busy few weeks! I haven't forgotten! This worked perfectly. The only thing I am failing to understand is why it would continue outside of the bounds until I release the movement key, not reset continually back to the bounding location. \$\endgroup\$ – AspiringGenious Jan 8 '16 at 18:18
  • \$\begingroup\$ Strange. Can I take a look at your updated code? \$\endgroup\$ – Mattias Jan 8 '16 at 19:47
1
\$\begingroup\$

Updated

I can observe more than one reason. May be Before After, may be this is due to vector3.x or vector3.y cannot be modified in c#.

First of all kindly change FixedUpdate to Update. And from now please don't get inputs in FixedUpdate otherwise you will get Jerks in getting input. Now Replace your whole FixedUpdate to these lines of code.

void Update(){

    transform.position = new Vector3(Mathf.Clamp(transform.position.x + Input.GetAxis("Horizontal") * speed,xMin,xMax), Mathf.Clamp(transform.position.y + Input.GetAxis("Vertical") * speed,yMin,yMax), transform.position.z);

    if (Input.GetAxis("Horizontal") || Input.GetAxis("Vertical"))
        anim.SetBool ("moving", true);
    else
        anim.SetBool ("moving", false);

    if (Input.GetKey (KeyCode.Space) && Time.time > nextFire1){
        nextFire1 = Time.time + fireRate;
        Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
    }

    if (Input.GetKey (KeyCode.X) && Time.time > nextFire2) {
        nextFire2 = Time.time + fireRate;
        Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
    }

    if (gameObject == null) {
        Application.Quit ();
      }
}
\$\endgroup\$
0
\$\begingroup\$

Well. That's because you clamp the values before accounting for the keys being pressed. So the position is clamped to the bounds, then the player moves out of bounds.

\$\endgroup\$

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.