Good morning everyone.
I must finish a little project for next month in unity.
This project is a remestered Angry Bird.
I want to create a code which allow to display and hide a panel everytime when I use Space touch on my keyboard.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RadialMenu : MonoBehaviour
{
public GameObject[] RadialMenuItems;
public AudioSource AudSourc;
public AudioClip MovementClip;
public AudioClip UseClip;
public GameObject radialMenu;
Vector2 NormalizedMPose;
float AngleOfMouse;
int SelectedItem;
int PrevItemID=5;
void Update()
{
if ((radialMenu.activeSelf == true) && Input.GetKey("space"))
radialMenu.SetActive(false);
else if((radialMenu.activeSelf == false) && Input.GetKey("space"))
radialMenu.SetActive(true);
}
}
But it doesn't work.
I can hide the panel when I click in Space button for the first time but I can't display it again with the button.
I'm actually stuck on it and I can't finish my project.
Any help please
Thanks
If the GameObject is disabled the Update method is not executed executed anymore.
A solution would be to disable a child GameObject, so that the Update method is executed.
Related
I am making a gunshot code for a zombie shooter, but for some reason whenever I fire more than once in the same time period as the other shot, they don't overlap? Is there any way I can make it so that they do? Also, it only plays occasionally when I wait
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class audioplay : MonoBehaviour
{
public AudioSource source;
public AudioClip clip;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
source.PlayOneShot(clip);
}
}
}
You wouldn't want a shoot function without any cooldown, especially in update. Also check your audio file to see if has blank space in it, like the one I used:
I used Audacity to trim the audio file. (it's free and open source :D )
Code stuff:
using UnityEngine;
public class MyPlayAudio : MonoBehaviour {
public AudioSource audioSource;
public AudioClip audioClip;
public float shootCooldown; //change this according to how fast you want to shoot
private float currentShootCooldown;
void Update()
{
//if you are holding mouse button down and we are ready to shoot
if(Input.GetMouseButton(0) && currentShootCooldown <= 0)
{
Pewpew();
}
//make sure you are not changing the public value
currentShootCooldown -= Time.deltaTime;
}
public void Pewpew()
{
//code whatever gun is supposed to do, like dealing damage
//resets cooldown for pewpew
currentShootCooldown = shootCooldown;
//plays the audio
audioSource.PlayOneShot(audioClip);
}
}
I think .Play might be better if we are thinking about a gun. I don't know, try both and see which one is better for your needs
audioSource.clip = audioClip; //this is not necessary if your gun is only going to do 1 sound.
audioSource.Play();
`
If you want it to overlap, you could for example add that component to two different gameobjects in the scene, that way there will be one frame where the function is called twice. Since Update would run on two objects.
I am trying to do when i destroy all boxes something happen.
My code is;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class destroy : MonoBehaviour
{
private string BALL_TAG = "ball";
public AudioClip coin;
public AudioSource src;
public float numBox = 120f;
public bool isDestroyed;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag(BALL_TAG))
{
src.clip = coin;
src.Play();
Destroy(gameObject);
isDestroyed = true;
}
}
private void Update()
{
boxes();
}
public void boxes()
{
if(isDestroyed == true)
numBox -= 1f;
if(numBox == 119)
SceneManager.LoadScene("mainManu");
}
private IEnumerator Two()
{
yield return new WaitForSeconds(1f);
Destroy(gameObject);
}
}
But it doesn't work.
It is suppose to do when I broke 1 box it sends me to menu.
I think its problem in "numBox -= 1f;" because I don't know hot to make this.
I don't understand your code completely. So, I need to make some assumptions.
I think the Script is attached to the box and every box has this Script. I also think, that your player Shoots Ball. Those Balls have a collider with an ball tag.
There are multiple problems with your code.
The first one is, that your count variable, numBox, is saved in your destroy Script, which is placed on each box.
this means, that every Box is counting for itself.
You have to centralize this. There are multiple ways for doing this.
One way is to declare this variable as static(https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/static)
This is not best practice, but works.
A Better way is to have a Script on Your Player, which holds this number and every Box searches for this Script and change this number if it is destroyed.
The second big Problem is, that your are doing some really weird thing in your Update and the collision handling
First of all, you are setting isDestroyed to true. Then in your boxes method, which is called in every Frame, you are decrementing your numBox variable by one, if this is Destroyed is true.
So if your Box gets hit, you are decrementing every frame.
After that you are checking every frame if your numBox is 119
If so, you change the Scene.
This is the reason, why you are getting to your MainMenu after only one boy
This behaviour is very weird, because it is totally unnecessary. You can reduce your variable directly in in your OnCollisionEnter2D Method.
There are some little things, which can be improved.
When you are trying to play a Sound, you don't have to specify the AudioClip in code. You can assign this directly in Unity on the AudioSource Component via drag and drop. This makes your code simpler.
You are not calling the Two Coroutine. You've specified this Coroutine but don't call it.
//Script on Player
public class PlayerBoxDestroyManager:MonoBehaviour
{
public int StartBoxes = 120;
private int Boxes;
private void Start()
{
Boxes = StartBoxes;
}
public void DestroyBox()
{
//Reduce our Boxes count
//This is equal to Boxes -= 1
// Boxes = Boxes -1
Boxes--;
// If we have less or zero Boxes left, we End call our EndGame methode
if(Boxes <= 0)
{
EndGame();
}
}
private void EndGame()
{
// We change the Scene to the mainMenu
SceneManager.LoadScene("mainManu");
}
}
```
//Script on all Boxes
public class Box : MonoBehaviour
{
public string Balltag = "ball";
//Audio Source the Audio Clip has to be assigned in the Unity editor
public AudioSource Coin;
private void OnCollisionEnter2D(Collision2D collision)
{
//Check it colliding Object has the right Tag
if(collision.transform.tag == Balltag)
{
//Get the reference to the Player Script
PlayerBoxDestroyManager PBDM = FindObjectOfType<PlayerBoxDestroyManager>();
//We can now access the Destroy Box Methode
PBDM.DestroyBox();
//Play the sound
Coin.Play();
//If we destroy our Object now, the Sound would also be deletet.
//We want to hear the sound, so we have to wait, till the sound is finished.
StartCoroutine(WaitTillAudioIsFinished());
}
}
IEnumerator WaitTillAudioIsFinished()
{
//we wait till the sound is finished
while (Coin.isPlaying)
{
yield return null;
}
//if finished, we destroy the Gameobject
Destroy(gameObject);
}
}
I hope I helped you. If you have questions, feel free to ask.
And sorry for my English:)
Im making my first 2D game in unity and I have successfully made it. However I want a start button.I have looked up videos on how to make a start button and they all seem to have a start button on a different screen and once clicked it goes to another scene. Where as I would like my button to be on the same screen as my game and once clicked it starts the game, while having the button disappear. Can the code also be in c# thank you.
If you don't want to have different scenes (which, by the way, it's the recommended pattern) you can pause the game until the player presses the button. More informations can be found here.
using UnityEngine;
using UnityEngine.UI;
class GameManager: MonoBehaviour
{
public Button startButton;
private void Awake()
{
Time.timeScale = 0f;
}
private void OnEnable()
{
startButton.onClick.AddListener(StartGame);
}
private void OnDisable()
{
startButton.onClick.RemoveListener(StartGame);
}
private void StartGame()
{
Time.timeScale = 1f;
// Hides the button
startButton.gameObject.SetActive(false);
}
}
Put your button on your main scene that's it.
As the title states the animation is not playing. the line telling it to play is in a coroutine and the code is before a waitforseconds(3f).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Play : MonoBehaviour {
public Animator AnimatorRef;
// Use this for initialization
void Start () {
if (AnimatorRef == null)
{
AnimatorRef = GetComponent<Animator>();
}
}
public void PlayGame()
{
StartCoroutine(TitlePlay());
Debug.Log("playing");
}
IEnumerator TitlePlay()
{
Debug.Log("playing1");
AnimatorRef.SetBool("Enlarge", true);
yield return new WaitForSeconds(3f);
Debug.Log("playing2");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}
it grabs the animator reference fine and all three of the comments show.
2 Considerations.
1st -
Did you check your transitions and AnimationController?
You can open up the AnimationController to see if the bool changes during runtime, if it does you'll know there is a transition error somewhere between your animation states.
2nd -
If you comment out the "LoadScene" part, does the animation then play correctly?
I suspect that the Animation bool is for some reason not allowed to carry out it's actions before the entire method has been run through, could be wrong though.
My unity shutdown without saving but it now works. If anyone has this problem remake the animation and MAKE SURE you go from the initial animation and click add clip. Then it worked for me :)
The states and animations not my own.
I have a prefab of a character that have Animator component attached to it. The character in the Hierarchy have Animator with some states and blends and also have some animation clips.
Now when i play/run a State of the Animator is that meaning i'm playing animation? Or the animation clips is something else ?
And why i can't playing the animation clips ? I'm not getting errors or exceptions it's just not playing it.
Here is a script that attached to this character and i also added to this character a Animation component. So now the character object have both Animator and Animation components.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SwitchAnimations : MonoBehaviour
{
private Animator animator;
private int index = 0;
private static UnityEditor.Animations.AnimatorController controller;
private UnityEditor.Animations.AnimatorState[] an;
// Use this for initialization
void Start()
{
animator = GetComponent<Animator>();
an = GetStateNames(animator);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
animator.Play(an[index].name);
if (++index == an.Length)
index = 0;
}
}
private static UnityEditor.Animations.AnimatorState[] GetStateNames(Animator animator)
{
controller = animator ? animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController : null;
return controller == null ? null : controller.layers.SelectMany(l => l.stateMachine.states).Select(s => s.state).ToArray();
}
private void RollSound()
{
}
private void CantRotate()
{
}
private void EndRoll()
{
}
private void EndPickup()
{
}
}
Inside the variable an there are 9 states:
Aiming
Death_A
Use
Grounded
Roll
PickupObject
Reload_Rifle
Shoot_Rifle
Empty
When i click on A key it's playing the states one by one each time i click on A Everything is working fine i can play the 9 states by clicking on A.
what i don't understand with the States is inside the editor when i'm in the hierarchy selecting the character and in the menu make: Window > Animator i see the 9 states on the LegsLayer:
But then if i click on state Grounded double click i see a blend tree and i'm not sure if this is also states or maybe this is animation clips ? Then how can i get access to them ?
Ok this is one part i don't understand yet about the Animator and what and how i can play with it.
The second part is related to AnimationClip/s and why i can't play them ?
The script for animations clips:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
public class SwitchAnimations : MonoBehaviour
{
private Animation animation;
private AnimationClip[] animationClips;
// Use this for initialization
void Start()
{
animation = GetComponent<Animation>();
animationClips = AnimationUtility.GetAnimationClips(gameObject);
foreach (AnimationClip clip in animationClips)
{
animation.AddClip(clip, clip.name);
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
animation.clip = animationClips[6];
animation.Play(animationClips[6].name);
}
}
private void RollSound()
{
}
private void CantRotate()
{
}
private void EndRoll()
{
}
private void EndPickup()
{
}
private void FootStep()
{
}
}
And in the variable animationClips i have 9 animations:
Rifle_Aiming_Idle
Rifle_Aiming_Walk_F_RM
Rifle_Aiming_Walk_B_RM
Rifle_Aiming_Walk_L_RM
Rifle_Aiming_Walk_R_RM
Rifle_Idle
Rifle_Walk_F_RM
Rifle_Run_F_RM
Rifle_Sprint_F_RM
When i'm running the game and clicking on A this time i see in the Inspector inside the Animation component all the animation clips and in Animation i see the animation clip to play.
I'm not getting any errors or exceptions but it's just not playing it. The character stay still idle. Even if i choose another animation clip index to play 5 or 3 or 1 nothing is playing.
I wonder why it's not playing the animations when i click A. In this case animation number 6 from the List but still not playing.
The Animation component is a legacy component, kept in Unity to ensure backward compatibility with older projects, so you should never use it for animations.
Basically, the system works this way:
First of all, you need an Animator Controller asset. This Animator is a Finite State Machine (with substates etc.), and every single state can have an Animation Clip (you assign it via script of via Inspector in the Motion field). When the FSM enters a specific state, it will play the Animation Clip assigned.
Clearly the Animator, in order to be used by a game object, has to be assigned to that object via the Animator component.
Animation Clips are assets which contain the actual animation, they're never assigned as components to game objects, but instead they must be referenced by an Animator to be played, as I said before.
Blend trees are used to blend different animations in a seamless way by using linear interpolation. They're a "special" state of the Animator, which has multiple Animation Clips that you can interpolate to display transitions from a state to another, for example when you need to change the animation among running forward, running left and running right.
The argument is very broad, you can start to get into it by reading the official documentation about Animators, Animation Clips and Blend Trees here:
https://docs.unity3d.com/Manual/AnimationSection.html