Separate bools in separate scripts on separate objects setting each other off. Please help!

tl;dr - I’m making a block puzzle game with so far their being 2 different blocks (Horizontal & Vertical) and I’m trying to disable Blocks two way movement when something is in it’s way. I’m using both detection from the block’s collider (left side) and another collider set as a trigger (right side) to detect either side when it’s blocked. For some reason the “OnTriggerEnter/OnColiderEnter” on either separate script is setting off the bools in both separate scripts and I don’t know why as they shouldn’t be communicating.

I’m new to game development and making a simple block puzzle game. Right now I just have 2 block types, one that can move left n right, the other up n down. I’ve been trying to figure out how to get my mouse input to disable when a block is, well blocked. It’s in 3D with I think is the correct code for 3D.

Each block type has it’s own script (so 2 different scripts for the 2 types of blocks so far), their bools are different names, I don’t have anything referencing or calling each others scripts either. The scripts are similar, but with directions (Vector3.up or Vector3.right) and variable name changes (rightBlocked or upBlocked).

I need to find out which side is blocked and to then disable that sides mouse input to then disable movement. How I’m currently doing this is by having a normal box collider along with another box collider trigger on each block. (I’ve seen around it’s not good to put more than one collider on an object but I couldn’t find any other way, but I’m open to totally changing this if there is a much better simpler way of multi detection)

So, as an example, the left side of the Horizontal Block uses OnColliderEnter to detect when its blocked, while the right side uses OnTriggerEnter to detect the right side when it’s blocked. the two colliders are not touching each other.
When these methods detect being blocked, they set bools in the same script to “true” thus not allowing the If statements to activate that houses the mouse input.

PROBLEM: So things were working fine so far, but then I noticed the “OnTriggerEnter/OnColiderEnter” in the Horizontal Block set off it’s own bools (like it’s suppose to) but also set off the Vertical Block’s bools aswell. And vice versa. This is confusing to me as from what I can tell there shouldn’t be any communication between these two separate script that are on separate Objects with their bools being named different and everything.

I have tried setting all the bools and “On____Enter” methods to private and didn’t find a difference.

Thanks for any help!

SCRIPT:

  • HORIZONTAL BLOCK -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HorBlockClick : MonoBehaviour
{

    private float speed = 2;
    public bool rightBlocked = false;
    public bool leftBlocked = false;
   
    void Start()
    {
       
    }

  
    void Update()
    {
       
        if (!leftBlocked && Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "HorBlock")
                {
                    if (hit.collider.gameObject == this.gameObject)
                    {
                        transform.Translate(Vector2.left * speed);
                        rightBlocked = false;
                    }
                }
            }
           
        }

        if (!rightBlocked && Input.GetMouseButtonDown(1))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "HorBlock")
                {
                    if (hit.collider.gameObject == this.gameObject)
                    {
                        transform.Translate(Vector2.right * speed);
                        leftBlocked = false;
                    }
                }
            }
           
        }
    }

//check left side
    void OnCollisionEnter(Collision left)
    {
        leftBlocked = true;
    }


//check right side
    void OnTriggerEnter(Collider right)
    {
        rightBlocked = true;
    }
}
  • VERTICAL BLOCK -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VerBlockClick : MonoBehaviour
{
    private float speed = 2f;

    public bool topBlocked = false;
    public bool bottomBlocked = false;
   
    void Start()
    {
       
    }

   
    void Update()
    {
        if (!topBlocked && Input.GetAxis("Mouse ScrollWheel") > 0f)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "VerBlock")
                {
                    if (hit.collider.gameObject == this.gameObject)
                    {
                        transform.Translate(Vector2.up * speed);
                        bottomBlocked = false;
                    }
                }
            }
           
        }

        if (!bottomBlocked && Input.GetAxis("Mouse ScrollWheel") < 0f)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "VerBlock")
                {
                    if (hit.collider.gameObject == this.gameObject)
                    {
                        transform.Translate(Vector2.down * speed);
                        topBlocked = false;
                    }
                }
            }
           
        }
       
    }

//check bottom
    void OnCollisionEnter(Collision bottom)
    {
        bottomBlocked = true;
    }


//check top
    void OnTriggerEnter(Collider top)
    {
        topBlocked = true;
    }
}

I’m 99.99% confident this is NOT happening. Something else is going wrong, and you have misdiagnosed the cause.

I’m guessing that your obstacle detection code isn’t working even close to how you want it to work. You are currently assuming that any non-trigger collision whatsoever means a blockage on the bottom or left–no matter what you collided with, or what angle it’s at–and that any trigger collision whatsoever means a blockage on the top or right. This could be collisions with the ground, collisions with the player, anything with a collider component. It’s perhaps theoretically possible that you set up your scene in such a way that this would get the result you want, but I doubt that’s what you did.

You are also assuming that once there’s an obstacle there, you will always be blocked until you move in the opposite direction. (This will fail if the obstacle could move or be destroyed without your block moving.)

2 Likes

Thanks for the reply!
I’m very new to script, so It totally is something I’m missing.

I think you’re describing my ideas right, in that “assuming that any non-trigger collision whatsoever means a blockage on the bottom or left–no matter what you collided with, or what angle it’s at–and that any trigger collision whatsoever means a blockage on the top or right.”

I have it this way because I’m only trying to add maybe 2-3 other types of more blocks to the game and each move exactly 4 units in either two or one direction, aswell as they instantly teleport to their locations. no click dragging or slow movement, it’s just a mouse click and instant movement. I felt like my method should be fine as the blocks will only be blocked by the outer wall or another block (player movement can only be done once you’re finished moving the blocks)

I also have literally nothing else in my game, I just started on it. In the entire assets folder I have two prefabs (the Horblock object & VerBlock object), two scripts (the two I posted), and last 1 unedited material for the Block prefab objects, oh and a main camera. For both prefab blocks I have it’s individual script, a box collider, a trigger box collider, a rigid body, and an unedited material.
otherwise a completely blank unity project, I don’t have any imported assets or anything either.

as for your last point, I agree and know that the idea for switching my activated bools back to false within the clicking input is inherently flawed, but I ran into my current problem at the same point I realized. Being that the bools getting mysteriously switched on seemed like my greater concern I didn’t try to fret about it yet, but thanks again for pointing it out.

Another thing I guess I should’ve pointed out is that the bools do have a pattern. As an example, when my the right side (trigger) of the horizontal block is blocked, it sets top side (also trigger) of the vertical block as Blocked, even though it is not.
And when reversed, Bottom of vertical block (collider) gets blocked by the horizontal block, both bools in both blocks get set to true. so its a bit different.

If, like you say, it’s an entirely different thing causing this issue, do you mean within Unity’s own default settings or systems? Because, and I can show you if needed, there’s literally nothing else in my project except 2 block objects, and 2 scripts.

Either way, thanks again for the reply!

If there’s nothing in your scene besides these blocks and the camera, then what are they colliding with that’s causing any bools to be set at all?

1 Like

This is not doing what you expect, I imagine:

//check left side
    void OnCollisionEnter(Collision left)
    {
        leftBlocked = true;
    }
//check right side
    void OnTriggerEnter(Collider right)
    {
        rightBlocked = true;
    }
}

Those simply check for collisions and triggers, respectively. They are unrelated to what side those collisions/triggers happen on (regardless of what you name them). To check being “blocked” on different sides you will need a different way to test for it, maybe a raycast, position check, or holding an array that knows all the “units” that are filled (like Tetris does). Or you could have 4 child objects on the block, each with a collider for top, bottom, right, left, and those would be polled independently.

Also I see you have both a collider and a trigger check…not sure why, because they are the same kind of check. Probably should all be the same.

1 Like

I’m testing their collisions on each other. Kind of how I described in my examples in my last reply. I aim to add a boarder wall and player but I haven’t done anything with that yet.

So just the two blocks, and I would sometimes duplicate one to test, but the my problem is occurring weather or not there are any duplicates.

Thanks for the reply!

I have both trigger and a collider methods because I’m very much a beginner so I don’t know how to use a single collider or trigger that can trigger in more than one way whether at the same time or not. As in a single trigger knowing which side, if not both, are being blocked.

So what I’m doing is putting one of the box colliders on the left side of the horizontal block that detects collision, and on its right side it has a trigger box collider. neither collider is touching or within the other, just right next to eachother. the Vertical block is the same but the top is a trigger and bottom is a collider. I only need to detect 2 directions being blocked.

I wish I knew the coding for raycasting from object to another, but sadly the recast code I used for my mouse detection was somewhat copied and I think it’s still different for when you need it on an object as opposed to your mouse.
I have tried the child approach with a child on either side, being 2 of them per block. But I couldn’t find any info on how to get booleans from a child into the parent script where the mouse input is. So if you could hep me with that, it would really help.

Thanks again for the reply!

1 Like

Well that would explain it! Collisions are symmetric: If block X collides with block Y, then that implies that block Y must have collided with block X also. The bools are getting set at the same time because the collisions are happening at the same time on both objects.

Remember, you don’t have anything in your collision code that cares about the direction of the collision in any way. It’s just “absolutely any collision at all” and your bool gets set.

No need to postulate any weird linkages between your scripts; they’re both responding, separately, to the exact same event.

2 Likes

Raycasting can be very flexible, you tell it a starting point, direction, and distance, and it’ll tell you all the colliders it hits (if they aren’t set to ignore raycasts). So you should be able to use them in this case with some playtesting.

For the child objects sending information “up” to the parent object, that’s just script-to-script communication and is essential for games of any complexity. Note that in this case, the parent/child relationship is irrelevant, you just have two separate objects with scripts that need to send values to/call methods on each other. (That said, there are some special communication methods with parent/child systems.)

https://gamedevbeginner.com/how-to-get-a-variable-from-another-script-in-unity-the-right-way/#access_variable

1 Like

You’re right as I don’t have any code that distinguishes direction, but my colliders are placed on either side of each-other. So the trigger is only on the right side while the normal collider isn’t anywhere on the right side, but only the left side. So if an object is on the horizontal blocks right side, but not inside the block, it can only trigger the right side trigger. the left side collider wouldn’t be touching it at all. I don’t know, maybe its too hard to explain well, or you understand but im not.

Either way thanks a lot for the help, but I think I’m gonna restart the project as I’ve done so little and try another approach, probably by using children and only triggers.

Thanks again!

Thanks so much for the info and link. I’ll try to research more about script communication and raycast. got to at some point anyway haha.

1 Like

If your horizontal block is touching your vertical block, then your vertical block must also be touching your horizontal block. Putting your colliders in weird places could conceivably prevent them from touching at all, but if they touch, then the touch is symmetrical. You can’t have A touching B without B touching A.

If you’re not convinced, it is very easy to test if this is what’s happening. You could add Debug.Log statements to both collision functions so you can see when exactly they get called, and whether it happens to both at the same time. Or you could try colliding one of the blocks with something else, and see whether that has any effect on the block that wasn’t involved.

1 Like