So i tryied to add the select button on controller to my script so i can access it with a controller but I don't under stand how because I'm new to coding and if you can explain that would be great.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PauseMenu : MonoBehaviour{
public static bool GameIsPaused = false;
public GameObject pauseMenuUI;
private bool pauseEnabled;
void Update() {
if (Input.GetKeyDown(KeyCode.Escape))
{
if (GameIsPaused)
{
Resume();
}else
{
Pause();
}
}
}
void Resume()
{
pauseMenuUI.SetActive(false);
Time.timeScale = 1f;
GameIsPaused = false;
}
void Pause()
{
pauseMenuUI.SetActive(true);
Time.timeScale = 0f;
GameIsPaused = true;
}
}
First you have to know which button ID's of gamepad/ joystick. I prefer using this package for getting the button ID's of any new gamepad/ joystick. And then by getting the ID's you have to modify the Input Manager if required and call the function, like for example
if(Input.GetKey(KeyCode.Joystick1Button10)){
// do something
}
Related
I press escape, in the debug it says that Pause(), Resum(), Pause() completed. And during the pause, Resum(), Pause(), Resum(), Pause() increase. During the dialogue, I press escape more to turn off the dialogue and still pause. How can I make sure that only one action is performed, and not several different ones? RETURN NOT WORKING
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PauseMenu : MonoBehaviour
{
public static bool GameIsPaused;
public DialogWindow dialogWindow;
public GameObject pauseMenuUI;
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (GameIsPaused)
{
Debug.Log("resume");
Resume();
}
if (DialogWindow.IsDialog)
{
Debug.Log("dialog");
dialogWindow.Close();
}
else
{
Debug.Log("pause");
Pause();
}
}
}
public void Resume()
{
Cursor.lockState = CursorLockMode.Locked;
pauseMenuUI.SetActive(false);
Time.timeScale = 1f;
GameIsPaused = false;
}
public void Pause()
{
Cursor.lockState = CursorLockMode.None;
pauseMenuUI.SetActive(true);
Time.timeScale = 0f;
GameIsPaused = true;
}
public void ToMainMenu(int sceneNumber)
{
SceneManager.LoadScene(sceneNumber);
}
}
Perhaps you could use else if instead of just else, that would eliminate any chance of the different if statements to trigger simultaneously.
if (Input.GetKeyDown(KeyCode.Escape))
{
if (GameIsPaused)
{
Debug.Log("resume");
Resume();
}
else if (DialogWindow.IsDialog)
{
Debug.Log("dialog");
dialogWindow.Close();
}
else
{
Debug.Log("pause");
Pause();
}
}
so everything seems to be running as far as the AI switching different States, however when it gets in range with the player the State freezes in attack and does not play any Attack Animation, I have created the AI with Bone Rigging, Im wondering if this may be affecting it, here is my script for calling the Animation and the script for one the animation has finished to go back to idleFollow state.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeleeWeapon : Weapon
{
[SerializeField] private float attackDelay = 1f;
private Collider2D damageAreaCollider2D;
private Animator animatorAttack;
private bool attacking;
private readonly int useMeleeWeapon = Animator.StringToHash(name:"UseMeleeWeapon");
private void Start()
{
damageAreaCollider2D = GetComponent<BoxCollider2D>();
animatorAttack = GetComponent<Animator>();
//animatorAttack.Play(useMeleeWeapon);
}
public override void UseWeapon()
{
StartCoroutine(routine: Attack());
}
/*protected override void Update()
{
base.Update();
// FlipMeleeWeapon();
}*/
private IEnumerator Attack()
{
if (attacking)
{
yield break;
}
// Attack
attacking = true;
damageAreaCollider2D.enabled = true;
animatorAttack.Play(useMeleeWeapon);
// Stop Attack
yield return new WaitForSeconds(attackDelay);
damageAreaCollider2D.enabled = false;
attacking = false;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "AI/Decisions/Attack Completed", fileName = "AttackCompleted")]
public class DecisionAttackCompleted : AIDecision
{
public override bool Decide(StateController controller)
{
return AttackCompleted(controller);
}
private bool AttackCompleted(StateController controller)
{
if (controller.CharacterWeapon.CurrentWeapon.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length
> controller.CharacterWeapon.CurrentWeapon.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime)
{
return true;
}
return false;
}
}
Ok I fixed the issue, I ended up placing this code into the WeaponMelee script, but now im dealing with a weird glitch where the AI keeps tring to face the left instead of the player when they are close to eachother. this has to do with the boxcollider2D so ive placed a capsulecollider2d inside of him and changed the script to capsulecollider2d as well. but the issue is still happening
private void OnTriggerEnter2D(Collider2D collision)
{
StartCoroutine(routine: Attack());
}
I am making a Pause menu in Unity that appears when you press escape. But whenever I press escape, the background music still plays. I am getting an error in lines 32 and 46.
The error log is Assets\PauseMenu.cs(32,32): error CS0029: Cannot implicitly convert type 'UnityEngine.AudioSource' to 'UnityEngine.AudioSource[]'
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PauseMenu : MonoBehaviour
{
public static bool GameIsPaused = false;
public GameObject pauseMenuUI;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (GameIsPaused)
{
Resume();
}
else
{
Pause();
}
}
}
void Resume()
{
pauseMenuUI.SetActive(false);
Time.timeScale = 1f;
GameIsPaused = false;
AudioSource[] audios = FindObjectOfType<AudioSource>();
foreach (AudioSource a in audios)
{
a.Play();
}
}
void Pause()
{
pauseMenuUI.SetActive(true);
Time.timeScale = 0f;
GameIsPaused = true;
AudioSource[] audios = FindObjectOfType<AudioSource>();
foreach (AudioSource a in audios)
{
a.Pause();
}
}
}
FindObjectOfType<AudioSource>() return only one object to return an array of object use FindObjectsOfType<AudioSource>()
I'm wondering why my pause script doesn't work as expected. It should freeze the time and bring up the Pause menu, but instead it only freezes and nothing happens after that. And i can't resume the game too
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class PauseMenu : MonoBehaviour
{
// Start is called before the first frame update
public static bool GameIsPaused = false;
public GameObject pauseMenuUI;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (GameIsPaused)
{
Resume();
}
else
{
Pause();
}
}
}
void Resume()
{
pauseMenuUI.SetActive(false);
Time.timeScale = 1f;
GameIsPaused = false;
}
void Pause()
{
pauseMenuUI.SetActive(true);
Time.timeScale = 0f;
GameIsPaused = true;
}
}
SetActive(false) will disable the game object, i.e. it won't update anymore. So if your pauseMenuUI is the object you call that on (or a descent of it) then your script won't be called anymore.
The solution is to put your script on another object (e.g. a parent of pauseMenuUI`).
i wonne make a game where the Gravity changes form 1enter image description here to -1enter image description here when i touch one Button and back when i touch the other button Button. In the Beginning it works but then it just stops working
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Button : MonoBehaviour
{
private Rigidbody2D rb;
private bool moveUp;
private bool MoveDown;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
moveUp = false;
MoveDown = false;
}
public void PionterDownRight(){
moveUp = true;
}
public void PionterUpRight(){
moveUp=false;
}
public void PionterDownLeft(){
MoveDown= true;
}
public void PionterUpLeft(){
MoveDown = false;
}
// Update is called once per frame
void Update()
{
if(moveUp){
rb.gravityScale = -1;
}
if (MoveDown){
rb.gravityScale = 1;
}
}
}
I recommend having only one bool variable:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Button : MonoBehaviour
{
private Rigidbody2D rb;
private bool moveDown = true;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
public void PionterDownRight()
{
moveDown = false;
}
public void PionterUpRight()
{
moveDown = true;
}
public void PionterDownLeft()
{
moveDown = true;
}
public void PionterUpLeft()
{
moveDown = false;
}
// Update is called once per frame
void Update()
{
if (moveDown == true)
{
rb.gravityScale = 1;
}
else
{
rb.gravityScale = -1;
}
}
}
Graviyscale affects how much gravity will effect the rigidbody, I'm assuming its not working because it plateaus at 0 = no effect. You might have to take a different approach, something like
rb.gravityScale = -1;
replace with
rb.AddForce(new Vector2(0, 9.81f * 2));