Hi,
Im working on a game where you need to move a cube past multiple obstacles (also cubes). Im trying to add some obstacles that move from one side of the track to the other, and soon as they reach one of the sides, they start to move to the other again. For efficiency i want to controll all of them with just 1 C# script.
My code works perfectly, as long as there is just 1 moving obstacle. Soon as I add more they will move to one of the sides and stay there. The moving obstacles have as tag “MovingWall”
Here is my code, any suggestions on how to make this work?
using UnityEngine;
public class MovingWalls : MonoBehaviour {
bool moveToRight = true;
GameObject[] walls;
void Start()
{
walls = GameObject.FindGameObjectsWithTag("MovingWall"); //create list of all the moving walls
}
void FixedUpdate () {
foreach (GameObject wall in walls)
{
float wallx = wall.transform.position.x;
if (wall.transform.position.x >= 12.5) //12.5
{
moveToRight = false;
}
else if (wall.transform.position.x <= -12.5)
{
moveToRight = true;
}
if (moveToRight)
{
wallx += 10f * Time.deltaTime;
}
else
{
wallx += -10f * Time.deltaTime;
}
wall.transform.position = new Vector3(wallx, wall.transform.position.y, wall.transform.position.z);
}
}
}
Sidenote: this is my first post on this forum, if i did anything wrong dont hesitate to tell me.
@Br4m3000
I believe your script will work fine, as long as your only have a single instance of it in your scene. I tested this to make sure, and it does. If you have 2 or more instances of this script in your scene, the cubes will speed up and stop at the one side.
Create yourself an empty game object in your scene (maybe “Cube Controller”) and only place the script on it. It will then find all the tagged cubes and move them like you want.
Suggestion: I would suggest re-writing your script so it CAN be placed on your individual cube objects, exposing a variable “speed” to the editor. That way you will have more control over the individual cubes, which can give your game some variety. Just a thought. 
Here is your ductaped solution like Habitablaba says lol.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MovingWalls : MonoBehaviour
{
private IEnumerable<WallObject> walls;
void Start()
{
walls = GameObject.FindGameObjectsWithTag("MovingWall").Select(f => new WallObject { Wall = f, MoveToRight = false});
}
private class WallObject
{
public GameObject Wall;
public bool MoveToRight;
}
void FixedUpdate()
{
foreach (WallObject obj in walls)
{
float wallx = obj.Wall.transform.position.x;
if (obj.Wall.transform.position.x >= 12.5) //12.5
{
obj.MoveToRight = false;
}
else if (obj.Wall.transform.position.x <= -12.5)
{
obj.MoveToRight = true;
}
if (obj.MoveToRight)
{
wallx += 10f * Time.deltaTime;
}
else
{
wallx += -10f * Time.deltaTime;
}
obj.Wall.transform.position = new Vector3(wallx, obj.Wall.transform.position.y, obj.Wall.transform.position.z);
}
}
}
Here is a quick script I wrote that takes into account my suggestion. You can place it on your cubes to control their speeds and when they change directions (xMax and xMin).
using UnityEngine;
public class MovingWall : MonoBehaviour
{
//Properties visible in the unity editor
[SerializeField] float xMax = 12.5f;
[SerializeField] float xMin= -12.5f;
[SerializeField] float speed = 10.0f;
bool movingRight = true;
Vector3 newPosition = Vector3.zero;
// Update is called once per frame
void Update ()
{
//switch directions as needed based on the xMin and xMax
if(transform.position.x > xMax)
{
movingRight = false;
}
else if(transform.position.x < xMin)
{
movingRight = true;
}
//reset the newPosition var to the attached object's current position
newPosition = transform.position;
//alter the position
newPosition.x += (movingRight) ? speed * Time.deltaTime : -speed * Time.deltaTime;
//set the new position
transform.position = newPosition;
}
}