So I have been following a Youtube tutorial for fence building and I have done everything. The only issue is now it wont work, 2 functions are saying that one of my variables pointer isn't defining them even though in the tutorial it worked, here is my script
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
public class CreateFence : MonoBehaviour
{
public int Building = 1;
bool creating;
ShowMousePosition Pointer;
public GameObject polePrefab;
public GameObject fencePrefab;
// Start is called before the first frame update
void Start()
{
Pointer = GetComponent<ShowMousePosition>();
}
// Update is called once per frame
void Update()
{
}
void getInput()
{
if(Input.GetMouseButtonDown(0) && Building == 1)
{
startFence();
}
else if (Input.GetMouseButtonUp(0))
{
setFence();
}
else if (creating)
{
updateFence();
}
}
void startFence()
{
creating = true;
Vector3 startpos = System.Reflection.Pointer.getWorldPoint();///getWorldPoint says Pointer has no definition for it
startpos = System.Reflection.Pointer.snapPosition(startpos);///snapPosition says Pointer has no definition for it
}
void setFence()
{
creating = false;
}
void updateFence()
{
}
}
So I figured it out, it was the system reflect thing, apparently unity autocorrected me incorrectly, Apple = Microsoft Visual Studios
Related
I have been trying to make my game, play an ad every 5 rounds/losses. I have tried copying some scripts, but they don't work for me. I am a really early developer and don't know much about c# and unity. If you find a solution tell me in which script I need to put the code.
My GameManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public GameObject gameOverCanvas;
public AdsManager ads;
private void Start()
{
Time.timeScale = 1;
ads.ShowBanner();
}
public void GameOver()
{
gameOverCanvas.SetActive(true);
Time.timeScale = 0;
ads.PlayAd();
}
public void Replay()
{
SceneManager.LoadScene(0);
}
}
My AdsManager script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsManager : MonoBehaviour, IUnityAdsListener
{
#if UNITY_IOS
string gameId = "#######";
#else
string gameId = "#######";
#endif
Action onRewardedAdSuccess;
// Start is called before the first frame update
void Start()
{
Advertisement.Initialize(gameId);
Advertisement.AddListener(this);
ShowBanner();
}
public void PlayAd()
{
if(Advertisement.IsReady("Interstitial_Android"))
Advertisement.Show("Interstitial_Android");
}
public void PlayRewardedAd(Action onSuccess)
{
onRewardedAdSuccess = onSuccess;
if(Advertisement.IsReady("Rewarded_Android"))
{
Advertisement.Show("Rewarded_Android");
}
else
{
Debug.Log("Rewarded ad is not ready!");
}
}
public void ShowBanner()
{
if (Advertisement.IsReady("Banner_Android"))
{
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
Advertisement.Banner.Show("Banner_Android");
}
else
{
StartCoroutine(RepeatShowBanner());
}
}
public void HideBanner()
{
Advertisement.Banner.Hide();
}
IEnumerator RepeatShowBanner()
{
yield return new WaitForSeconds(1);
ShowBanner();
}
public void OnUnityAdsReady(string placementId)
{
Debug.Log("ADS ARE READY!");
}
public void OnUnityAdsDidError(string message)
{
Debug.Log("ERROR: " + message);
}
public void OnUnityAdsDidStart(string placementId)
{
Debug.Log("VIDEO STARTED!");
}
public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
{
if (placementId == "Rewarded_Android" && showResult == ShowResult.Finished)
{
onRewardedAdSuccess.Invoke();
}
}
}
If you need any more scripts then tell me. I would appreciate any feedback.
Create a counter, increment it after every game and then check if you reached required number of games.
You would need to create counter and required games variables. Then, put the increment and if statement code in your GameOver method:
public void GameOver()
{
gameOverCanvas.SetActive(true);
Time.timeScale = 0;
gameCount++; //increment game count
if(gameCount >= gamesToShowAd) // check if player played enough games to show ad
{
ads.PlayAd();
gameCount = 0; // reset counter
}
}
If you wish, you could consider saving game count using https://docs.unity3d.com/ScriptReference/PlayerPrefs.html or using ready online solution, but it's up to you.
I made a simple game, and for the test I decided to add an advertisement there. Until the moment of importing the package with ads, everything was compiled fine, but after that the compiler started giving errors. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Advertisements;
public class DrwLog : MonoBehaviour
{
public GameObject pnel;
public GameObject[] ColorButtons;
public GameObject button;
// Start is called before the first frame update
void Start()
{
if (Advertisement.isSupported)
{
Advertisement.Initialize("*******", false );
}
Invoke("Bn", 10f);
pnel.active = false;
}
// Update is called once per frame
void Update()
{
}
public void Clicked(bool on)
{
if (on)
{
button.GetComponent<AudioSource>().Play();
}
else
{
button.GetComponent<AudioSource>().Stop();
}
}
public void ColorChnge(int clr)
{
button.GetComponent<Image>().color = ColorButtons[clr].GetComponent<Image>().color;
}
public void PnelEnble()
{
if (!pnel.active)
{
pnel.active = true;
}
else
{
pnel.active = false;
}
}
public void Bn()
{
if (Advertisement.IsReady())
{
Advertisement.Show("bn");
}
}
}
Unity Monetization - full Add-On name.
Here's the first script which is just for the gems to be "collected".
using UnityEngine;
public class GemDestructionScript : MonoBehaviour
{
public int gemsCollected = 0;
void Awake()
{
}
void Update()
{
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag.Equals("Player1"))
{
gemsCollected++;
GetComponent<SpriteRenderer>().enabled = false;
GetComponent<CircleCollider2D>().enabled = false;
}
}
}
This is the 2nd script which is for the gemsCollected to be displayed on the canvas.
using UnityEngine;
using UnityEngine.UI;
using System;
public class GemCounter : GemDestructionScript
{
private Canvas canvas;
void Start()
{
}
void Update()
{
Transform child = transform.Find("Text");
Text t = child.GetComponent<Text>();
t.text = Convert.ToString(gemsCollected);
}
}
The problem is that the gemsCollected variable doesn't update on the canvas, it just stays at 0 the whole time.
Thanks in advance.
I fail to see the need for GemCounter to inherit from GemDestruction. Inheritance is more commonly used when having different Categories build upon each other.
A good, simple example of this is the Fruit example from Unity
In your case I would recommend using 2 separate Classes that are not linked via Inheritance. This will save you the headache of properly accessing whatever Data you need, unless it's really important for you to use Inheritance.
When you've split the classes and moved your gemsCollected to the Counter, instead of on the Gems themselves, you can just have the Gems "report in" when they are collected. This way the Counter can keep track of how many Gems have been collected and displays them on the UI. Every Object should have their job, and only use things that are relevant for that Job.
Example:
public class GemDestructionScript : MonoBehaviour
{
GemCounter counter;
private void Start()
{
// Find where-ever you keep the GemCounter Script (the Canvas in your case)
counter = GameObject.Find("Canvas").GetComponent<GemCounter>();
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag.Equals("Player1"))
{
counter.AddGem();
GetComponent<SpriteRenderer>().enabled = false;
GetComponent<CircleCollider2D>().enabled = false;
}
}
}
public class GemCounter : MonoBehaviour
{
public int gemsCollected = 0;
Text GemCounterText;
private void Start()
{
// Finding the Text Object in every Frame would be inefficient, so unless that object is constantly changing, just get it once during Start/Awake/before using it
GemCounterText = GameObject.Find("Text").GetComponent<Text>();
}
public void UpdateGemCount()
{
GemCounterText.text = gemsCollected.ToString();
}
public void AddGem()
{
gemsCollected++;
UpdateGemCount();
}
}
I am trying to create a simple dialogue system for my game in Unity. I've set up a special trigger for a Dialogue to start and the code is passing right variable but somehow it gets stuck at clearing the queue and throws a NullReferenceException.
I've seen through debugger that all variables and triggers work perfectly fine till cs:27 inside DialogueManager.cs. I've also checked the inspector to make sure everything is correctly assigned.
Dialogue class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
public string name;
[TextArea(3,10)]
public string[] sentences;
}
DialogueTrigger class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPC_DialogTrigger : MonoBehaviour
{
// Player
public Transform player;
// GameMaager to close
public GameObject Gameplay;
// Camera and Canvas to turn on
public GameObject DialogueManager;
// NPC Details
public GameObject InteractionNPCNameTextField;
public Transform interactionTransform;
public float radius = 3f;
private bool isBusy = false;
// DialogueStart
public GameObject DialogueStart;
void Start()
{
InteractionNPCNameTextField.gameObject.SetActive(false);
}
void Update()
{
float distance = Vector3.Distance(player.position, interactionTransform.position);
if (distance <= radius)
{
if (isBusy == false)
{
InteractionNPCNameTextField.gameObject.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
Dialogue();
Debug.Log("Started Dialogue procedure.");
}
}
}
else if (distance > radius)
{
InteractionNPCNameTextField.gameObject.SetActive(false);
}
}
public void Dialogue()
{
Gameplay.SetActive(false);
DialogueManager.SetActive(true);
DialogueStart.GetComponent<DialogueStart>().TriggerDialogue();
Debug.Log("Triggered Dialogue.");
}
void OnDrawGizmosSelected()
{
if (interactionTransform == null)
{
interactionTransform = transform;
}
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(interactionTransform.position, radius);
}
}
DialogueStart class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueStart : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
Debug.Log("Dialogue sent to dialogue manager.");
}
}
DialogueManager class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DialogueManager : MonoBehaviour
{
public Text nameText;
public Text DialogueText;
private Queue<string> sentences;
public GameObject DialogueManagerUI;
void Start()
{
if (sentences == null)
{
sentences = new Queue<string>();
}
}
public void StartDialogue (Dialogue dialogue)
{
Debug.Log("Received dialogues: " + dialogue);
nameText.text = dialogue.name;
Debug.Log("Start Dialogue: " + sentences.Count);
sentences.Clear();
Debug.Log("Sentences Cleared: " + sentences);
foreach (string sentence in dialogue.sentences)
{
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if(sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
DialogueText.text = sentence;
}
void EndDialogue()
{
Debug.Log("End of conversation.");
}
private void Update()
{
if (DialogueManagerUI.activeInHierarchy)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
else if (!DialogueManagerUI.activeInHierarchy)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
}
Visual Studio doesn't give me any errors.
Unity error code -> Screenshot
Debugger right before issue -> Screenshot2
Seems to me like the Queue is never assigned to sentences and it remains empty.
If it is so - why?
It sounds like DialogueManager.StartDialogue probably via DialogueStart.TriggerDialogue is called from somewhere in either Awake or at least before your Start was executed.
Especially
DialogueManager.SetActive(true);
lets assume the DialogueManager object is inactive at first anyway. So maybe your stuff is called before it is set to active.
This might also be due to the Start where you set
InteractionNPCNameTextField.gameObject.SetActive(false);
so any component on this GameObject might not have its Start method getting called. Maybe you referenced the wrong GameObject here?
Debugging would help to figure out in which order your methods get called.
In general my thumb rule for initializing is
Do everything that depends only on yourself in Awake
Do everything that depends on other components being setup already in Start
This way you can (almost) always be sure that stuff is already initialized when you need it.
However, these are only guesses but
The simple solution here:
You could already solve this by simply initializing the sentences right away using
private readonly Queue<string> sentences = new Queue<string>();
now it is definitely initialized even before Start or Awake get called!
I'm in C# and I want my handgun Muzzleflash to be inactive after each shot. I keep getting error message:
"Error CS8025 Feature 'local functions' is not available in C# 4. Please use language version 7 or greater."
WHEN I fix this I still get compiler errors and can't run game. It would be highly appreciated if you could take a look at code below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunFire : MonoBehaviour
{
public GameObject Flash;
void Update()
{
if (GlobalAmmo.LoadedAmmo >= 1)
{
if (Input.GetButtonDown("Fire1"))
{
AudioSource gunsound = GetComponent<AudioSource>();
gunsound.Play();
Flash.SetActive(true);
StartCoroutine(MuzzleOff());
GetComponent<Animation>().Play("GunShot");
GlobalAmmo.LoadedAmmo -= 1;
}
}
IEnumerator MuzzleOff()
{
yield return new WaitForSeconds(0.01f);
Flash.SetActive(false);
}
}
}
MuzzleOff() method is mistakenly put within the scope of Update() method. Please move it out as separate method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunFire : MonoBehaviour
{
public GameObject Flash;
void Update()
{
if (GlobalAmmo.LoadedAmmo >= 1)
{
if (Input.GetButtonDown("Fire1"))
{
AudioSource gunsound = GetComponent<AudioSource>();
gunsound.Play();
Flash.SetActive(true);
StartCoroutine(MuzzleOff());
GetComponent<Animation>().Play("GunShot");
GlobalAmmo.LoadedAmmo -= 1;
}
}
}
IEnumerator MuzzleOff()
{
yield return new WaitForSeconds(0.01f);
Flash.SetActive(false);
}
}