Enable/disable a GameObject component from a script [Unity3D] - c#

I need to take the value of a boolean (put in a variable called "bouclier") set in one script to enable or disable a GameObject.
The variable is in game object Player (bottom right here):
And I need to enable of disable this game object ("Bouclier01"):
To do this, I attached a script to game object "Bouclier01". Here it is:
using UnityEngine;
using System.Collections;
public class ShowBouclier : MonoBehaviour {
public GameObject Bouclier01;
public bool bouclier;
// Use this for initialization
void Start () {
Bouclier01 = Bouclier01.GetComponent<GameObject>();
}
// Update is called once per frame
void Update () {
Bouclier01.enabled = false;
if (bouclier == true) {
Bouclier01.enabled = true;
}
}
}
I must be missing something, because this comes up with this error message:
Any idea how to properly accomplish this?

You can use GameObject.SetActive() function to activate or deactivate a GameObject (I think GameObject.enabled was in the old API):
Bouclier.SetActive(false);
By the way, if you want to know the current activation state of a GameObject, use GameObject.activeSelf, which is a read only variable:
Debug.Log(Bouclier.activeSelf);

it will works
public GameObject otherobj;//your other object
public string scr;// your secound script name
void Start () {
(otherobj. GetComponent(scr) as MonoBehaviour).enabled = false;
}

Related

TextMesh Pro text will not change via script

I cannot seem to change my TextMeshPro value via script.
In my inspector I have a TextmeshPro object named Countdown. I have a script named GameController which is attached to this.
My script then sets the string value of Countdown to Hello but it does not work.
GameController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameController : MonoBehaviour {
public TextMeshProUGUI Countdown;
// Use this for initialization
void Start () {
Countdown = GetComponent<TextMeshProUGUI> ();
Countdown.text = "Hello";
}
// Update is called once per frame
void Update () {
}
}
In the inspector there is a field for TextMesh but I cannot drag the CountDown object to this for some reason, could that be the issue?
the problem is that you are using a regular TextMeshPro object, and in your code your looking for a TextMeshProUGUI, simple mistake. change code to:
public class GameController : MonoBehaviour {
public TextMeshPro Countdown;
// Use this for initialization
void Start () {
//you shouldnt need to get component the editor should take care of this for you when
//you drop it since you have the object set to TextMeshPro and not just GameObject
Countdown = GetComponent<TextMeshPro> ();
Countdown.text = "Hello";
}
// Update is called once per frame
void Update () {
}
}
the only way to make a TextMeshProUGUI object is to add it through a canvas. in your scene when you just add a TMP it will be Regular TMP which your "countdown" is. you can tell because it uses the TMP script not the TMPUGUI script.

Passing values from one script to another without a game object in the scene

I’ve found a lot of information on passing parameters from one script to another when a game object is present in the hierarchy. My problem is that my Transform object is created on the fly using Instantiate(myPrefab). Is there any way to access the position of myPrefab game object from another script?
You could store a reference to the instantiated GameObject after it has been instantiated (see example below). If there are more GameObjects, use a list to store them instead.
Call the InstantiateGO() and GetGOPosition() where it makes sense for you.
public class YourClass: MonoBehaviour
{
public GameObject yourPrefab;
public GameObject yourGameObject;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
void InstantiateGO()
{
yourGameObject = Instantiate(yourPrefab); // assign the newly instantiated GameObject to yourGameObject
}
void GetGOPosition()
{
var x = yourGameObject.position;
//Do something here
}
}

Go to next level when Key is grabbed by Player Unity 2d

I need some help with a feature I'm implementing for a game made in Unity 2D.
The player must take a key in order to unlock a door (maybe showing an animation) and when the player go in front of that door if he has the key, he will automatically go to the next level.
I need help, cause the door is not letting go to the next level.
Here is the KEY code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class KeyScript : MonoBehaviour {
//public AudioSource coinSoundEffect;
public AudioClip key1;
void Awake () {
//source = GetComponent<AudioSource>();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter2D (Collision2D other) {
Debug.Log("Chiave Presa");
if(other.gameObject.tag =="Player")
GameObject.Find("KeyDoor").SendMessage("HitKey");
SoundManager2D.playOneShotSound(key1);
}
}
Here is the DOOR code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class DoorScript : MonoBehaviour {
public bool key = false;
public string nextLevelName;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void HitKey (){
Debug.Log("La porta è sbloccata");
key = true;
Destroy (GameObject.Find ("Key"));
}
void OnCollisionEnter2D (Collision2D other){
if(other.gameObject.tag == "Player"){
if (key == true){
Application.LoadLevel(nextLevelName);
//Destroy(gameObject);
//GameObject.Find("Key").SendMessage("DestroyKey"); //If you also want to destroy the key
//GoToNextLevel ();
}
}
}
void OnTriggerEnter2D (Collision2D other)
{
Application.LoadLevel(nextLevelName);
}
public virtual void GoToNextLevel()
{
//loadingImage.SetActive(true);
Application.LoadLevel(nextLevelName);
}
}
The code works but when the player goes in front of the door, he is not passing to the next level.
Any help or hint appreciated.
Cheers
First of all, you're missing one thing:
unity is Component based engine
This means you should make interactions between Components, not GameObjects.
In your script there's a public field public bool key which should not be accessible from the outside. But if you're looking for simple and wrong answer that will work then you can just replace this line :
GameObject.Find("KeyDoor").SendMessage("HitKey");
Into this one :
GameObject.Find("KeyDoor").GetComponent<DoorScript>().key = true;
In that case you'll end up with messy code and unstable game. What I can recommend to you as an good alternative is to rewrite your logic a bit.
Instead of making a MonoBehaviour which is not needed you can just create a Component :
public class KeyComponent : Component
{
[SerializeField]
AudioClip m_KeyPickupSound;
[SerializeField]
bool m_IsPickedUp;
public bool PickedUp
{
get { return m_IsPickedUp; }
}
public void PickUp()
{
m_IsPickedUp = true;
SoundManager2D.playOneShotSound(m_KeyPickupSound);
}
}
Now attach this into your Player's Components list and in your door script do:
void OnCollisionEnter2D (Collision2D other)
{
if(other.GetComponent<KeyComponent>() != null && other.GetComponent<KeyComponent>().PickedUp)
{
SceneManager.LoadScene(2);
}
}
Now only thing left is to update your Player's MonoBehaviour and add simple collision check :
void OnCollisionEnter2D(Collision2D other)
{
if(other.tag == "TAG_FOR_KEY")
GetComponent<DoorScript>().PickUp();
}
Now you're interacting with Components and not GameObject which then require less effort changing some scripts.
First off, you should change Application.LoadLevel to SceneManager.LoadScene. The first is obsolete in the newer versions of unity.
Second you need to make sure that your scenes are actually registered in File -> BuildSettings and the parameter you pass to LoadScene matches either the index in that list or the name as string.
Make sure your player needs to have a Rigidbody2D and a Collider2D and the door has a Collider2D component
If your doors Collider2D is a trigger you must use void OnTriggerEnter2D(Collider2D other).
Another problem may be that "Level 2" isn't added to your build settings, make sure that it is added to the level's list.
Answering your last comment as it seemed the problem was that the Collider2D on the door, you can make this in a lot of ways, the easiest way is this:
Add a public string variable called nextLevelName in your Door's script, then when calling LoadLevel, use this variable. You can change the value from the inspector in each level. The problem with this is that if you rearrange the levels then you need to change the strings in each level.
The best solution in that case is this one:
int currentLevelNum = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentLevelNum+1);
This way if you have your levels in order in your build settings you don't need to do anything else.

Character not attacking via Unity

So I have built an attack using SpriteFactory, and simply want to assign the keyboard letter A as a default attack. I have used GetKeyUp for the sole purpose of the character to attack once, and not multiple times like a loop (i.e. GetKeyDown). At this stage I have not included any enemies or anything, as i just want the the character to simply attack when I Press A. I have Included the game object and added the Attack.cs but no success. Maybe I am complete missing the point of what I am doing, but some help in the right direction would be appreciated.
using UnityEngine;
using System.Collections;
public class Attack : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetKeyUp(KeyCode.A)) {
}
}
}
Ok so i have tried the below method. Have adjusted the code as follows:
using UnityEngine;
using System.Collections;
using FactorySprite = SpriteFactory.Sprite;
public class Attack : MonoBehaviour {
// you forgot to set name of variable representing your sprite
private FactorySprite sprite;
// Use this for initialization
void Start () {
sprite = GetComponent<FactorySprite> (); // Edited
}
void Update ()
{
if(Input.GetKeyUp(KeyCode.A))
{
sprite.Play("Attack");
}
}
}
But now have a ''nullReferenceError'' Object reference not set to an instant object?
You have to add yourSprite.Play("AnimationName"); to your loop:
void Update ()
{
if(Input.GetKeyUp(KeyCode.A))
{
yourSprite.Play("AnimationName");
}
}
For this to work you have to add a reference to your sprite to the script, with GetComponent().
Btw, GetKeyDown only triggers once for each key-press, you can use this too. (GetKey() would fire every frame)

Acessing custom property with AddComponent

In Unity3D I've got a script that adds the variable 'eaten' as a component.
using UnityEngine;
[AddComponentMenu("My game/IsEaten")]
public class IsEaten : MonoBehaviour
{
public bool Eaten;
}
Yay! I can then add another script to access 'Eaten'
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
private Eaten someScript;
// Use this for initialization
void Start ()
{
someScript = GetComponent<IsEaten>();
bool temp = someScript.Eaten;
print(temp); // false
}
}
Which works fine. What do I have to do to access the variable with dot notation from another script? ie
if (myCube.eaten == true)
{
// do something
}
You know, in Unity one does rarely create the whole script to add a single property to some object. The common approach is to think of scripts as 'components' (which they are, in fact). Let me explain this, a component is a single piece of code that add certain functionality to your GameObject, like ability to animate, or to behave the laws of physics. So, maybe, it would be better to reform your IsEaten class to form a true component, like Pickup (I'm assuming that you need Eaten property for the pickup of some sort) that will have functionality to be eaten by a player, or something.
// You will actually need to attach a collider (and check the 'IsTrigger' checkbox on it) to your GameObject
// Then this method will be called whenewer some game object with a collider (e. g. player, npc's, monsters) will enter the trigger of this object
void OnTriggerEnter(Collider other)
{
// Check whether this object was eaten before and if the actor entering our trigger is actually the player
if (!Eaten && other.tag == "Player")
{
// Make shure that we will not get eaten twice
Eaten = true;
// Apply some effect to the player that has devoured us
other.GetComponent<Player>().AddHp(25);
}
}
Other than that, I'm personally thinking, that getting out of your way to simply enable a little sweeter syntax is not worth the hassle, but, if you provide some insight of what are you actually trying to implement, I may try to help you with it :)
One way to do it might be using Get/Set:
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
private Eaten someScript;
// start new!
public bool eaten
{
get
{
return someScript.Eaten;
}
set
{
someScript.Eaten = value;
}
}
// end new!
// Use this for initialization
void Start ()
{
someScript = GetComponent<IsEaten>();
bool temp = someScript.Eaten;
print(temp); // false
}
}
Then you can access the Test class property:
Test t = GetComponent<Test>();
t.eaten = true;
ath.

Categories