Activating game objects based on other objects collisions

Hey, am a complete beginner at Unity and scripting but need to create something for a course and have a few things that I can’t for the life of me figure out myself.

background:
My game I’m building is a sort of 3D tetris. Cubes fall in isometric view and can be rotated (each face will have a different condition) and when it lands in the designated spot it becomes a hexagon (aka material changes to an unlit colour) which based on the way the cube is rotated creates a city tile.

Here is the code I’ve managed to make work so far

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Changestateofmumba : MonoBehaviour
{
    public Rotate myCube;
    public Rigidbody rigitbody;
    public bool rotateControl = true;
    public Material[] material;
    public Renderer rend;
    private float t = 0.0f;
    private bool moving = false;
    public float fallingspeed;
 
  

  




        // Start is called before the first frame update
        void Start()
    {
        rigitbody = GetComponent<Rigidbody>();
        rend = GetComponent<Renderer>();
        rend.enabled = true;
        rend.sharedMaterial = material[0];
        fallingspeed = -1;
      



        }

        void FixedUpdate()
        {
          
              
                rigitbody.velocity = new Vector3(0, fallingspeed, 0);
                moving = true;
              
          
        }
    private void OnCollisionEnter(UnityEngine.Collision collision)
    {
        if (collision.gameObject)
        {
            rend.sharedMaterial = material[1];
        }
        if (collision.gameObject)
        {
            myCube.enabled = false;
        }
        if (collision.gameObject)
        {
            moving = false;
        }
        if (collision.gameObject)
        {
        var: Vector3 vec = transform.eulerAngles;
            vec.x = Mathf.Round(vec.x / 90) * 90;
            vec.y = Mathf.Round(vec.y / 90) * 90;
            vec.z = Mathf.Round(vec.z / 90) * 90;
            transform.eulerAngles = vec;
        }
        if (collision.gameObject)
        {
            rigitbody.useGravity = false;
            rigitbody.constraints = RigidbodyConstraints.FreezeAll;
        }
        if (collision.gameObject)
        {
            GameObject component.<objects[0]> = enabled;

        }
    }

}

and

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotate : MonoBehaviour
{
    private bool rotatingClockwise = false;
    public Rotate myCube;
    public float smooth = 1f;
    private Quaternion targetRotation;
    private Rigidbody rb;
    public float speed;

    // Use this for initialization
    void Start()
    {
        targetRotation = transform.rotation;
        myCube = GetComponent<Rotate>();
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame

void FixedUpdate()
    {
        rb.AddForce(0, -10 * Time.deltaTime, 0);
        var currentPos = transform.position;
        if (Input.GetKeyDown(KeyCode.D))
        { transform.position = new Vector3((currentPos.x - 1), currentPos.y, currentPos.z); }
        if (Input.GetKeyDown(KeyCode.A))
        { transform.position = new Vector3((currentPos.x + 1), currentPos.y, currentPos.z); }
        if (Input.GetKeyDown(KeyCode.W))
        { transform.position = new Vector3(currentPos.x , currentPos.y, (currentPos.z -1)); }
        if (Input.GetKeyDown(KeyCode.S))
        { transform.position = new Vector3(currentPos.x, currentPos.y, (currentPos.z + 1)); }

        if (Input.GetKeyDown(KeyCode.DownArrow))
        {

            transform.rotation *= Quaternion.Euler(0, 90, 0);

        }
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 10 * smooth * Time.deltaTime);


        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            transform.rotation *= Quaternion.Euler(0, -90, 0);
        }

        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            transform.rotation *= Quaternion.Euler(90, 0, 0);
        }

        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            transform.rotation *= Quaternion.Euler(-90, 0, 0);
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject)
        {
          
            {
                var currentPos = transform.position;


                transform.position = new Vector3 (Mathf.Round(currentPos.x), Mathf.Round(currentPos.y),    Mathf.Round(currentPos.z));
                            }
        }
    }
}

First problem:
I want to get a block to preview where the falling cube is going to land. in this image, that block exists but has no code associated because I haven’t managed to figure it out. I need to make it that:
when the cube lands at the preview spot, the preview needs to turn off its mesh render (or completely turn off) and activate the next preview. The preview has no rigid-body or collider because that interferes with the falling cubes scripts, so needs to be activated by the cube having a collision with another object.

Second problem:
the face conditions I can make graphics for fairly easily, but I need to work out a way to identify which conditions are showing (they rotate with the cube as it falls) to create the appropriate hexagonal city tile.
I’m not expecting this one to be all that straight forward but I’m hoping with some guidance it’s achievable…

Final issue:
once the ‘city tile’ has been placed/generated, values from it need to be analysed for a simple scoring system. (for example to get to the next level you need x amount of one condition and y amount of another and transport routes need to connect). again, I haven’t even begun to look at this part yet but I’m unsure about how I’d even start to generate this code at this point so any ideas would be great.

I know there’s a fair bit of guidance I’m asking for here but I’m pretty stumped as to how this all works and any little bit of help would be amazing!
Cheers

I recommend that instead of using mesh renderers to turn on and off inside a single object, use entire objects and an object-external contrioller script. Use SetActive(true) to make it visible and active (including all scripts) and SetActive(false) to make it disappear. The Advantage is that this way, all your objects are fully configured and optimized for what they should do. Also, remember that you can temporarily switch off a rigidbody by setting its isKinematic bool to true.

1 Like

Thanks! I have been trying to do it this way, what I’m struggling with on that issue is getting the trigger to work. Is there a way to set the ‘active’ state of one object from a different gameObject? Apologies if this is dead easy but I’ve only been (attempting to)using code/unity for about 2 weeks.

It is very simple to activate game objects from otehr scripts, and one of the great things in Unity. You Need a ‘reference’ to the object, and in simple Scenes you do that with the Inspector/Editor, or you do that in the script after you instantiate an object (i.e. create a new object).

Let’s say you have a script attached to your main game Controller and this script is to control another object. You’d declare this in your script as follows:

class test : Monobehaviour {

public GameObject theOtherObject

public void Start(){
...
}
}

Attach this script to one object in Editor. Then, usining Inspector, drag another object into the 'theOtherObject Slot. You now have a reference to another object that you can use to activate and deactive. Consider this script:

public void Update(){
  if (Input.GetKeyDown("space")) {
    // sapce was pressed
    bool currentlyActive = theOtherObject.activeInHierarchy; // find its current state
    theOtherObject.SetActive(!currentlyActive); // flip state
  }

}

Above script should switch another objects state from active to inactive and back whenever you press space.

Cheers,
-ch

Thanks! got that part working now.