Coroutine issue in VR - c#

I have tried everything with this. The coroutine will do nothing after yield return. My timestep is 0.005, because I'm executing this in VR (and require this setup). I have no idea if it has anything to do with it, I have read conflicting info. Please help, totally stumped. If there is another route I should go down, happy to dry a different method.
Ideally: tap on object, voiceover comes on and panel appears, panel disappears after 5sec, voiceover obj gets destroyed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ActiveTouch : MonoBehaviour
{
bool redCell;
bool whiteCell;
bool plateletCell;
bool plasmodiumCell;
public GameObject plasmodiumGroup;
public GameObject rPanel;
public GameObject wPanel;
public GameObject pPanel;
public GameObject pfPanel;
public GameObject mPanel;
public GameObject welldonePanel;
public GameObject dragdropPanel;
public GameObject infoPanel;
public AudioSource myAudioSource;
public AudioSource rAudioSource;
public GameObject rAudio;
public AudioSource wAudioSource;
public GameObject wAudio;
public AudioSource pAudioSource;
public GameObject pAudio;
public AudioSource pfAudioSource;
public GameObject pfAudio;
public GameObject groupParent;
Animator groupAnimator;
private void Start()
{
redCell = false;
whiteCell = false;
plateletCell = false;
plasmodiumCell = false;
plasmodiumGroup.SetActive(false);
rPanel.SetActive(false);
wPanel.SetActive(false);
pPanel.SetActive(false);
pfPanel.SetActive(false);
welldonePanel.SetActive(false);
dragdropPanel.SetActive(false);
mPanel.SetActive(true);
rAudio.SetActive(true);
wAudio.SetActive(true);
pAudio.SetActive(true);
pfAudio.SetActive(true);
}
void OnTriggerEnter(Collider col)
{
if (col.gameObject.CompareTag("WhiteBloodCell"))
{
//Debug.Log("White Cell triggered!");
whiteCell = true;
mPanel.SetActive(false);
wPanel.SetActive(true);
myAudioSource.Play();
wAudio.SetActive(true);
wAudioSource.Play();
if (wAudioSource.isPlaying)
{
rAudio.SetActive(false);
pAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(wPanelCoroutine(wPanel));
StartCoroutine(PanelCoroutine(wPanel));
}
else if (col.gameObject.CompareTag("RedBloodCell"))
{
redCell = true;
mPanel.SetActive(false);
rPanel.SetActive(true);
//Debug.Log("Red Cell triggered!");
myAudioSource.Play();
rAudio.SetActive(true);
rAudioSource.Play();
if (rAudioSource.isPlaying)
{
wAudio.SetActive(false);
pAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(rPanelCoroutine(rPanel));
StartCoroutine(PanelCoroutine(rPanel));
}
else if (col.gameObject.CompareTag("PlateletCell"))
{
//Debug.Log("Platelet Cell triggered!");
plateletCell = true;
mPanel.SetActive(false);
pPanel.SetActive(true);
myAudioSource.Play();
pAudio.SetActive(true);
pAudioSource.Play();
if (pAudioSource.isPlaying)
{
wAudio.SetActive(false);
rAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(pPanelCoroutine(pPanel));
StartCoroutine(PanelCoroutine(pPanel));
}
else if (col.gameObject.CompareTag("PlasmodiumF"))
{
plasmodiumCell = true;
mPanel.SetActive(false);
pfPanel.SetActive(true);
myAudioSource.Play();
pfAudio.SetActive(true);
pfAudioSource.Play();
if (pfAudioSource.isPlaying)
{
wAudio.SetActive(false);
pAudio.SetActive(false);
rAudio.SetActive(false);
}
//StartCoroutine(pfPanelCoroutine(pfPanel));
StartCoroutine(PanelCoroutine(pfPanel));
}
else
{
}
}
IEnumerator PanelCoroutine(GameObject myPanel)
{
myPanel.SetActive(true);
yield return new WaitForSeconds(35);
myPanel.SetActive(false);
infoPanel.SetActive(true);
if (redCell == true)
{
if(GameObject.FindWithTag("RedAudio"))
Destroy (GameObject.FindWithTag("RedAudio"));
}
else if (whiteCell == true)
{
if(GameObject.FindWithTag("WhiteAudio"))
Destroy (GameObject.FindWithTag("WhiteAudio"));
}
else if (plateletCell == true)
{
if(GameObject.FindWithTag("PLAudio"))
Destroy (GameObject.FindWithTag("PLAudio"));
}
else if (plasmodiumCell == true)
{
if(GameObject.FindWithTag("PFAudio"))
Destroy (GameObject.FindWithTag("PFAudio"));
}
}
void Update()
{
if (redCell == true && whiteCell == true && plateletCell == true)
{
Debug.Log("yay");
rPanel.SetActive(false);
pPanel.SetActive(false);
wPanel.SetActive(false);
welldonePanel.SetActive(true);
//StartCoroutine(DoneCoroutine(welldonePanel));
plasmodiumGroup.SetActive(true);
redCell = false;
whiteCell = false;
plateletCell = false;
}
if (plasmodiumCell == true)
{
welldonePanel.SetActive(false);
pfPanel.SetActive(false);
dragdropPanel.SetActive(true);
}
}

Related

A fade animation on another gameObject

is actually a rythm game and when a circle enter into a trigger we can make disapear the circle.
public class CursorPress : MonoBehaviour {
public bool canBePressed;
public KeyCode keyToPress;
void Update()
{
if (Input.GetKeyDown(keyToPress))
{
GameObject target = GameObject.Find("hitcircle_r");
if(target.tag == "Target")
{
if (canBePressed)
{
target.GetComponent<Animation> ().play("hitcircle_fading");
target.SetActive(false);
}
}
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = true;
}
}
void OnTriggerExit2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = false;
}
}
}
I want that when the player press a key (keyToPress), a custom gameObject (hitcircle_r) gets a fade animation before disapearing, but idk how to do it, i tried a lot of code i found on the web, can someone helps me please ?
There are many ways to achieve what you want.
One would be to call a coroutine that fades deactivates your target after time.
If you are only doing fading style animations you should look into DOTween.
using System.Collections;
using UnityEngine;
public class CursorPress : MonoBehaviour
{
public bool canBePressed;
public KeyCode keyToPress;
void Update()
{
if (Input.GetKeyDown(keyToPress))
{
GameObject target = GameObject.Find("hitcircle_r");
if (target.tag == "Target")
{
if (canBePressed)
{
target.GetComponent<Animation>().Play("hitcircle_fading");
float hideTime = 0.5f; // the length of your animation
StartCoroutine(DeactivateTarget(target, hideTime));
}
}
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = true;
}
}
void OnTriggerExit2D(Collider2D col)
{
if (col.gameObject.tag == "Target")
{
canBePressed = false;
}
}
// coroutine to deactivate GameObject
private IEnumerator DeactivateTarget(GameObject targetGo, float hideDelay)
{
yield return new WaitForSeconds(hideDelay);
targetGo.SetActive(false);
}
}

i have a camera shake script but when i click start it directy goes off and it wont stop

i have a camera shake script but when i click start it directy goes off and it wont stop
in this script i wanted to trigger the shake effect
public class GameOver : MonoBehaviour
{
public Explosion shake;
void OnCollisionEnter2D (Collision2D coll)
{
Debug.Log("Collision!");
if (coll.gameObject.tag == "platform")
{
Destroy(gameObject);
shake.GameOver = true;
}
}
}
and this is the other script
public class Explosion : MonoBehaviour
{
public Transform cameraTransform;
private Vector3 orignalCameraPos;
public float shakeDuration;
public float shakeAmount;
private bool canShake = false;
public bool GameOver = false;
private float _shakeTimer;
void Start()
{
orignalCameraPos = cameraTransform.localPosition;
GameOver = false;
_shakeTimer = 0;
}
void Update()
{
if (GameOver = true)
{
ShakeCamera();
}
}
public void ShakeCamera()
{
_shakeTimer = shakeDuration;
StartCameraShakeEffect();
}
public void StartCameraShakeEffect()
{
if (_shakeTimer > 0)
{
cameraTransform.localPosition = orignalCameraPos + Random.insideUnitSphere * shakeAmount;
_shakeTimer -= Time.deltaTime;
}
else
{
_shakeTimer = 0f;
cameraTransform.position = orignalCameraPos;
GameOver = false;
}
}
}
if you are able to help me i would be very thankfull :)
in the statement if (GameOver = true) you are setting GameOver to true and then checking its value. I think you might have wanted to use if (GameOver == true) or if (GameOver) which will check if this variable is set to true.

I want to enable my collider again after disabling it

When my character hits the gameobject collider, an enemy will be spawned and the collider is disabled, cuz I do not want to spawn multiple enemies. When my character dies and I have to start from the beginning, the collider should be enabled again to spawn the enemy again.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriggerSpawner : MonoBehaviour
{
public EnemySpawn enemyspawn;
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
enemyspawn.SpawnEnemy();
gameObject.GetComponent<BoxCollider2D>().enabled = false;
}
}
}
//in other class
private void SetHealth(float health)
{
var actualNextHealth = Mathf.Min(m_maxHealth, health);
m_currentHealth = actualNextHealth;
if (m_healthBar != null && m_maxHealth > 0f)
m_healthBar.SetHealth(actualNextHealth / m_maxHealth);
if (m_currentHealth <= 0f)
{
UpdateHighscore();
Die();
}
}
private void Die()
{
m_character.NotifyDied();
if (m_canRespawn)
{
SetVulnerable();
RemovePoison();
m_hazards.Clear();
gameObject.transform.position = m_spawnPosition;
SetHealth(m_maxHealth);
}
else {
Destroy(gameObject);
}
}
You can create a static variable in the trigger script that you assign the Collider value to it.
When an enemy is spawned it deactivates, as in your code.
public class TriggerSpawner : MonoBehaviour
{
public static Collider2D spawnCollider;
public EnemySpawn enemyspawn;
void Start() => spawnCollider.GetComponent<Collider2D>();
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
enemyspawn.SpawnEnemy();
spawnCollider.enabled = false;
}
}
}
When you die, it will reactivate.
private void Die()
{
m_character.NotifyDied();
if (m_canRespawn)
{
TriggerSpawner.spawnCollider.enabled = true;
SetVulnerable();
RemovePoison();
m_hazards.Clear();
gameObject.transform.position = m_spawnPosition;
SetHealth(m_maxHealth);
}
else {
Destroy(gameObject);
}
}
With minimal changes on your code, I'd suggest this:
private void Die()
{
m_character.NotifyDied();
if (m_canRespawn)
{
SetVulnerable();
RemovePoison();
m_hazards.Clear();
gameObject.transform.position = m_spawnPosition;
SetHealth(m_maxHealth);
gameObject.GetComponent<BoxCollider2D>().enabled = true; // add this line
}
else {
Destroy(gameObject);
}
}

OnCollisionExit() Not Working on my script unity?

I Am Working With Unity 3d and know little scripting and unity well. I Came To a point where I don't know what to do. My OnCollisionExit Don't Work on collision exit there is moment = true this dont work. Somebody told me you have not reset the variable. So I Don't Know How To Make It So Please Help. Thanks In Advance
This is The Player Script This Is My Script or code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
public Animator anim;
public Transform housepos;
public Transform deadpos;
public static bool safe1_click = false;
public bool safe1_clicked = false;
public float speed = 25;
public Rigidbody rb;
Collider mycollider;
float Walk = 8;
float jump = 7;
float sadWalk = 6;
float idle = 0;
public static bool stopwalking = false;
public static bool Jump = false;
public static bool sadwalk = false;
public static bool freeze = false;
public static bool yourchance = false;
public static bool movement = true;
public bool movement23 = true;
// Start is called before the first frame update
void Start()
{
mycollider = transform.GetComponent<Collider>();
rb = GetComponent<Rigidbody>();
anim.SetFloat("Animation", Walk);
stopwalking = false;
Jump = false;
freeze = false;
}
// Update is called once per frame
void Update()
{
movement23 = movement;
if (movement == true)
{
safe1_click = safe1_clicked;
rb.velocity = new Vector3(speed * Time.deltaTime, rb.velocity.y, 0);
}
else
{
rb.velocity = new Vector3(0,0,0);
}
if (Jump == true)
{
anim.SetFloat("Animation", jump);
}
if (Jump == true)
{
anim.SetFloat("Animation", sadWalk);
}
if (stopwalking == true)
{
anim.SetFloat("Animation", idle);
}
}
public void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "stop")
{
Debug.Log("Stopped");
spawner.stopspawn = true;
movement = false;
return;
}
if (collision.gameObject.tag == "dec")
{
Debug.Log("oh");
freeze = true;
}
}
public void OnCollisionExit(Collision collision)
{
if (collision.gameObject.tag == "stop")
{
Debug.Log("Spawning");
spawner.stopspawn = false;
movement = true;
}
if (collision.gameObject.tag == "dec")
{
Debug.Log("oh");
freeze = false;
}
}
public void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "fre")
{
spawner.yourchance = true;
}
if (other.gameObject.tag == "Player")
{
Destroy(other.gameObject);
}
if (other.gameObject.tag == "dec")
{
freeze = true;
Debug.Log("oh");
}
if (other.gameObject.tag == "new")
{
yourchance = true;
Debug.Log("stopstop");
}
if (other.gameObject.tag == "con")
{
Debug.Log("collide happened");
movement = true;
}
}
private void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "dec")
{
freeze = false;
Debug.Log("oh");
}
}
}

Coroutine not starting due to inactive game object

I'm getting an error message and I'm not exactly sure how to solve. I'm trying to start a countdown after a short period of idleness that then kicks off a second countdown that is paired with a visual warning. As soon as the coroutine kicks on I'm getting this error:
Coroutine couldn't be started because the the game object '_CountdownTimer' is inactive!
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
CountdownTimer:StartPreCountTimer() (at Assets/_Components/_Scripts/CountdownTimer.cs:38)
GameManager:CheckUserActivity() (at Assets/_Components/_Scripts/GameManager.cs:68)
What am I missing? Where would I need to set the active state of _CountdownTimer? Thank you!!
GameManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager gameManagerInstance = null; // Create Singleton
public float checkUserActivityInterval;
public GameObject loader;
public GameObject countdownTimer;
private GameObject gameManager;
private Vector3 currentMousePosition;
private Vector3 prevMousePosition;
private CountdownTimer countdownInstance;
private Scene currentScene;
public Color defaultBackgroundColor;
public Object startingScene;
public static bool userActive;
public static bool preCountActive;
public static bool restartWarningActive;
public static string animalDataFilePathJSON;
public static string animalDataFilePathTex;
void Awake ()
{
if (CountdownTimer.countdownTimerInstance == null)
Instantiate(countdownTimer);
if (gameManagerInstance == null)
gameManagerInstance = this;
else if (gameManagerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
void Start()
{
prevMousePosition = Input.mousePosition;
countdownInstance = countdownTimer.GetComponent<CountdownTimer>(); // Create an instance of CountdownTimer
InvokeRepeating("CheckUserActivity", 0, checkUserActivityInterval);
InvokeRepeating("SetPrevMousePosition", 0, checkUserActivityInterval);
}
void Update()
{
currentScene = SceneManager.GetActiveScene();
currentMousePosition = Input.mousePosition;
}
void CheckUserActivity()
{
if (currentScene.name != startingScene.name)
{
if (currentMousePosition == prevMousePosition)
{
Debug.Log("MOUSE HAS NOT MOVED!!");
userActive = false;
if (!userActive && !preCountActive)
countdownInstance.StartPreCountTimer();
}
if (currentMousePosition != prevMousePosition)
{
Debug.Log("MOUSE HAS MOVED!!");
userActive = true;
if (preCountActive == true)
countdownInstance.RestartPreCountTimer();
}
}
}
void SetPrevMousePosition()
{
prevMousePosition = Input.mousePosition;
}
}
CountdownTimer.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour
{
public static CountdownTimer countdownTimerInstance = null; // Create Singleton
public Object startingScene;
public GameObject timeOutWarningDialog;
private GameObject timerDialogBoxInstance;
private GameObject canvas;
private IEnumerator counter;
private Button stopCountButton;
private Text timerTextField;
public float countdownLength;
public float countdownDelay;
private float countdownInterval = 1;
void Awake()
{
if (countdownTimerInstance == null)
countdownTimerInstance = this;
else if (countdownTimerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
public void StartPreCountTimer()
{
GameManager.preCountActive = true;
GameManager.restartWarningActive = false;
counter = RunTimer(countdownDelay); // create new reference to counter
StartCoroutine(counter);
}
public void RestartPreCountTimer()
{
GameManager.preCountActive = false;
StopTimer();
}
void ShowRestartWarning()
{
GameManager.preCountActive = false;
GameManager.restartWarningActive = true;
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerDialogBoxInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
timerDialogBoxInstance.transform.SetParent(canvas.transform, false);
timerDialogBoxInstance.SetActive(true);
Text[] textFields = timerDialogBoxInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
timerTextField = textFields[2]; // access and assign countdown textfield
stopCountButton = timerDialogBoxInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
stopCountButton.onClick.AddListener(StopTimer); // add button listener
if (timerDialogBoxInstance.activeInHierarchy == true)
{
counter = RunTimer(countdownLength); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(counter);
}
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > -1)
{
if (GameManager.restartWarningActive == true)
if (timerTextField != null)
timerTextField.text = s.ToString();
yield return new WaitForSeconds(countdownInterval);
s -= countdownInterval;
}
if (s == -1)
{
if (GameManager.restartWarningActive == true)
RestartGame();
}
}
void StopTimer()
{
Debug.Log("Restart Cancelled");
StopCoroutine(counter);
Destroy(timerDialogBoxInstance);
}
void RestartGame()
{
SceneManager.LoadScene(startingScene.name);
}
}
I think I know where your error is. When you create an instance of the countdownTimer. You have to store a reference to it in order to get the underlying CountdownTimer class.
Try doing this, in your GameManager Class
private GameObject countDownTimerInstance;
Awake()
countDownTimerInstance = Instantiate(countdownTimer);
and in the Start() do,
countdownInstance = countdownTimerInstance.GetComponent<CountdownTimer>();
I think the problem was you were directly accessing the prefab's getComponent() instead of the instantiated gameObject's CountdownTimer!.

Categories