How to Destroy and Instantiate a GameObject? - c#

I have a GameObject that I want to Destroy and Instantiate depending on button clicked. I don't really understand how it works but is it something like the code below? Then I attach the script on some gameobject then on onClick set via the function name.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CreateDestroyAR : MonoBehaviour {
//PAGE HAS BEEN CREATED AS A PREFAB
public GameObject Page;
public void CreatePage() {
Instantiate(Page);
}
public void DestroyPage()
{
Destroy(Page);
}
}
Yes, they are "pages" which I can just use setActive for but one of the "page" needs to be destroyed when a different button is clicked and re-instantiated every time its corresponding button is clicked.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CreateDestroyAR : MonoBehaviour {
//PAGE HAS BEEN CREATED AS A PREFAB
public GameObject Page;
private GameObject instantiatedPage;
public void CreatePage() {
instantiatedPage = Instantiate(Page);
}
public void DestroyPage()
{
Destroy(instantiatedPage);
}
}

Related

Menu panels show in game by default as open

i'm making a 2D game and my Menu panels are showing when i press play on unity they show as opened is there anyway to make them closed and only show when i press on menu button. this is the picture from the game:
And this is the script for panel opener when i press the menu button:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PanelOpener : MonoBehaviour
{
public GameObject Panel;
public void OpenPanle()
{
if (Panel != null)
{
bool isActive = Panel.activeSelf;
Panel.SetActive(!isActive);
}
}
}
Disable panels at start with a:
private void Awake(){
Panel.SetActive(false);
}
Complete code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PanelOpener : MonoBehaviour
{
public GameObject Panel;
private void Awake(){
Panel.SetActive(false);
}
public void OpenPanle()
{
if (Panel != null)
{
bool isActive = Panel.activeSelf;
Panel.SetActive(!isActive);
}
}
}
Get yourself familiar with MonoBehaviour functions like Start, Awake, Update, FixedUpdate in the future.

How to modify UI text via script?

A simple question: I'm trying to modify UI text (TextMeshPro if that makes any difference) via C# script. I am using the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Coins : MonoBehaviour
{
public Text coins;
void Start()
{
coins = GetComponent<Text>();
}
void Update()
{
coins.text = "text";
}
}
I've done a similar thing in Unity 2018 (I'm currently using Unity 2020.2) and it worked there.
For some reason it doesn't work here though. I would appreciate any help.
Changing text in TMP is practicly the same, but you need to add "using TMPro;" and also change variable type. The code should look like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class Coins : MonoBehaviour
{
public TMP_Text coins;
void Start()
{
coins = GetComponent<TextMeshProUGUI>();
}
void Update()
{
coins.text = "text";
}
}
To modify TextMeshPro components, you have to use TMP_Text class.
public class Coins : MonoBehaviour
{
public TMP_Text coins;
void Start()
{
coins = GetComponent<TMP_Text>();
}
void Update()
{
coins.text = "text"; //or coins.SetText(“text”);
}
}
You need to reference the tmp text component instead of the normal Unity text one:
Instead of GetComponent<Text>(); do GetComponent<TextMeshProUGUI>();
Of course don’t forget:
using TMPro;
on top of your code.

Unity3d:Add a public script via inspector

So I am creating a game, which is a Novel game. I want to add a functionality where my friend can add a new dialogue on a character game object. To do that, I already created a main script that enqueue and dequeue all of what is written on the inspector. Two more scripts, one script is a class for creating a new properties on the inspector where my friend can write, the other script functionality is to patch it on the inspector itself. I decided to add a patcher to customize unity editor to add a button. All what is left is a function to add another class where in my friend can write another character name and sentences.
This is what it looks like on Unity Inspector:
Please Help.
DialogueManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
private Queue<string> sentences;
public Text WrapperName;
public Text WrapperContent;
void Start()
{
sentences = new Queue<string>();
}
public void StartDialogue (Dialogue dialogue)
{
WrapperName.text = dialogue.name;
sentences.Clear();
foreach (string sentence in dialogue.sentences)
{
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if(sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
WrapperContent.text = sentence;
}
public void EndDialogue()
{
Debug.Log("dialogue Ended..");
}
}
Dialogue.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
public string name;
[TextArea(3, 10)]
public string[] sentences;
}
StoryElement.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StoryElement : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
}
}
elementscriptpatcher.cs
using System.Collections;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(StoryElement))]
public class elementscriptpatcher : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if(GUILayout.Button("Add another script"))
{
// I need to write a function for appending a class Dialogue on Dialogue.cs which was initialized on the StoryElement.
}
}
}
you can use GameObject.AddComponent.
if(GUILayout.Button("Add another script"))
{
gameObject.AddComponent<Dialogue>();
}
EDIT : As #derHugo said in comments, we can't add a class that's base is not Monobehaviour. So you will require an Access Class to access Dialogue.cs.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AccessClass : MonoBehaviour {
public Dialogue mClassObject;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Use Ink for Unity, and author the dialogue as text files.

How to properly make variable Public so it can be accessed by another script?

In Unity I have 2 GameObjects, a sphere and a capsule.
And I have a script attached to each.
Capsule script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh capsuleMesh;
void Awake()
{
capsuleMesh = GetComponent<MeshFilter>().mesh;
Debug.Log(capsuleMesh);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Sphere script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
Mesh mesh;
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
Debug.Log(mesh);
}
// Start is called before the first frame update
void Start()
{
mesh = capsuleMesh;
}
// Update is called once per frame
void Update()
{
}
}
The mesh = capsuleMesh here is giving me an error about "the name capsuleMesh does not exist in the current context".
I thought that making capsuleMesh public in the other script would make THIS script be able to access it without issue.
What am I doing wrong?
capsuleMesh is a class variable defined in the CapsuleMesh class. It's not a global variable you can use everywhere. You need a reference to the instance of the CapsuleMesh class to retrieve the mesh stored in the capsuleMesh variable.
I've reworked your both scripts to make them work. I've spotted a flaw in your scripts. I guess ChangeMesh is meant to change the mesh of the gameObject? If so, you need to assign a new value to the meshFilter.mesh. Assigning a new reference to the mesh class variable is not enough (it would be pretty long to explain why)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh Mesh
{
get ; private set;
}
void Awake()
{
Mesh = GetComponent<MeshFilter>().mesh;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
// Drag & drop in the inspector the gameObject holding the `CapsuleMesh` component
public CapsuleMesh CapsuleMesh;
private MeshFilter meshFilter;
void Awake()
{
meshFilter = GetComponent<MeshFilter>();
}
void Start()
{
meshFilter.mesh = CapsuleMesh.Mesh;
}
}

Events in scriptable objects

Is it possible to use UnityEvents and/or UnityActions in scriptable objects?
My attempt looks like this:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[CreateAssetMenu(menuName ="Dog", fileName ="New Dog")]
public class Dog : ScriptableObject
{
public string Id;
public string Text;
public UnityEvent WhenFinished;
public GameObject Go;
}
Is it possible to make a scriptable object hold a reference to a GO in the hierarchy or have an event point to a listener in the hierarchy. Is there anyway a scriptable object can communicate with the logic in the hierarchy?
Yes and no.
You can get an SO to GO reference and the reverse, but only during runtime.
When outside runtime, you can only get a SO to GO reference, an SO created in the editor outside of runtime can't reference any game object (it wouldn't know from which scene to get the GO).
Following is the code showing how to achieve this.
Scriptable Object Code
using System;
using UnityEngine;
[CreateAssetMenu(menuName = "Dog", fileName = "New Dog")]
public class Dog : ScriptableObject {
public GameObject Go;
public static event Action<string> ScriptableToGameobjectEvent;
private void Awake() {
EventScript.GameobjectToScriptableEvent += InstanceCreated;
if (Application.isPlaying) {
ScriptableToGameobjectEvent("Dog Created");
}
}
private void InstanceCreated(GameObject go) {
Go = go;
Debug.Log(Go.name);
}
}
Game Object Code
using UnityEngine;
using System;
public class EventScript : MonoBehaviour {
public static event Action<GameObject> GameobjectToScriptableEvent;
public ScriptableObject myScriptable;
private void Awake() {
Dog.ScriptableToGameobjectEvent += DogCreated;
}
private void Start() {
myScriptable = ScriptableObject.CreateInstance<Dog>();
}
private void DogCreated(string str) {
Debug.Log(str);
GameobjectToScriptableEvent(gameObject);
}
}

Categories