Disable meshrenderer for multiple gameobjects - c#

I'm currently working on some type of LOD system where I have some ferns that have to be enabled and disabled. I'm using a cube for this process, so when when my character touches the cube the ferns meshrenderers will be disabled and when not touching it, it'll enable them. Now the part where I struggle, is when I have to enable/disable the meshrenderes of these gameobjects tagged with fern.
Here is my code so far:
public GameObject[] FernPlants;
public MeshRenderer MR;
// Start is called before the first frame update
void Start()
{
FernPlants = GameObject.FindGameObjectsWithTag("Fern");
}
private void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
//Disable meshrenderers on FernPlants
}
}
private void OnTriggerExit(Collider other)
{
//Enable meshrenderers on FernPlants
}

Try with something like:
public GameObject[] FernPlants;
public MeshRenderer MR;
// Start is called before the first frame update
void Start()
{
FernPlants = GameObject.FindGameObjectsWithTag("Fern");
}
private void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
//Disable meshrenderers on FernPlants
foreach(GameObject go in FernPlants)
{
go.GetComponent<MeshRenderer>().enabled = false;
}
}
}
private void OnTriggerExit(Collider other)
{
//Enable meshrenderers on FernPlants
foreach(GameObject go in FernPlants)
{
go.GetComponent<MeshRenderer>().enabled = true;
}
}

Related

A fade animation on another gameObject

is actually a rythm game and when a circle enter into a trigger we can make disapear the circle.
public class CursorPress : MonoBehaviour {
public bool canBePressed;
public KeyCode keyToPress;
void Update()
{
if (Input.GetKeyDown(keyToPress))
{
GameObject target = GameObject.Find("hitcircle_r");
if(target.tag == "Target")
{
if (canBePressed)
{
target.GetComponent<Animation> ().play("hitcircle_fading");
target.SetActive(false);
}
}
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = true;
}
}
void OnTriggerExit2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = false;
}
}
}
I want that when the player press a key (keyToPress), a custom gameObject (hitcircle_r) gets a fade animation before disapearing, but idk how to do it, i tried a lot of code i found on the web, can someone helps me please ?
There are many ways to achieve what you want.
One would be to call a coroutine that fades deactivates your target after time.
If you are only doing fading style animations you should look into DOTween.
using System.Collections;
using UnityEngine;
public class CursorPress : MonoBehaviour
{
public bool canBePressed;
public KeyCode keyToPress;
void Update()
{
if (Input.GetKeyDown(keyToPress))
{
GameObject target = GameObject.Find("hitcircle_r");
if (target.tag == "Target")
{
if (canBePressed)
{
target.GetComponent<Animation>().Play("hitcircle_fading");
float hideTime = 0.5f; // the length of your animation
StartCoroutine(DeactivateTarget(target, hideTime));
}
}
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = true;
}
}
void OnTriggerExit2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = false;
}
}
// coroutine to deactivate GameObject
private IEnumerator DeactivateTarget(GameObject targetGo, float hideDelay)
{
yield return new WaitForSeconds(hideDelay);
targetGo.SetActive(false);
}
}

The scene change script for my unity project is not working, I cant understand why

Here is the code for the same.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class changescene : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
if(Input.GetKeyDown(KeyCode.Space))
{
SceneManager.LoadScene(1);
}
}
}
}
Running this with a 3D cube tagged player is not changing scenes and neither showing any errors.
Input.GetKeyDown is only true once per key press and only during a single frame where the key went down.
It is extremely unlikely that you press the key down exactly in the FixedUpdate physics all when the trigger enters your collider!
You want to split your physics / collision detection from user input and rather do e.g.
public class changescene : MonoBehaviour
{
private bool isEntered;
private void OnTriggerExit(Collider other)
{
if (!other.CompareTag("Player")) return;
isEntered = false;
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
isEntered = true;
}
private void Update()
{
if(isEntered && Input.GetKeyDown(KeyCode.Space))
{
SceneManager.LoadScene(1);
}
}
}
Or if you want to make it a bit more efficient without an Update method that runs most of time unnecessary you can use a Coroutine like e.g.
public class changescene : MonoBehaviour
{
private void OnTriggerExit(Collider other)
{
if (!other.CompareTag("Player")) return;
StartCoroutine(CheckSpaceRoutine());
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
StopAllCoroutines();
}
private IEnumerator CheckSpaceRoutine()
{
while(true)
{
if(Input.GetKeyDown(KeyCode.Space))
{
SceneManager.LoadScene(1);
yield break;
}
yield return null;
}
}
}

unity ui and collider2d

this is a pretty long code for a simple function but i can't seem to know how i can shorten it. any advice?
this is a simple script that i created for a beginner project and i placed the script inside the player object with both rigidbody2d and boxcollider2d and yeah it works and all, it toggles both the button gameobjects which is what i was going for in a sense but i wanted it to use only one button. if you can help with this as well i would appreciate it.
//different button objects
public GameObject smithbutton;
public GameObject innbutton;
private void OnTriggerEnter2D(Collider2D col)
{
//debugs which collider player is in
if (col.gameObject.name == "Blacksmith")
{
Debug.Log("This is the Blacksmith");
}
if (col.gameObject.name == "Inn")
{
Debug.Log("This is the Inn");
}
}
private void OnTriggerStay2D(Collider2D col)
{
//once playerobject stays, button will toggle till player leaves
if (col.gameObject.name == "Blacksmith")
{
Debug.Log("still on the Blacksmith's door");
smithbutton.SetActive(true);
}
if (col.gameObject.name == "Inn")
{
Debug.Log("still on the Inn's door");
innbutton.SetActive(true);
}
}
private void OnTriggerExit2D(Collider2D col)
{
//once playerobject exits, button will toggle and disappear
if (col.gameObject.name == "Blacksmith")
{
smithbutton.SetActive(false);
}
if (col.gameObject.name == "Inn")
{
innbutton.SetActive(false);
}
}
There is no much you could do, as the function is quite simple. You could make it better, and still reduce some of the lines. Using tag instead of name will be future proof if you create more Inns or more blacksmiths. Using the collider call a method will let you extend the functionality with ease. I will usually add each of this checks to the Inn and Blacksmiths myself, and they will be looking for the player.
//different button objects
[SerializeField] private GameObject smithbutton;
[SerializeField] private GameObject innbutton;
private void OnTriggerEnter2D(Collider2D col)
{
//debugs which collider player is in
if (col.gameObject.tag == "Blacksmith")
{
ButtonActivationToggle(smithbutton, col);
}
if (col.gameObject.tag == "Inn")
{
ButtonActivationToggle(innbutton, col);
}
}
private void OnTriggerExit2D(Collider2D col)
{
//once playerobject exits, button will toggle and disappear
if (col.gameObject.tag == "Blacksmith")
{
ButtonActivationToggle(smithbutton, col);
}
if (col.gameObject.tag == "Inn")
{
ButtonActivationToggle(innbutton, col);
}
}
public void ButtonActivationToggle(GameObject button, Collider2D collider)
{
bool tmp = false;
tmp = button.activeInHierarchy ? false : true;
button.SetActive(tmp);
if (button.activeInHierarchy)
{
Debug.Log("This is the " + gameObject.collider.tag)
}
}
you dont need the OnTriggerStay, you can do that in OnTriggerEnter and get rid of the Stay function.
public Button mybtn;
bool isBlacksmith; // keep track of where you are (you can later make it an enum if there are more than 2 places and check that)
void Start()
{
//when the button is clicked buttonFunction will be called
mybtn.onClick.AddListener(buttonFunction);
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.name == "Blacksmith")
{
Debug.Log("Entered Blacksmith's door");
mybtn.gameObject.SetActive(true);
isBlacksmith = true;
}
if (col.gameObject.name == "Inn")
{
Debug.Log("Entered Inn's door");
mybtn.gameObject.SetActive(true);
isBlacksmith = false;
}
}
private void OnTriggerExit2D(Collider2D col)
{
//once playerobject exits, button will toggle and disappear
if (col.gameObject.name == "Blacksmith" || col.gameObject.name == "Inn")
{
smithbutton.SetActive(false);
}
}
public void buttonFunction()
{
if (isBlacksmith)
Debug.Log("In Blacksmith");
else
Debug.Log("In Inn");
}

Play animator on collider enter

I have wrote a code that semi-works for me. Everything works aside from working animation.
What I'm trying to do is that when Player enters trigger, and if he/she presses E it will perform an animation. (Animation is working fine btw, so it's just code error?).
Here's what I got so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class barTrigger : MonoBehaviour {
// press shit to drink text
public GameObject drinkText;
// bottle
public GameObject alcBottle;
// drink animator
public GameObject animatorOjbect;
Animator drinkAmin;
public bool triggerIsOn;
// Use this for initialization
void Start () {
drinkAmin = animatorOjbect.GetComponent<Animator> ();
drinkText.SetActive(false);
alcBottle.SetActive(false);
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider other){
triggerIsOn = true;
if (other.gameObject.name == "vThirdPersonController") {
drinkText.SetActive (true);
}
if (triggerIsOn && Input.GetKeyDown (KeyCode.E)) {
drinkAmin.Play ("Dab");
alcBottle.SetActive (true);
}
}
void OnTriggerExit(Collider other){
if (other.gameObject.name == "vThirdPersonController") {
drinkText.SetActive (false);
alcBottle.SetActive (false);
}
}
}
OnTriggerEnter is called once and it will be hard to get press the E button and get Input.GetKeyDown(KeyCode.E) to detect that at the-same time. Checking the E input in the OnTriggerStay function is more appropriate for this but OnTriggerStay does not work sometimes so count it out. Although it's worth knowing that it exist.
Move Input.GetKeyDown(KeyCode.E) to the Update function which is called every frame then set it to true in the OnTriggerEnter function and false in the OnTriggerExit function. Below are the code that should be changed.
void Update()
{
if (triggerIsOn && Input.GetKeyDown(KeyCode.E))
{
Debug.Log("E button pressed");
drinkAmin.Play("Dab");
alcBottle.SetActive(true);
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.name == "vThirdPersonController")
{
Debug.Log("Detected vThirdPersonController");
triggerIsOn = true;
drinkText.SetActive(true);
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "vThirdPersonController")
{
Debug.Log("Lost vThirdPersonController");
triggerIsOn = false;
drinkText.SetActive(false);
alcBottle.SetActive(false);
}
}
Once you get that working, starting using the CompareTag function instead of gameObject.name as that is more proficient.

Enable/disable mesh renderer of multiple gameobjects

How can I enable/disable mesh renderer of multiple gameobjects when the player enters in a collider? This is my code but it doesn't works.
using UnityEngine;
using System.Collections;
public class SueloManager : MonoBehaviour {
private GameObject suelo;
void Start ()
{
suelo = GameObject.FindGameObjectsWithTag ("SueloWireframe");
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player") {
suelo.GetComponent<Renderer> ().enabled = false;
Debug.Log ("Oculta suelo");
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player") {
suelo.GetComponent<Renderer> ().enabled = true;
Debug.Log ("Aparece suelo");
}
}
}
FindGameObjectWithTag returns a single GameObject and FindGameObjectsWithTag returns array of GameObject. Just like Kroltan mentioned, you have to change suelo to an array then use loop to enable and disable all of them. Having the loop in a simple re-usable function should simplify this. Look at the EnableRenderer function in the solution below.
private Renderer[] sueloRenderers;
void Start()
{
GameObject[] suelo = GameObject.FindGameObjectsWithTag("SueloWireframe");
sueloRenderers = new Renderer[suelo.Length];
for (int i = 0; i < sueloRenderers.Length; i++)
{
sueloRenderers[i] = suelo[i].GetComponent<Renderer>();
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
EnableRenderer(sueloRenderers, false);
Debug.Log("Oculta suelo");
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player")
{
EnableRenderer(sueloRenderers, true);
Debug.Log("Aparece suelo");
}
}
void EnableRenderer(Renderer[] rd, bool enable)
{
for (int i = 0; i < rd.Length; i++)
{
rd[i].enabled = enable;
}
}

Categories