I’m making sort of a Breakout / Arknoid clone and one of the perks is to have the ball turned into a “wrecking ball” where the ball will destroy any bricks it hits without bouncing (i.e. colliding).
I figure the best way to do this is to set the bricks on the playfield to “istrigger = true” and then have a OnTriggerEnter in the script attached to the bricks.
Problem is I cant figure out how to iterate through any and all remaining bricks in the playfield. I have the bricks currently set up like this in the hierarchy:
Bricks (empty gameobject)
BrickReg (1)
BrickReg (2)
BrickReg (3)
BrickHard (1)
BrickHard (2)
etc etc etc
The bricks can have either tag “BrickReg” or “BrickHard”. Sometimes there might be 21 bricks remaining when the perk is activated and sometimes there might only be 2 as they are destroyed (Destroy(this.gameObject))…
So…I need a logic where I can loop through any remaining gameobjects in the parents folder in the hierchy and then set istrigger to ‘true’ on these…
Most problems I’ve managed to google a solution to, but this one has me beat…I know there is a foreach loop but I’m not quite sure how I should set it up.
You can use GetComponentsInChildren with RigidBody as type to find them all below your Bricks object.
Note that this isnt particularly performant. If this happens often, and you see this coming up in the profiler, consider doing this at the beginning and looping over the same array every time. Just check if it has been destroyed (== null) before using the element.
Many thanks for the suggestions. I found this regarding GetComponentsinChildren, but is there a way to call this from a script on a different object or does it specifically have to sit on the parent object? I guess I could make it a public class to access the components found from other scripts though.
Regarding arrays - Ive never ever worked with arrays before, not even in my main language (VB). Do you happen to have a link to some documentation on how to work with arrays? Cheers!
Yeah it’s all in the Learn Section (above) and the manual. It’s a bit much to go into here, but there’s two kinds of collections usually (there are many more but you use these two)
List and Array
So you’d want to research those. Unity has good support for collections. Hopefully someone else has time to further tutor you but these should get you started.
You will also need to learn about references vs values because some things held in arrays will be the actual number or basic built-in type (int, float, string etc and these are called value types) and others will be reference to a type that is not built in. These references instead point to the class data it reference (a gameobject for example, or your own thing).
It matters because when you create an array or list, and put stuff in that list, or ask a function to do so, it will be null or not null (does it exist or not) still per thing in the array, so you need to be making sure that exists too. So add null to things to think about in the future.
A bit long winded isn’t it? but give it time and it will make more sense as you go along, just push through it
As you see in the manual, you can call GetComponentsInChildren on anything that is a Component. When you click on the Component class you see its the base class of everything attached to gameObjects, so you can call it on many types. For example you can get a reference of your Bricks Transform (which inherits from Component, thus has GetComponentsInChildren) and call it. You can get the transform by either putting the script on the Bricks object, or making it public and dragging it in via the inspector.
The manual for GetComponentsInChildren shows how to loop over them and set a value.
Many thanks for the help - I have managed to write a piece of code that will set my bricks to isTrigger = true (easy peasy once you understand it…like most things…)
However I’ve run into a peculiar issue - the game is an Arknoid clone of sorts. The perk “wreckingball” should be activated when the player picks up another game object (a cylinder).
The script I have made is on the parent empty gameobject in the hierarchy, like so:
Bricks (empty gameobject) - SCRIPT (see script details below)
BrickReg (1)
BrickReg (2)
BrickReg (3)
etc etc etc
However, the I’m calling this script from another script that is attached to the perk-cylinder gameobject, using this line of code: SetBrickTriggers.instance.settriggers();
The perk-cylinder gameobject is itself initiated by this line: Instantiate(Cylinder, brickpos, Quaternion.Euler(0, 0, 90));
The perk-cylinder will be created in the root of the hierarchy, BUT for some odd reason the perk-cylinder gameobject will be affected by the isTrigger = true while the bricks are unaffected, despite the actual script being on the parent empty gameobject which holds the children bricks…
Help? I’ve obviously missed something on how this works…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SetBrickTriggers : MonoBehaviour
{
public Component[] BoxieCollider;
public static SetBrickTriggers instance = null;
// Start is called before the first frame update
void Start()
{
BoxieCollider = GetComponentsInChildren<BoxCollider>();
}
// Update is called once per frame
void Update()
{
}
public void settriggers()
{
foreach (BoxCollider box in BoxieCollider)
box.isTrigger = true;
}
public void resettriggers()
{
foreach (BoxCollider box in BoxieCollider)
box.isTrigger = false;
}
}
Unfortunately I dont even know how to use the debug.log namespace…I think I’ll have to figure this all out by myself…might take a few more days, but I’ll get there
Using Debug.Log() is one of the most useful ways to quickly track down problems in code, it’s worth getting the hang of using it, and it’s not difficult to use.
it is good habit to organize things from the start when deciding to make a project.
you should really take the time to learn loops and arrays and references. planning a good organizational system for any game saves the developer time and can give a game much more proficiency and FPS. Run this. here is a system where you dont need any game engine lookups and pry don’t need any scripts on the blocks.
using UnityEngine;
using System.Collections;
public class breakout : MonoBehaviour {
GameObject[][] bricks;
void Start () {
int x,y;
// make yer bricks
x = 10;
bricks = new GameObject[x][];
while(x>0){x--;
y = 5; bricks[x] = new GameObject[y];
while(y>0){y--;
bricks[x][y] = GameObject.CreatePrimitive(PrimitiveType.Cube);
bricks[x][y].transform.position = new Vector3(x,y,0);
bricks[x][y].transform.name = x+" "+y;
bricks[x][y].collider.isTrigger = true;
}}
// now you can refer to your brick gameobjects with coodinates like this:
bricks [2][3].transform.renderer.material.color = Color.green;
// search bricks like this
for (x = 0; x < bricks.Length; x++) {
for (y = 0; y < bricks[x].Length; y++) {
if(bricks[x][y].transform.renderer.material.color == Color.green){
print (x+","+y+" is green");
}}}
// page through a row like this
for (x = 0; x < bricks.Length; x++) {
bricks[x][0].transform.renderer.material.color = Color.red;
}
}
}