When I enter a collider for a certain game object I would like to play a different sound according to whether its the first time entering the sphere collider or the 2nd or 3rd time. Can this all be written in the same script?
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
//attach in inspector or make private and get with code in the Start()
public AudioSource audioSource1;
public AudioSource audioSource2;
void Start() {
// get audioSources optional
}
int colCounter = 0;
void OnCollisionEnter(Collision collision) {
colCounter++;
if (colCounter == 1)
audioSource1.Play();
else
audioSource2.Play();
}
}
Related
I'm trying to shoot bullets in a 2D top-down-shooter game but they just stay rest and doesnt move
I tried to add "addforce" but they didnt move. I changed it with "new Vector2" but that time it doesnt follow my cursor. istead of it shoots in a different same direction.I want to shoot to my cursor. and if possible I want to add a fire delay between object and make it possible to attack repeatly while holding mouse left button.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
public Transform firePoint;
public GameObject bulletPrefab;
public float bulletForce = 15f;
void Update()
{
if (Input.GetButtonDown("Fire1"))
Shoot();
}
void Shoot()
{
GameObject bullet = Instantiate(bulletPrefab,firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.right* bulletForce, ForceMode2D.Impulse);
}
}//class
`
I'm trying to shoot a raycast from a gameobject at the front of a gun that is being carried by an XR hand. The gun shoots fine most of the time, but sometimes, for some reasons beyond my fragile little minds comprehension, it shoots in the wrong direction. It shoots in random directions, but never more than 90 degrees of where it should be. This is my code. [I have attached a video of it happening.][1] Every time I think I find a pattern, it changes. All I can say is that I have reason to believe it's related to mesh colliders. Only very vague reason though. Edit: https://youtu.be/JxC4wq9nVRw here's an updated video, it shows the problem more clearly. I also changed the redundant if statements.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class GunBasic : MonoBehaviour
{
public Transform BulletShootPoint;
public ParticleSystem muzzleFlash;
public GameObject impactEffect;
public AudioSource audioSource;
public AudioClip audioClip;
public float Ammo;
public TextMeshPro text;
public void Fire()
{if (Ammo > 0)
{
muzzleFlash.Play();
audioSource.PlayOneShot(audioClip);
RaycastHit hit;
if (Physics.Raycast(BulletShootPoint.transform.position, BulletShootPoint.transform.forward, out hit) && Ammo > 0)
{
Debug.Log(hit.transform.name);
GameObject impactDestroy = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(impactDestroy, 2f);
}
Ammo -= 1f;
}
}
private void Update()
{
text.text = Ammo.ToString();
}
public void Reload()
{
Ammo = 10;
}
public void OnTriggerEnter(Collider other)
{
if(other.tag == "ReloadTag")
{
Ammo = 10f;
}
}
}
It was a bug in the xr interaction toolkit. It was fixed by an update. Sorry I didn’t try this sooner, thanks for all the help.
Unity has a new inputsystem where the old OnMouseDown() {} no longer works.
In the migration guide they mention replacing this with Mouse.current.leftButton.isPressed.
And in other forum posts they mention using an InputAction.
The problem is that these options detect mouse clicks anywhere in the scene, instead of just on the object:
public InputAction clickAction;
void Awake() {
clickAction.performed += ctx => OnClickedTest();
}
void OnClickedTest(){
Debug.Log("You clicked anywhere on the screen!");
}
// this doesn't work anymore in the new system
void OnMouseDown(){
Debug.Log("You clicked on this specific object!");
}
How can I detect mouse clicks on a specific gameObject with the new input system in Unity?
With this code somewhere in your scene:
using UnityEngine.InputSystem;
using UnityEngine;
public class MouseClicks : MonoBehaviour
{
[SerializeField]
private Camera gameCamera;
private InputAction click;
void Awake()
{
click = new InputAction(binding: "<Mouse>/leftButton");
click.performed += ctx => {
RaycastHit hit;
Vector3 coor = Mouse.current.position.ReadValue();
if (Physics.Raycast(gameCamera.ScreenPointToRay(coor), out hit))
{
hit.collider.GetComponent<IClickable>()?.OnClick();
}
};
click.Enable();
}
}
You can add an IClickable Interface to all GameObjects that want to respond to clicks:
public interface IClickable
{
void OnClick();
}
and
using UnityEngine;
public class ClickableObject : MonoBehaviour, IClickable
{
public void OnClick()
{
Debug.Log("somebody clicked me");
}
}
Make sure you have a an EventSystem with an InputSystemUIInputModule in the scene and a PhysicsRaycaster or Physics2DRaycaster on your Camera, and then use the IPointerClickHandler interface on the object with a collider on itself or its children:
using UnityEngine;
using UnityEngine.EventSystems;
public class MyClass : MonoBehaviour, IPointerClickHandler {
public void OnPointerClick (PointerEventData eventData)
{
Debug.Log ("clicked");
}
}
in my Unity scene I'm trying to activate a portal animation when you pick up all the coins on that level, but the problem is that my portal script does not detect when the coin counter value is equal to 6 (that's the total number of coins in that level).
I have this script which is the script that is attached to the coins and increases the coin counter value.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonedaScript2 : MonoBehaviour
{
public GameObject moneda;
public AudioClip clip;
public Vector3 PosicionMoneda;
public void Update ()
{
transform.Rotate (0, 90 * Time.deltaTime, 0);
}
public void OnTriggerEnter(Collider other)
{
if (other.name == "Player")
{
AudioSource.PlayClipAtPoint(clip, PosicionMoneda, 1f);
AparecerPortalNivel9.ContadorMonedas += 1;
Destroy(moneda);
}
}
}
And then i have the portal script which sould detect ewhen you pick all the coins. It is attached to the PanelPortal gameobject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AparecerPortalNivel9 : MonoBehaviour
{
public Animator anim;
public GameObject PanelPortal;
//public ScoringSystem SS;
public bool DeberiaAparecer = true;
public static int ContadorMonedas;
void Start()
{
//SS = GameObject.FindGameObjectWithTag("SistemaDeScore").GetComponent; ScoringSystem();
PanelPortal.gameObject.SetActive(false);
}
void Update()
{
if (ContadorMonedas == 6f)
{
Debug.Log("FuncionaHostia");
PanelPortal.gameObject.SetActive(true);
anim.SetBool("Aparecer",true);
DeberiaAparecer = false;
}
}
}
Could someone help me on what should i do so my portal script detects when the coins picked up are 6 and then run all the functions inside the IF method?
Thanks everyone
A MonoBehaviour's Update will never run while the gameobject it is on is disabled.
Because AparecerPortalNivel9 is attached to PanelPortal, when you do this you are preventing the Update method from being called:
PanelPortal.gameObject.SetActive(false);
The easiest solution here is to move AparecerPortalNivel9 to a different gameobject.
I was getting Missing Reference Exception within my Audio Source when I change my game scene and again move back to the same scene.
Before I change the main menu scene, it is working fine but after changing and moving back to the main menu scene, it is started showing this exception.
Here is the code I have written for AudioManager:
public class AudioManager : MonoBehaviour
{
static AudioManager instance;
//
[SerializeField] AudioClip buttonClickClip;
[SerializeField] AudioSource myAudioSource;
private void Awake()
{
instance = this;
}
public static AudioManager Instance
{
get
{
return instance;
}
}
public void PlayButtonClickSound()
{
if (GameManager.Instance.IsEnableSounds)
myAudioSource.PlayOneShot(buttonClickClip);
}
}
Here is the code that I wrote for DontDestroyOnLoad purpose:
public class DontDetroyOnLoad : MonoBehaviour
{
private static bool created = false;
void Awake()
{
if (!created)
{
DontDestroyOnLoad(this.gameObject);
created = true;
}
else
Destroy(this.gameObject);
}
}
Now please give me some suggestion to solve this problem.
You are referencing the AudioManager that you are destroying in the script that is trying to play the sound.
Think of it this way. You have
AudioManager A - DontDestroyOnLoad
AudioManager B - That gets destroyed cause A exists
In your scripts you are referencing AudioManager A when you first start up. Then when you leave the Scene and return you are now referencing AudioManager B, which got destroyed because A exists. All you need to do is always reference AudioManager A, not B.
Appreciate the answer from #jfish. That clearly describes the situation.
Here let me elaborate mine, on the example of using DontDestroyOnLoad
[SerializeField] AudioSource audioSource;
void Awake()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("music");
if (objs.Length > 1)
{
Destroy(this.gameObject);
//Here, get the previous audioSource from previous game object
audioSource = objs[0].GetComponent<AudioSource>();
}
DontDestroyOnLoad(this.gameObject);
}
On first load, it gets from Editor.
Subsequently, it gets from previous game object.