- Home /
Moving Platforms and Efficient Code
Hello, I've created moving platforms in my game that can move left, right, up, or down at the flip of a switch. The code will automatically determine which direction the platform should move based on its moveSpeed, whether it has a distanceX or distanceY value, and if it's in its original or second position.
I have two questions. Firstly, my platform lever uses an OnTriggerStay2D method. It will work the first time I trigger the switch, but I have to move at least one frame before I can trigger the switch again. Is there a better way of doing this?
public class PlatformLever : MonoBehaviour
{
[SerializeField] GameObject platform;
public void OnTriggerStay2D(Collider2D collision)
{
if (CrossPlatformInputManager.GetButtonDown("Vertical"))
{
platform.GetComponent<SwitchablePlatform>().SwitchOn();
}
}
}
Secondly, the platform generally works fine when it's triggered, but I feel like I really brute-forced my way through the code with a lot of if statements and repeated logic. I'm very new to coding so I don't know a lot of best practices or clever tricks yet. I'm wondering if anyone would be kind enough to take a look at my code and either give me some helpful pointers on making it more efficient or pointing me in a direction where I could look for a more efficient way of doing it.
[DisallowMultipleComponent]
public class SwitchablePlatform : MonoBehaviour
{
[Header("Movement Parameters")]
[SerializeField] float moveSpeed = 1f; // a negative moveSpeed will cause the platform to move backwards
// the platform will automatically determine which direction to move based on the below two variables
[SerializeField] float distanceX = 2f;
[SerializeField] float distanceY = 0f;
[Header("Movement Logic")]
bool inOriginalPosition = true;
bool inSecondPosition = false;
bool isMoving = false;
Vector2 originalPosition;
Vector2 secondPosition;
bool horizontalMovement = false; // when isMoving is true, this will cause the platform to move Horizontally
bool verticalMovement = false; // when isMoving is true, this will cause the platform to move vertically
// Start is called before the first frame update
void Start()
{
originalPosition = transform.position;
if (distanceX != 0 && distanceY != 0)
{
Debug.Log("Platform should only move in one direction");
}
else if (distanceX > 0 && distanceY == 0)
{
SetHorizontalMovement();
}
else if (distanceX == 0 && distanceY > 0)
{
SetVerticalMovement();
}
}
private void SetHorizontalMovement()
{
horizontalMovement = true;
verticalMovement = false;
// the below is used to reinforce the final position of the platform since it won't move to exactly 0 or 0 +- distance
if (moveSpeed >= 0)
{
secondPosition = new Vector2(originalPosition.x + distanceX, originalPosition.y);
}
else if (moveSpeed < 0)
{
secondPosition = new Vector2(originalPosition.x - distanceX, originalPosition.y);
}
}
private void SetVerticalMovement()
{
horizontalMovement = false;
verticalMovement = true;
// the below is used to reinforce the final position of the platform since it won't move to exactly 0 or 0 +- distance
if (moveSpeed >= 0)
{
secondPosition = new Vector2(originalPosition.x, originalPosition.y + distanceY);
}
else if (moveSpeed < 0)
{
secondPosition = new Vector2(originalPosition.x, originalPosition.y - distanceY);
}
}
// Update is called once per frame
void Update()
{
if(isMoving == true)
{
Moving();
}
else
{
return;
}
}
public void SwitchOn() // this is called from PlatformLever.cs
{
isMoving = true;
}
private void Moving()
{
if (!horizontalMovement && !verticalMovement)
{
return;
}
else if(horizontalMovement) // determined during Start
{
MoveHorizontal();
}
else if(verticalMovement) // determined during Start
{
MoveVertical();
}
}
public void MoveHorizontal()
{
float movementXThisFrame = moveSpeed * Time.deltaTime;
Vector2 currentPosition = transform.position;
float xPos = originalPosition.x;
float xCurrent = transform.position.x;
float movementTracker = xCurrent - xPos; // measure the distance between the current x position and the original x position
// Moving Right
if (inOriginalPosition) // will move to (roughly) its second position and stop
{
if (Mathf.Abs(movementTracker) < distanceX)
{
transform.position = new Vector2(currentPosition.x + movementXThisFrame, originalPosition.y);
}
else if (Mathf.Abs(movementTracker) >= distanceX)
{
transform.position = secondPosition; // used to reinforce the final position of the platform since it won't move to exactly 0 or 0 +- distance
inOriginalPosition = false;
inSecondPosition = true;
isMoving = false;
}
}
else if (inSecondPosition) // will move to (roughly) its original position and stop
{
if (movementTracker < 0)
{
transform.position = new Vector2(currentPosition.x - movementXThisFrame, originalPosition.y);
}
else if (movementTracker >= 0)
{
transform.position = originalPosition;
inOriginalPosition = true;
inSecondPosition = false;
isMoving = false;
}
}
}
private void MoveVertical()
{
float movementYThisFrame = moveSpeed * Time.deltaTime;
Vector2 currentPosition = transform.position;
float yPos = originalPosition.y;
float yCurrent = transform.position.y;
float movementTracker = yCurrent - yPos; // measure the distance between the current y position and the original y position
if (inOriginalPosition) // will move to (roughly) its second position and stop
{
if (Mathf.Abs(movementTracker) < distanceY)
{
transform.position = new Vector2(originalPosition.x, currentPosition.y + movementYThisFrame);
}
else if (Mathf.Abs(movementTracker) >= distanceY)
{
transform.position = secondPosition; // used to reinforce the final position of the platform since it won't move to exactly 0 or 0 +- distance
inOriginalPosition = false;
inSecondPosition = true;
isMoving = false;
}
}
else if (inSecondPosition) // will move to (roughly) its original position and stop
{
if (movementTracker < 0)
{
transform.position = new Vector2(originalPosition.x, currentPosition.y - movementYThisFrame);
}
else if (movementTracker >= 0)
{
transform.position = originalPosition;
inOriginalPosition = true;
inSecondPosition = false;
isMoving = false;
}
}
}
}
Thank you very much for taking the time to look at all of this. I really appreciate any help I receive.