In Unity:
Could anybody tell me what I did wrong. I wanted to pop up a dialogue after you are nearby a charecter but somehow my code doesn't really work.
public class Interactable : MonoBehaviour {
[HideInInspector]
public NavMeshAgent playerAgent;
private bool hasInteracted;
public virtual void MoveToIneraction(NavMeshAgent playerAgent)
{
hasInteracted = false;
this.playerAgent = playerAgent;
playerAgent.stoppingDistance = 2.3f;
playerAgent.destination = this.transform.position;
Interact ();
}
void Update()
{
if (!!hasInteracted && playerAgent != null && playerAgent.pathPending)
{
if(playerAgent.remainingDistance <= playerAgent.stoppingDistance)
{
Interact();
hasInteracted = true;
}
}
}
public virtual void Interact()
{
Debug.Log("Interacted");
}
}
!!hasInteracted
It should be !hasInteracted, I guess
Related
I had a script that controlled my main menu that was on a GameObject and moved it to another gameobject and reconnected all the loose ends. now for some reason none of my buttons work, even with highlighting.
just had two gameobjects and moved the script between them using the editor
the script itself doesnt do much, just this:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour
{
public GameObject mainMenu;
public GameObject optionsMenu;
public GameObject modeMenu;
public Dropdown resolutionDropdown;
private Resolution[] resolutions;
public Toggle fullscreenToggle;
public void StartGameLocal()
{
SceneManager.LoadScene("Local2P");
}
public void StartGameAI()
{
SceneManager.LoadScene("AI2P");
}
public void MenuToOptions()
{
mainMenu.SetActive(false);
optionsMenu.SetActive(true);
}
public void OptionsToMenu()
{
mainMenu.SetActive(true);
optionsMenu.SetActive(false);
}
public void MenuToMode()
{
mainMenu.SetActive(false);
modeMenu.SetActive(true);
}
public void ModeToMenu()
{
mainMenu.SetActive(true);
modeMenu.SetActive(false);
}
public void ExitGame()
{
Application.Quit();
}
void Start()
{
resolutions = Screen.resolutions;
resolutionDropdown.ClearOptions();
List<string> options = new List<string>();
int currentResolutionIndex = 0;
for (int i = 0; i < resolutions.Length; i++)
{
string option = resolutions[i].width + " x " + resolutions[i].height;
options.Add(option);
if (resolutions[i].width == Screen.width && resolutions[i].height == Screen.height)
currentResolutionIndex = i;
}
resolutionDropdown.AddOptions(options);
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
if (Screen.fullScreen == true)
{
fullscreenToggle.isOn = true;
}
}
public void SetResolution(int resolutionIndex)
{
Resolution resolution = resolutions[resolutionIndex];
Screen.SetResolution(resolution.width,
resolution.height, Screen.fullScreen);
PlayerPrefs.SetInt("ResolutionPreference", resolutionDropdown.value);
}
public void SetFullscreen(bool isFullscreen)
{
Screen.fullScreen = isFullscreen;
if (isFullscreen)
{
PlayerPrefs.SetInt("FullscreenPreference", 1);
}
else
{
PlayerPrefs.SetInt("FullscreenPreference", 0);
}
}
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
if (optionsMenu.activeSelf)
{
OptionsToMenu();
}
else if (optionsMenu.activeSelf)
{
ModeToMenu();
}
else
{
Application.Quit();
}
}
}
}
i dont know how to fix this and why my buttons just stopped working, even after reconnecting everything, but please help!
p.s. havent checked the update code to see if it worked, if yall have suggestions let me know
Your buttons likely pointed to the functions in this script in their OnClick handlers. If you moved the location of the script, you need to go to each of the buttons and hook those handlers back up.
Within my, if function, the Input.GetKey("t") command does not work.
The Restart method is called when I remove the contents from the if function and place them outside.
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
public GameObject LevelFailedUI;
public GameObject LevelCompleteUI;
public void CompleteLevel ()
{
if (LevelFailedUI == true)
{
LevelCompleteUI.SetActive(true);
}
}
public void EndGame ()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
LevelFailedUI.SetActive(true);
if (Input.GetKey("t")) //nothing happens when "t" is pressed.
{
Invoke("Restart", restartDelay);
}
}
}
void Restart ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
LevelFailedUI.SetActive(false);
}
}
It won't work because unity has to be inside the function and also hasn't reached the check before reaching the if statement and you press the button during one frame which is basically impossible. You have to check for input constantly that is why it is done inside the Update function.
void Update() {
if (Input.GetKey(KeyCode.T) && gameHasEnded) {
Invoke("Restart", restartDelay);
}
}
public void EndGame() {
if (gameHasEnded == false) {
gameHasEnded = true;
LevelFailedUI.SetActive(true);
}
}
I'm started with Unity, and I need (before game is in paused) trigger an avent. Is there any way to trigger any event when the Time.timeScale is changed to 0? Something like: Time.timeScale.onBeforeChange()...
Thanks a lot.
Make the thing that changes the time scale a controller, then make that controller raise the event.
[System.Serializable]
public class BeforeTimeChangedData
{
public bool canceled;
public float oldValue;
public float newValue;
}
[System.Serializable]
public class BeforeTimeChangedEvent : UnityEvent<BeforeTimeChangedData>
{
}
//Attach this to a game object that gets loaded in your pre-load scene with the tag "Singletons"
public class TimeController : MonoBehaviour
{
void Awake()
{
DontDestroyOnLoad(gameObject);
if(BeforeTimeChanged == null)
BeforeTimeChanged = new BeforeTimeChangedEvent();
}
public BeforeTimeChangedEvent BeforeTimeChanged;
public bool ChangeTimeScale(float newValue)
{
var args = new BeforeTimeChangedData();
args.oldValue = Time.timeScale;
args.newValue = Time.timeScale;
BeforeTimeChanged.Invoke(args);
if(!args.canceled)
{
Time.timeScale = newValue;
}
return args.canceled;
}
}
Elsewhere you can change the timescale by doing
public class TimeSlower : MonoBehaviour
{
private TimeController _timeController;
public Text TimeChanged;
void Start()
{
var singletons = GameObject.FindWithTag("Singletons");
_timeController = singletons.GetComponent<TimeController>();
if(_timeController == null)
throw new System.ArgumentNullException("Could not find a TimeController on the Singletons object");
}
void Update()
{
if(Input.GetButton("SlowTime"))
{
var changed = _timeController.ChangeTimeScale(0.5f);
if(changed)
{
TimeChanged.text = "Time Changed!";
}
}
}
}
And here is another component that listens for the change and cancels the change if the change has happened too recently;
public class TimeChangeLimiter : MonoBehaviour
{
private float lastTimeChange = 0;
private TimeController _timeController;
public Text TimeChanged;
[Range(0, float.MaxValue)]
public float Cooldown;
void Start()
{
var singletons = GameObject.FindWithTag("Singletons");
_timeController = singletons.GetComponent<TimeController>();
if(_timeController == null)
throw new System.ArgumentNullException("Could not find a TimeController on the Singletons object");
_timeController.BeforeTimeChanged.AddListener(OnBeforeTimeChanged);
}
void OnDestroy()
{
_timeController.BeforeTimeChanged.RemoveListener(OnBeforeTimeChanged);
}
void OnBeforeTimeChanged(BeforeTimeChangedData args)
{
if(Time.time - lastTimeChange < Cooldown)
{
args.canceled = true;
return;
}
lastTimeChange = Time.time;
}
}
I cannot figure out the issue, I deleted then remade the PlayTab object, but it no longer works... It is telling me it has not been assigned, but it has to my knowledge. Relatively new to Unity programming, any help would be great, the script below.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Audio;
public class MainMenu : MonoBehaviour {
public GameObject Buttons;
public GameObject CreditsPanel;
public GameObject QuitPanel;
public GameObject Options;
public GameObject PlayTab;
public Slider audiosl;
public Slider graphicsl;
public Toggle fullscreen;
public string SceneName;
void Start (){
QualitySettings.SetQualityLevel (100);
//(int)PlayerPrefs.GetFloat("Quality")
AudioListener.volume = 100;
//PlayerPrefs.GetFloat("Volume");
int qualityLevel = QualitySettings.GetQualityLevel();
audiosl.value = AudioListener.volume;
graphicsl.value = qualityLevel;
}
void Update (){
Debug.Log ("Update");
AudioListener.volume = audiosl.value;
QualitySettings.SetQualityLevel ((int)graphicsl.value);
}
public void InGame(bool a){
if (a == true) {
Application.LoadLevel (SceneName);
} else {
//continue
}
}
public void Play(bool a){
Debug.Log ("Inside Play Function");
if (a == true) {
Debug.Log ("Inside If Statment");
PlayTab.SetActive(a);
Buttons.SetActive(!a);
Animation pl = PlayTab.GetComponent<Animation>();
pl.Play("EnterPlayMenu");
}else {
Debug.Log ("Else'd");
PlayTab.SetActive(a);
}
}
public void ShowMenu(bool a){
}
public void Option(bool a){
if (a == true) {
Options.SetActive(a);
Buttons.SetActive(!a);
Animation Opt = Options.GetComponent<Animation>();
Opt.Play("OptionEnter");
}if (a == false) {
Animation d = Buttons.GetComponent<Animation> ();
d.Play ("mainbuttonenter");
Options.SetActive (false);
}
}
public void Credits(bool a){
if (a == true) {
CreditsPanel.SetActive(a);
Buttons.SetActive(!a);
Animation cr = CreditsPanel.GetComponent<Animation>();
cr.Play("EnterCredits");
}else {
CreditsPanel.SetActive(a);
}
}
public void Quit(bool a){
if (a == true) {
QuitPanel.SetActive(a);
Buttons.SetActive(!a);
Animation q = QuitPanel.GetComponent<Animation>();
q.Play("EnterQuit");
}else {
QuitPanel.SetActive(a);
}
}
public void Exit(bool a){
if (a == false) {
Option(false);
Buttons.SetActive(true);
CreditsPanel.SetActive(false);
QuitPanel.SetActive(false);
Options.SetActive(false);
PlayTab.SetActive(false);
saveSettings();
}
if (a == true) {
Application.Quit();
}
}
public void saveSettings(){
PlayerPrefs.SetFloat ("Quality", QualitySettings.GetQualityLevel ());
PlayerPrefs.SetFloat ("Volume", AudioListener.volume);
}
public void FullScreen(bool a){
if (Screen.fullScreen == a) {
Screen.fullScreen = !a;
} else {
Screen.fullScreen = a;
}
}
}
As far as I see, you have only defined the playTab variable, but not assigned it.
EDIT:
Try displaying it at start, then automatically hiding it via code. Probably Unity don't initialize objects that are not visible on scene from the start.
I have a list of enemys. so i want each enemy have their turn.
First of all :
Player turn --> enemys turn ("here each enemy move one by one untill the end then player move again"). how do i making some waiting time here and forcus on enemy turn?
Any help would be appreciated.
void Start()
{
// find list enemy
enemy = GameObject.FindGameObjectsWithTag("Enemy");
}
void Update()
{
//enemy turn reference to player. after move all enemy we change it to false to change the player turn.
if(StaticClass.enemyTurn == true )
{
for(int i=0;i<enemy.length;i++)
{
// how do i making some waiting time here and forcus on enemy turn?
EnemyTurn(i);
}
}
}
public void EnemyTurn(int id)
{
ChessMoveMent chessMoveScript = enemy[id].GetComponent<ChessMoveMent>();
chessMoveScript.ProcessMove();
id++;
if(id>=enemy.Length)
{
isMove = false;
}
}
I usually use StartCoroutine in this case.
Please try the below code:
public IEnumerator EnemyTurn(int id)
{
yield return null;
ChessMoveMent chessMoveScript = enemy[id].GetComponent<ChessMoveMent>();
chessMoveScript.ProcessMove();
id++;
if(id>=enemy.Length)
{
isMove = false;
}
}
When you want to use it, please use with "StartCoroutine()"
StartCoroutine(EnemyTurn(i));
More details here
You might have a coordinator, who tells the participants when it's their turn.
public class GameCoordinator : MonoBehaviour
{
public List<Participant> participants;
private int currentParticipantIdx = -1;
private Participant CurrentParticipant
{
get { return participants[currentParticipantIdx]; }
}
private void Start()
{
PlayNextMove();
}
private void PlayNextMove()
{
ProceedToNextParticipant();
CurrentParticipant.OnMoveCompleted += OnMoveCompleted;
CurrentParticipant.BeginMove();
}
private void OnMoveCompleted()
{
CurrentParticipant.OnMoveCompleted -= OnMoveCompleted;
StartCoroutine(PlayNextMoveIn(2.0f));
}
private IEnumerator PlayNextMoveIn(float countdown)
{
yield return new WaitForSeconds(countdown);
PlayNextMove();
}
private void ProceedToNextParticipant()
{
++currentParticipantIdx;
if (currentParticipantIdx == participants.Count)
currentParticipantIdx = 0;
}
}
public class Participant : MonoBehaviour
{
public event Action OnMoveCompleted;
public void BeginMove()
{
//
}
}