when I instsiate the bomb it makes more then one sometimes up to 3bombs at once I want it to make 1 bomb not 2 or 3 bombs.
I need a way to be sure it only use the void dropbomb once.
I'm looking forward to your help I like to say sry for the bad English and maby that point that I could have missed something important in my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlaneBombDroper : MonoBehaviour
{
public GameObject bomb;
public GameObject bombDropPostion;
public GameObject planePostion;
int bombDropRandomNum;
public float[] dropPostionsX;
bool bombIsDroped;
// Use this for initialization
void Start()
{
bombDropRandomNum = Random.Range(1, 3);
}
void Update()
{
if (bombDropRandomNum == 1 && bombIsDroped != true)
{
if (planePostion.transform.position.x < -2.75f && planePostion.transform.position.x > -3)
{
dropBomb();
}
}
if (bombDropRandomNum == 2&& bombIsDroped != true)
{
if (planePostion.transform.position.x < -9.5 && planePostion.transform.position.x > -10)
{
StartCoroutine("WaitForSeconds");
StopCoroutine("WaitForSeconds");
}
}
}
void dropBomb()
{
Instantiate(bomb, gameObject.transform.position, gameObject.transform.rotation);
}
IEnumerator WaitForSeconds()
{
dropBomb();
yield return new WaitForSeconds(1);
}
}
the bombdrop function fires off a new bomb irrelevant of if there is a bomb already in action - you need to add a condition that if a bomb is firing not to run that new bomb code. You already have the bombisdroped variable - it makes sense that if (!bombisdroped) is then your new bombdrop function
Simply add a flag on your update
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlaneBombDroper : MonoBehaviour
{
public GameObject bomb;
public GameObject bombDropPostion;
public GameObject planePostion;
int bombDropRandomNum;
public float[] dropPostionsX;
bool bombIsDroped;
private bool launchingBomb = false;
// Use this for initialization
void Start()
{
bombDropRandomNum = Random.Range(1, 3);
}
void Update()
{
if (!launchingBomb)
{
if (bombDropRandomNum == 1 && bombIsDroped != true)
{
if (planePostion.transform.position.x < -2.75f && planePostion.transform.position.x > -3)
{
dropBomb();
}
}
if (bombDropRandomNum == 2&& bombIsDroped != true)
{
if (planePostion.transform.position.x < -9.5 && planePostion.transform.position.x > -10)
{
StartCoroutine("WaitForSeconds");
StopCoroutine("WaitForSeconds");
}
}
}
void dropBomb()
{
launchingBomb = true;
Instantiate(bomb, gameObject.transform.position, gameObject.transform.rotation);
launchingBomb = false;
}
IEnumerator WaitForSeconds()
{
launchingBomb = true;
dropBomb();
yield return new WaitForSeconds(1);
}
}
Related
I wanted to add multiplayer to my game but i quickly faced many many problems, i cant find any clear solution online. i made a weapon script where the player can shoot and reload.
problems:
when i shoot, on 1 screen both players shoot, but at the other screen nothing happens
when i swap weapons, on 1 screen both players swap weapons, on the second screen nothing happens
note: im still a complete beginner so go easy on me please :)) thanks!
weapon script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Photon.Pun;
public class weaponScript : MonoBehaviour
{
public weaponSO weaponStats;
public GameObject reloadingText;
public TMP_Text ammoValue;
public Transform firePoint;
public GameObject bulletPrefab;
public float bulletForce = 2f;
public bool isShooting;
public float pistolDamage;
public int currentAmmoClip = 1;
public int maxAmmoClip;
public int currentReserve = 1;
public int maxReserve;
public float reloadTime = 2f;
public bool isReloading = false;
public int bulletsShot;
public float startingDamage;
PhotonView view;
public void Start()
{
view = GetComponent<PhotonView>();
if(view.IsMine)
{
view.RPC("Update", RpcTarget.AllBuffered);
}
WeaponStats();
currentAmmoClip = maxAmmoClip;
currentReserve = maxReserve;
bulletsShot = maxAmmoClip - currentAmmoClip;
isShooting = false;
weaponStats.damage = startingDamage;
}
[PunRPC]
public void Update()
{
ammoValue.text = currentAmmoClip.ToString("0") + "/" + currentReserve.ToString("0");
if (Input.GetKeyDown(KeyCode.R))
{
if(currentReserve <= 0)
{
return;
}
if (currentAmmoClip == maxAmmoClip && !isReloading)
{
return;
}
else
{
StartCoroutine(Reload());
return;
}
}
if(Input.GetButtonDown("Fire1") && currentAmmoClip >= 1)
{
if(isReloading == false)
{
bulletsShot += 1;
currentAmmoClip -= 1;
isShooting = true;
Shoot();
FindObjectOfType<AudioManager>().Play("shot1");
return;
}
}
if(isReloading)
return;
if(currentAmmoClip <= 0 && currentReserve >= 1)
{
StartCoroutine(Reload());
return;
}
}
IEnumerator Reload()
{
reloadingText.SetActive(true);
isReloading = true;
yield return new WaitForSeconds(reloadTime);
if(currentReserve <= bulletsShot)
{
currentAmmoClip += currentReserve;
currentReserve = 0;
}
else
{
currentReserve -= bulletsShot;
currentAmmoClip = maxAmmoClip;
}
bulletsShot = 0;
reloadingText.SetActive(false);
isReloading = false;
}
void Shoot()
{
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
}
public void WeaponStats()
{
pistolDamage = weaponStats.initialDamage;
maxAmmoClip = weaponStats.maxAmmoClip;
maxReserve = weaponStats.maxReserve;
reloadTime = weaponStats.reloadTime;
bulletForce = weaponStats.bulletForce;
startingDamage = weaponStats.initialDamage;
}
}
weapon holder:
using UnityEngine;
public class WeaponHolder : MonoBehaviour
{
public int selectedWeapon = 0;
void Start()
{
SelectWeapon();
}
void Update()
{
if(FindObjectsOfType<weaponScript>()[0].isReloading == true)
{
return;
}
else
{
switchWeapon();
}
}
public void switchWeapon()
{
int previousSelectedWeapon = selectedWeapon;
if(Input.GetAxis("Mouse ScrollWheel") > 0f)
{
if(selectedWeapon >= transform.childCount - 1)
{
selectedWeapon = 0;
}
else
{
selectedWeapon++;
}
}
if(Input.GetAxis("Mouse ScrollWheel") < 0f)
{
if(selectedWeapon <= 0)
{
selectedWeapon = transform.childCount - 1;
}
else
{
selectedWeapon--;
}
}
if(previousSelectedWeapon != selectedWeapon)
{
SelectWeapon();
}
}
public void SelectWeapon()
{
int i = 0;
foreach (Transform weapon in transform)
{
if(i == selectedWeapon)
{
weapon.gameObject.SetActive(true);
}
else
{
weapon.gameObject.SetActive(false);
}
i++;
}
}
}
i tried adding
if(view.IsMine == true)
{
Debug.Log("true");
}
else
{
Debug.Log("false");
}
but nothing happened and i couldnt shoot anymore. thanks for reading
The problem is you don't sync anything in your game. This means the other computer can't know what it has to do.
Whenever you want to sync something you have to call an RPC function.
Maybe watch some tutorials about how to do this properly and how to set up a simple multiplayer lobby.
EDIT:
What the other comments above mentioned with .IsMine is true, but you're doing it wrong. You have to call this in start or awake and whenever the view is not yours you disable the camera of the person only and disable shooting. Its important to only do this on your computer! If you are not doing everyone will shoot when you press Shoot and everyone will walk when you walk.
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'm new to Unity, I'm using it to make 2D games for Android, when I hold the right button or left button, it doesn't continue moving , it just moves once, What I want to do is when I hold the right button or left button, I want the character to continue moving until I release the button. Could someone please help? I would greatly appreciate it! The tutorial is here
Here's the code for botonDerScript.cs:
using UnityEngine;
using System.Collections;
public class botonDerScript : MonoBehaviour {
private PersonajeScript personaje;
private CircleCollider2D presionar;
void Start()
{
presionar = this.gameObject.GetComponent<CircleCollider2D>();
}
// Update is called once per frame
void Update()
{
tocandoPantalla();
}
private void tocandoPantalla()
{
int numPresiones = 0;
foreach (Touch toque in Input.touches)
{
if (toque.phase != TouchPhase.Ended && toque.phase != TouchPhase.Canceled)
numPresiones++;
}
if (numPresiones > 0 | Input.GetMouseButtonDown(0))
{
Vector3 posicionTap = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 posicionTap2D = new Vector2(posicionTap.x, posicionTap.y);
bool presiono = presionar.OverlapPoint(posicionTap2D);
if (presiono)
{
personaje = this.transform.parent.gameObject.GetComponent<PersonajeScript>();
personaje.MoverJugadorDerecha();
}
}
}
}
Here's the code for botonIzqScript.cs:
using UnityEngine;
using System.Collections;
public class botonIzqScript : MonoBehaviour {
private PersonajeScript personaje;
private CircleCollider2D presionar;
void Start()
{
presionar = this.gameObject.GetComponent<CircleCollider2D>();
}
// Update is called once per frame
void Update()
{
tocandoPantalla();
}
private void tocandoPantalla()
{
int numPresiones = 0;
foreach (Touch toque in Input.touches)
{
if (toque.phase != TouchPhase.Ended && toque.phase != TouchPhase.Canceled)
numPresiones++;
}
if (numPresiones > 0 | Input.GetMouseButtonDown(0))
{
Vector3 posicionTap = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 posicionTap2D = new Vector2(posicionTap.x, posicionTap.y);
bool presiono = presionar.OverlapPoint(posicionTap2D);
if (presiono)
{
personaje = this.transform.parent.gameObject.GetComponent<PersonajeScript>();
personaje.MoverJugadorIzquierda();
}
}
}
}
Here's the code for PersonajeScript.cs :
using UnityEngine;
using System.Collections;
public class PersonajeScript : MonoBehaviour {
private JugadorScript[] jugadores;
void Start () {
jugadores = GetComponentsInChildren<JugadorScript>();
}
// Update is called once per frame
void Update () {
}
public void MoverJugadorIzquierda()
{
foreach (JugadorScript jugador in jugadores)
if (jugador != null) {
jugador.moverIzquierda();
}
}
public void MoverJugadorDerecha()
{
foreach (JugadorScript jugador in jugadores)
if (jugador != null) {
jugador.moverDerecha();
}
}
}
And finally, here's the code for JugadorScript.cs:
using UnityEngine;
using System.Collections;
public class JugadorScript : MonoBehaviour
{
public float velocidad = -10f;
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void moverIzquierda()
{
transform.Translate(Vector2.right * velocidad * Time.deltaTime);
transform.eulerAngles = new Vector2(0, 0);
}
public void moverDerecha()
{
transform.Translate(Vector2.right * velocidad * Time.deltaTime);
transform.eulerAngles = new Vector2(0, 180);
}
}
In your botonIzqScript.cs you have the if statement
if (numPresiones > 0 | Input.GetMouseButtonDown(0))
{
...
}
Change the | in the conditional to ||. | is a binary operator. || is the "OR" operator.
Do the same in your botonDerScript.cs script
Update
To stop moving when the mouse button is released, add the following if statement:
if (Input.GetMouseButtonUp(0) || (Input.touchSupported && numPresiones == 0))
{
// stop moving
}
I'm trying to get a number between 0 and 3. I am trying to iterate through a counter and every 5 clicks on a button, it calls a method, but I can't seem to figure it out. I have tried various ways to do it. If I could get some hints on how to complete this then please let me know. If you need any other info then also let me know. Thanks!
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class ButtonClick : MonoBehaviour {
private Vector3 starPos;
private int starCounter;
private int[] starTypes;
private int totalStarTypes = 4;
public Button button;
public UnityEngine.UI.Text starCounterText;
private Image starImage;
// Use this for initialization
void Start () {
starTypes = new int[totalStarTypes];
}
void Update(){
if (Input.GetMouseButtonDown (0)) {
starCounter++;
}
for (int i = 0; i < starCounter; i++) {
int j = i;
int type = (j % 5);
if (type == 0) {
//SpawnStar (j%5);
}
}
}
// Update is called once per frame
public void UpdateStar () {
starCounterText.text = "Star Counter: " + starCounter;
}
public void SpawnStar(int type){
if (type == 0) {
Debug.Log ("White Star Spawned!");
}
if (type == 1) {
Debug.Log ("Red Star Spawned!");
}
if (type == 2) {
Debug.Log ("Yellow Star Spawned!");
}
if (type == 3) {
Debug.Log ("Blue Star Spawned!");
}
}
}
Random r = new Random();
void Update()
{
if (Input.GetMouseButtonDown(0))
{
starCounter = (starCounter + 1) % 5;
if (starCounter == 0) SpawnStar(r.Next(0, 4));
}
}
Your code will spawn the all stars every frame after the 5'th click.
Try this, it will spawn a single star when you click, and only the one you wanted to spawn.
The int starCounter will handle which star to spawn
The bool executeSpawn will handle when to spawn a star
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class ButtonClick : MonoBehaviour {
private Vector3 starPos;
private int starCounter;
private bool executeSpawn;
private int[] starTypes;
private int totalStarTypes = 4;
public Button button;
public UnityEngine.UI.Text starCounterText;
private Image starImage;
// Use this for initialization
void Start () {
starTypes = new int[totalStarTypes];
}
void Update(){
if (Input.GetMouseButtonDown (0)) {
starCounter++;
executeSpawn = true;
}
if(executeSpawn) {
SpawnStar (i % 5);
executeSpawn = false;
}
}
// Update is called once per frame
public void UpdateStar () {
starCounterText.text = "Star Counter: " + starCounter;
}
public void SpawnStar(int type){
if (type == 0) {
Debug.Log ("White Star Spawned!");
}
if (type == 1) {
Debug.Log ("Red Star Spawned!");
}
if (type == 2) {
Debug.Log ("Yellow Star Spawned!");
}
if (type == 3) {
Debug.Log ("Blue Star Spawned!");
}
}
}
If i am at location 1 and hit it,after the delay of 10 sec arrows to the location 3 generates.
Now I move to location 3, when I hit location 3, Arrows generated by location 2 should turn off.
I tried hard to get my Deactivate previous function working but failed. Can anybody help regarding this?
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour {
public int _currentCheckPoint = 0;
public ArrowObjects _arrowObjectInstance;
public float _checkPointWaiTime = 10;
public float _elappsedTime;
public bool GenerateArrow = false;
void Start()
{
_arrowObjectInstance = GetComponent<ArrowObjects> ();
foreach (var item in _arrowObjectInstance._listArrowGameObject) {
item.SetActive (false);
}
}
void Update()
{
if (_currentCheckPoint != 0 && GenerateArrow) {
GenerateArrow = false;
Invoke ("DelayedActive", 10f);
}
print (_currentCheckPoint);
}
void DelayedActive()
{
_arrowObjectInstance._listArrowGameObject [_currentCheckPoint - 1].SetActive (true);
}
void DeactivePrevious()
{
_arrowObjectInstance._listArrowGameObject [_currentCheckPoint - 1].SetActive (false);
}
}
Changed the update part from the above script to this.
void Update()
{
if (_currentCheckPoint != 0 && GenerateArrow) {
GenerateArrow = false;
if (_currentCheckPoint > 1) {
_arrowObjectInstance._listArrowGameObject [_currentCheckPoint - 2].SetActive (false);
}
Invoke ("DelayedActive", 10f);
}
and added a check in