- Home /
Object gets stuck outside boundary if pushed
Hi, I'm writing a script which controls an object which moves randomly around the 2D play area. The idea is that the game ends if the player runs into it, but for now I'm having a little trouble with the movement. I've used a random movement script (perhaps not the best one) which selects random x and y components for a vector and then uses that to alter the Transform. I've also used Mathf.Clamp to stop it leaving the boundary area alongside a little code to turn it when it reaches the boundary and gets it out of corners, both of which are really just there to keep it moving smoothly. Finally, I've added a boolean loop which causes it to head towards the player if the player gets too close (this doesn't need to be in a boolean at the moment but I was thinking of adding some things which would use it and I don't think it's the problem in any case).
This works to a certain extent, but I've found that the player can push the object out of the boundary, at which point it's then stuck outside/at the boundary. Technically this isn't a problem at the moment as I'm going to code in a collision with the player ending the game, but I'd whether fix it now rather than come across it again if I add another feature.
I've done some checking and removing all the boundary related scripts (detect corner, reverse direction at boundary, and mathf.clamp) fixes the problem, but removing only 1 of these doesn't so I can't say for certain the exact issue. Any help would be appreciated. Apologies for the long code, I'm not 100% certain the problem so I thought it best to include the whole thing.
using UnityEngine; using System.Collections;
public class BabyControllerScript : MonoBehaviour {
private float tChange =0;
private float randomX;
private float randomY;
private float RandomTurn;
public float moveSpeed;
public Boundary boundary;
public float AllowedTurn;
private Quaternion Turn;
public GameObject player;
private Vector2 PlayerPositionX;
private Vector2 StartDirection;
private Vector2 FinalDirection;
//for coerner logic
private bool InCorner;
public float CornerLimitX;
public float CornerLimitY;
private float RanX1;
private float RanX2;
private float RanY1;
private float RanY2;
private float TempRanX;
private float TempRanY;
private float EndCornerExit;
//for too close feature
public float TooClose;
public float TooCloseTime;
private float EndTooClose;
//for move towards cat feature
private bool CloseToPlayer;
public float ClosePlayerDist;
// Use this for initialization
void Start () {
InCorner = false;
CloseToPlayer = false;
}
// Update is called once per frame
void FixedUpdate ()
{
// loop used for moving towards player if too close
if ((player.GetComponent<Rigidbody2D> ().position - GetComponent<Rigidbody2D> ().position).magnitude <= ClosePlayerDist) {
CloseToPlayer = true;
} else {
CloseToPlayer = false;
}
if ( CloseToPlayer == true){
FinalDirection = player.GetComponent<Rigidbody2D> ().position - GetComponent<Rigidbody2D> ().position;
//performs the actual movement
transform.Translate (FinalDirection.normalized * moveSpeed * Time.fixedDeltaTime);
//Makes sure the object doesn't leave the borders
GetComponent<Rigidbody2D> ().position = new Vector2
(
Mathf.Clamp (GetComponent<Rigidbody2D> ().position.x, boundary.minX, boundary.maxX),
Mathf.Clamp (GetComponent<Rigidbody2D> ().position.y, boundary.minY, boundary.maxY)
);
}
//loop used for changing to random direction at random intervals
else {
if (Time.time >= tChange) {
//prevents corner exit loop
if (Time.time >= EndCornerExit) {
InCorner = false;
}
//Direction select loop
if (InCorner == true) {
TempRanX = Random.Range (RanX1, RanX2);
TempRanY = Random.Range (RanY1, RanY2);
FinalDirection = new Vector2 (TempRanX, TempRanY);
} else {
TempRanX = Random.Range (-1.0f, 1.0f);
TempRanY = Random.Range (-1.0f, 1.0f);
FinalDirection = new Vector2 (TempRanX, TempRanY);
}
// set a random interval between 0.5 and 1.5
tChange = Time.time + Random.Range (0.25f, 1.0f);
}
//performs the actual movement
transform.Translate (FinalDirection.normalized * moveSpeed * Time.fixedDeltaTime);
//reverts direction because it reached a border
if (transform.position.x >= boundary.maxX || transform.position.x <= boundary.minX) {
FinalDirection.x = -FinalDirection.x;
}
if (transform.position.y >= boundary.maxY || transform.position.y <= boundary.minY) {
FinalDirection.y = -FinalDirection.y;
}
//Checks whether to activate corner exit loop
if (boundary.maxX - transform.position.x <= CornerLimitX) {
if (boundary.maxY - transform.position.y <= CornerLimitY) {
//+ve x +ve y
InCorner = true;
RanX1 = -1.0f;
RanX2 = 0.0f;
RanY1 = -1.0f;
RanY2 = 0.0f;
EndCornerExit = Time.time + Random.Range (2.0f, 3.0f);
} else if (-boundary.maxY - transform.position.y >= CornerLimitY) {
//+ve x -ve y
InCorner = true;
RanX1 = -1.0f;
RanX2 = 0.0f;
RanY1 = 0.0f;
RanY2 = 1.0f;
}
}
if (-boundary.maxX - transform.position.x >= CornerLimitX) {
if (boundary.maxY - transform.position.y <= CornerLimitY) {
//-ve x +ve y
InCorner = true;
RanX1 = 0.0f;
RanX2 = 1.0f;
RanY1 = -1.0f;
RanY2 = 0.0f;
EndCornerExit = Time.time + Random.Range (2.0f, 3.0f);
}
else if (-boundary.maxY - transform.position.y >= CornerLimitY) {
//-ve x -ve y
InCorner = true;
RanX1 = 0.0f;
RanX2 = 1.0f;
RanY1 = 0.0f;
RanY2 = 1.0f;
}
}
//Makes sure the Object doesn't leave the borders
GetComponent<Rigidbody2D> ().position = new Vector2
(
Mathf.Clamp (GetComponent<Rigidbody2D> ().position.x, boundary.minX, boundary.maxX),
Mathf.Clamp (GetComponent<Rigidbody2D> ().position.y, boundary.minY, boundary.maxY)
);
}
}
}