OnTriggerEnter not working properly - c#

In the game I'm making in order to call a dead state I'm using a box collider to track if the player enters in a particular zone, but the problem is that it only tracks it if I'm pressing any of the a,s,d or w keys in the keyboard.
This is the code.
The OnTriggerEnter is called in line 48.
using UnityEngine;
using System.Collections;
public class PlayerManager : MonoBehaviour
{
public bool Death = false;
public bool Alive = false;
public bool Muerto;
public GameObject Generador;
public GameObject StartButton;
public CharacterMotor Motor;
public static PlayerManager Instanse;
// Use this for initialization
void Start()
{
Instanse = this;
}
// Update is called once per frame
void Update()
{
if (gameObject.transform.position.y <= -3.5f)
Death = true;
if (!Alive)
Generador.transform.position = new Vector3(0, -0.57f, -4.98f);
if (Death)
{
Generador.transform.position = new Vector3(0, -0.57f, -4.12f);
GenerateManager.Instante.BeforeObject = GenerateManager.Instante.Spawn;
Motor.canControl = false;
StartButton.SetActive(true);
CameraMovement.Instanse.CanMoveCamera = false;
gameObject.transform.position = new Vector3(0.46f, 1.102971f, -6);
Camera.main.transform.position = new Vector3(-0.07402526f, 12.0031f, -1.937099f);
foreach (GameObject gm in GenerateManager.Instante.BloquesGenerados)
{
Destroy(gm);
}
GenerateManager.Instante.BloquesGenerados.Clear();
Death = false;
}
}
void OnTriggerStay(Collider other)
{
Debug.Log(other.tag);
if (other.gameObject.tag == "Generador")
GenerateManager.Instante.DoGenerate = true;
if (other.gameObject.tag == "Muerte")
{
Alive = false;
Death = true;
}
}
}

Add rigidbody component to gameobject,set rigidbody component attribute kinematic=false.

Related

Why the when playing animation state it's executing the play twice in a row instead once?

The script is attached to empty gameobject
At this line i'm using the mouse left button to fire a bullet one time.
If i'm using a break point it will shot one bullet once. but if i'm not using a break point it will shot two bullets in a row one after the other.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class Shooting : MonoBehaviour
{
public CinemachineVirtualCamera cmf;
[Header("Main")]
public Rigidbody bulletPrefab;
public float launchForce = 700f;
public bool automaticFire = false;
public float bulletDestructionTime;
public bool go = false;
[Space(5)]
[Header("Slow Down")]
public float maxDrag;
public float bulletSpeed;
public bool bulletsSlowDown = false;
public bool overAllSlowdown = false;
[Range(0, 1f)]
public float slowdownAll = 1f;
public List<Transform> firePoints = new List<Transform>();
public Animator anim;
private void Start()
{
if (anim != null)
{
anim.SetBool("Shooting", true);
}
}
public void Update()
{
if (overAllSlowdown == true)
{
Time.timeScale = slowdownAll;
}
if (firePoints.Count > 0))
{
for (int i = 0; i < firePoints.Count; i++)
{
if (Input.GetMouseButton(0))
{
anim.SetTrigger("Shoot");
}
if (Input.GetMouseButton(1))
{
cmf.enabled = false;
}
if (go)
{
LaunchProjectile(firePoints[i]);
go = false;
}
}
}
}
private void LaunchProjectile(Transform firePoint)
{
Rigidbody projectileInstance = Instantiate(
bulletPrefab,
firePoint.position,
firePoint.rotation);
projectileInstance.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
cmf.enabled = true;
cmf.Follow = projectileInstance.transform;
cmf.LookAt = projectileInstance.transform;
projectileInstance.AddForce(new Vector3(0, 0, 1) * launchForce);
if (bulletsSlowDown == true)
{
if (projectileInstance != null)
{
StartCoroutine(AddDrag(maxDrag, bulletSpeed, projectileInstance));
}
}
}
IEnumerator AddDrag(float maxDrag, float bulletSpeed, Rigidbody rb)
{
if (rb != null)
{
float current_drag = 0;
while (current_drag < maxDrag)
{
current_drag += Time.deltaTime * bulletSpeed;
rb.drag = current_drag;
yield return null;
}
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.drag = 0;
}
}
}
This script is attached to my player with animator and i'm using this method to reference event i added to animation in the animator controller. when the event happens the variable bool flag go is set to true.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThrowObject : MonoBehaviour
{
public Shooting shooting;
public void ThrowEvent()
{
shooting.go = true;
}
}
This is a screenshot of the animator controller.
I added a new state name Throwing with two transitions from and to the Grounded state.
The Grounded state is playing idle animation.
In the transition from the Grounded to the Throwing i added a condition name Shoot type trigger.
In the transition from the Throwing state to the Grounded there is no any conditions.
Afaik animator triggers are stackable!
So since you call this in a for loop it might happen that it adds multiple triggers at once but each transition only consumes one at a time!
What I ended up using in combination with triggers in an animator is this script
public class AnimatorTriggerResetter : StateMachineBehaviour
{
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
foreach(var p in animator.parameters)
{
if (p.type == AnimatorControllerParameterType.Trigger)
{
animator.ResetTrigger(p.name);
}
}
}
}
attach this to no specific state at all but directly to the Basic layer of your AnimatorController itself => It is called for each and every state that is entered => resets all existing triggers.
In your specific case though, why not rather pull the general calls out of the loop and rather make it
if (firePoints.Count > 0 && go)
{
if (Input.GetMouseButton(0))
{
anim.SetTrigger("Shoot");
}
if (Input.GetMouseButton(1))
{
cmf.enabled = false;
}
for (int i = 0; i < firePoints.Count; i++)
{
LaunchProjectile(firePoints[i]);
}
go = false;
}

Everything breaks after using PlayOneShot

In a game I am working on, the player uses a cube to open doors. When the player interacts with the cube while near the door, the door slides open. I am now trying to make it so that while it slides open, it makes a sound as doors should but I kinda ran into some issues. When I tried to add in the sound for the door, it ignored the part where the door should open altogether.
Here is what I did:
I added an AudioSource to the Cube's child object, CORE because the Cube object already contains an AudioSource which will play at the same time as this sound and assigned it in my Cube's script...
public AudioSource Woosh;
void Start()
{
//Debug.Log("Script initialized!");
Hm = gameObject.GetComponent<AudioSource>();
anim = GameObject.Find("TheFirstDoor").GetComponent<Animator>();
//Door = GameObject.Find("TheFirstDoor").GetComponent<AudioSource>();
Woosh = GameObject.Find("CORE").GetComponent<AudioSource>();
}
Here's the interactive part of the script, it runs a check but for some reason, it is pretending CanBeKey is false...
public void OnActivate()
{
if(HasPlayed == false) //Have I played? Has the Time out passed?
{
HasPlayedFirstTime = true;
Hm.Play();
HasPlayed = true;
PlayTimeOut = 30.0f;
if(CanBeKey == true)
{
anim.Play("Door_Open");
//Door.Play();
StartCoroutine(PlayDaWoosh());
Debug.Log("OPENING!");
}
}
}
Now here is the IEnumerator part of the script, PlayDaWoosh()
IEnumerator PlayDaWoosh()
{
Woosh.PlayOneShot(Woosh.clip);
yield return new WaitForSeconds(Woosh.clip.length);
}
I am aware that the last code snippet is a bit messy but it was the best thing I can think of.
Here is the full script in case you are that curious.....
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CUBE_CORE : MonoBehaviour
{
public AudioSource Hm; // HM!!!
private bool HasPlayed = false;
public float PlayTimeOut = 0.0f;
public static bool CanBeKey = false;
public Animator anim;
public static bool HasPlayedFirstTime = false;
public static AudioSource Door;
public AudioSource Woosh;
// Start is called before the first frame update
void Start()
{
//Debug.Log("Script initialized!");
Hm = gameObject.GetComponent<AudioSource>();
anim = GameObject.Find("TheFirstDoor").GetComponent<Animator>();
//Door = GameObject.Find("TheFirstDoor").GetComponent<AudioSource>();
Woosh = GameObject.Find("CORE").GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
if(HasPlayed == true)
{
if (PlayTimeOut < 0.0f)
{
HasPlayed = false;
}
PlayTimeOut -= Time.smoothDeltaTime;
}
}
public void OnActivate()
{
if(HasPlayed == false) //Have I played? Has the Time out passed?
{
HasPlayedFirstTime = true;
Hm.Play();
HasPlayed = true;
PlayTimeOut = 30.0f;
if(CanBeKey == true)
{
anim.Play("Door_Open");
//Door.Play();
StartCoroutine(PlayDaWoosh());
Debug.Log("OPENING!");
}
}
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.name == "SecondDoor")
{
anim = GameObject.Find("DoorSecond").GetComponent<Animator>();
}
if(other.gameObject.name == "ThirdDoor")
{
anim = GameObject.Find("TheThirdDoor").GetComponent<Animator>();
}
if(other.gameObject.name == "FourthDoor")
{
anim = GameObject.Find("TheFourthDoor").GetComponent<Animator>();
}
}
IEnumerator PlayDaWoosh()
{
Woosh.PlayOneShot(Woosh.clip);
yield return new WaitForSeconds(Woosh.clip.length);
}
}
Expected result: Door opening and sound playing
Actual result: Neither happening unless I remove anything that has to do with the Woosh
I apologize ahead of time if I wasn't specific enough or if the question was answered somewhere else. I am relatively new here.

creating a Breakout game in unity3d c#-bricks wont get destroyed

I have made a breakout game using unity tutorials and everything seemed to work well, but when I played it in the game mode there were some errors. So after I tried fixing the errors, the bricks wont get destroyed anymore. I tried undoing it, writing the code anew or even writing the same project anew but nothing works. What can I do?
These are the codes for my game which are exactly like the codes in the tutorial!
Paddle:
public class Paddle : MonoBehaviour {
public float paddleSpeed = 1f;
private Vector3 playerPos = new Vector3(0, -9f, 0);
void Update ()
{
float xPos = transform.position.x + (Input.GetAxis("Horizontal")*paddleSpeed);
playerPos = new Vector3(Mathf.Clamp(xPos, -7.5f, 7.5f), -9f, 0f);
transform.position = playerPos;
}
}
Ball:
public class Ball : MonoBehaviour {
private float ballInitialVelocity = 600f;
private Rigidbody rb;
private bool ballInPlay;
void Awake ()
{
rb = GetComponent<Rigidbody>();
}
void Update ()
{
if(Input.GetButtonDown("Fire1") && ballInPlay==false)
{
transform.parent = null;
ballInPlay = true;
rb.isKinematic = false;
rb.AddForce(new Vector3(ballInitialVelocity, ballInitialVelocity, 0));
}
}
}
GM:
using UnityEngine; using System.Collections;
public class deathZone : MonoBehaviour {
void OnTriggerEnter(Collider col)
{
GM.instance.loseLife();
}
}
public class GM : MonoBehaviour {
public int Lives = 3;
public int bricks = 16;
public float resetDelay = 1f;
public Text livesText;
public GameObject gameOver;
public GameObject bricksPrefab;
public GameObject youWon;
public GameObject paddle;
public GameObject deathParticles;
public static GM instance = null;
private GameObject clonePaddle;
void Start()
{
if (instance == null)
instance = this;
else if (instance != this)
instance = null;
setup();
}
public void setup()
{
clonePaddle = Instantiate(paddle, new Vector3(0, -9,0), Quaternion.identity) as GameObject;
Instantiate(bricksPrefab, new Vector3((float)18.5, (float)-61.14095, (float)238.4855), Quaternion.identity);
}
void checkGameOver()
{
if (bricks < 1)
{
youWon.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
if (Lives < 1)
{
gameOver.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
}
void Reset()
{
Time.timeScale = 1f;
Application.LoadLevel(Application.loadedLevel);
}
public void loseLife()
{
Lives--;
livesText.text = "Lives: " + Lives;
Instantiate(deathParticles, clonePaddle.transform.position, Quaternion.identity);
Destroy(clonePaddle);
Invoke("SetupPaddle", resetDelay);
checkGameOver();
}
void SetupPaddle()
{
clonePaddle = Instantiate(paddle, new Vector3(0, -9, 0), Quaternion.identity) as GameObject;
}
public void destroyBrick()
{
bricks--;
checkGameOver();
}
}
Bricks:
public class Bricks : MonoBehaviour {
public GameObject brickParticle;
void OnCollisionEnter(Collision other)
{
Instantiate(brickParticle, transform.position, Quaternion.identity);
GM.instance.destroyBrick();
Destroy(gameObject);
}
}
deathZone:
public class deathZone : MonoBehaviour {
void OnTriggerEnter(Collider col)
{
GM.instance.loseLife();
}
}
In this tutorial you have to make sure all of the bricks GameObject have both the Bricks script and a BoxCollider components. Also the ball should have a Rigidbody and a SphereCollider components.
An easy way to debug Collisions or Triggers is to simply use a Debug.Log("something"); as a first command in the OnCollisionEnter/OnTriggerEnter/... methods.
It seems that the issue is with colliders. You should check them in Editor if they are placed right ( since no debug.log on collision is written). Also make sure that you are using Colliders and not colliders2D ( collision is called by diffrent method)

Player stuck on reactivation - not changing position to spawn

I'm writing a script controlling the enter and exit of a space ship in a 2D game.
The problem I'm running into is when exiting the ship, the player is reactivated, and you regain control, but it does not move the player to the empty gameobject I have attached to the ship, in a beginners attempt to move the player to the location of the ship, without ever destroying the player. The player simply spawns on its last known location prior to entering the ship, and I seem to be forced into that location, I can try to move, but its like I'm anchored to that position.
using UnityEngine;
using System.Collections;
public class SpaceShipActivator : MonoBehaviour
{
//Takeoff
public bool inRange;
public SpaceShipAtmosphereController SpaceShipAtmosphereController;
public PlayerController playerControl;
public GameObject Player;
public bool onBoard;
//End Takeoff
//Landing
public Transform Spawn;
public Transform landingGear2;
public Transform landingGear;
public LayerMask whatIsGround;
float groundRadius = 0.2f;
bool getIn;
bool landingGearStable;
bool landingGearStable2;
bool shipStable;
//EndLanding
Animator anim;
void Start()
{
anim = GetComponent<Animator>();
inRange = false;
SpaceShipAtmosphereController.enabled = false;
}
void Update()
{
AnimationUpdate();
//Launch
if (inRange && Input.GetButtonDown("Interact") && !onBoard)
{
LaunchShip();
}
//End launch
CheckLandingGear();
//Land
if(onBoard && Input.GetButtonDown("Roll"))
{
LandShip();
}
//End Land
}
//*********************************Functions**************************************
void LaunchShip()
{
anim.SetBool("Get In", true);
this.gameObject.tag = "Player";
SpaceShipAtmosphereController.enabled = true;
Player.tag = "InactivePlayer";
playerControl.enabled = false;
Player.SetActive(false);
onBoard = true;
}
void LandShip()
{
anim.SetBool("Get Out", true);
this.gameObject.tag = "InactivePlayer";
Player.tag = "Player";
playerControl.enabled = true;
SpaceShipAtmosphereController.enabled = false;
onBoard = false;
Player.SetActive(true);
Player.transform.position = Spawn.transform.position;
}
void CheckLandingGear()
{
//landingGear
landingGearStable = Physics2D.OverlapCircle(landingGear.position, groundRadius, whatIsGround);
landingGearStable2 = Physics2D.OverlapCircle(landingGear2.position, groundRadius, whatIsGround);
if (landingGearStable && landingGearStable2)
{
shipStable = true;
}
//End landingGear
}
void AnimationUpdate()
{
anim.SetBool("Get In", false);
anim.SetBool("Get Out", false);
}
//For launching ship
//IF player: inRange enter/exit boolean control.
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
//Debug.Log("houi p;gberf");
inRange = true;
}
}
void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
inRange = false;
}
}
//End IF player: inRange enter/exit boolean control.
}
On a side note, In that same script I've included landingGear, which is set to be two empty gameobjects that basically share Y and are spaced apart on X to check that the spaceship is not only grounded but level for the most part, so the animation doesn't look silly AND to check if the player can even get out. I know this isn't the question, but any input on it would be appreciated, but please don't feel obligated.
Thanks for the help

Trouble reveling objects using layer based colliderspheres C# Unity

I'm having some trouble getting a mechanic to function correctly in my game. Basically I have two zones: Collidersight and Colliderfatal, defined by collider spheres that are attached to a artillery shell that is fired by a cannon. Essentially, I want any objects that are within the Collidersight zone to be revealed as long as they are within that particular zone, if they are outside that zone they should return to being invisible. If an object collides with Colliderfatal, then that object should be revealed perminantly, even after the shell has been destroyed. I have tried to initialize the gameObjects individually but this appears to be extremely confusing and not applicable to the situation. The gameobjects already exist within the scene and I am not instantiating them in. I have been told, that I may need to create a list of the gameobjects to loop inside the collidersphere as a potentional solution for this problem but I am totally lost on how this might be achieved.
here is the code.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class zone : MonoBehaviour {
public LayerMask m_SightLayers;
public LayerMask s_FatalityLayers;
public Vector3 m_Position;
public float m_Radius;
public float m_Force;
public float s_Radius;
public Vector3 s_Position;
public Invisible1 revealenemy1;
public Invisible1 enemykill1;
public float s_Force;
public InvisibleKill makeDead;
public GameObject EnemyCube1;
//public GameObject enemydead;
bool hasExploded;
public bool inZone;
public bool inKillzone;
//public float removeTime = 5.0f;
bool hasBeenhit;
void Awake(){
GameObject[] objects = GameObject.FindGameObjectsWithTag("Enemy");
}
void start (){
makeDead = (InvisibleKill) EnemyCube1.GetComponent (typeof(InvisibleKill));
revealenemy1 = (Invisible1) EnemyCube1.GetComponent(typeof(Invisible1));
}
void OnCollisionEnter(Collision explode){
if(explode.gameObject.name == "Terrain" || explode.gameObject.name == "EnemyCube" || explode.gameObject.name == "EnemyCube1" ){
hasExploded = true;
}
}
void FixedUpdate ()
{
if (hasExploded == true){
Collider[] collidersight;
Collider[] colliderfatal;
Rigidbody rigidbody;
collidersight = Physics.OverlapSphere (transform.position + m_Position, m_Radius, m_SightLayers);
foreach (Collider collider in collidersight)
{
if(collider.tag == "Enemy"){
Debug.Log("stuff");
}
rigidbody = (Rigidbody) collider.gameObject.GetComponent (typeof (Rigidbody));
if (rigidbody == null)
{
continue;
}
if(rigidbody.gameObject.tag == "Enemy"){
inZone = true;
if(inZone == true){
revealenemy1.Reveal1();
// revealenemy2.Reveal2();
//revealenemy3.Reveal3();
Debug.Log ("hit");
hasBeenhit = true;
if(hasBeenhit == false){
hasBeenhit = false;
// revealenemy1.Hidden();
//// revealenemy2.Hidden2();
// revealenemy3.Hidden3();
}
}else{
}
}
}
//Debug.Log (hasExploded);
colliderfatal = Physics.OverlapSphere (transform.position + s_Position,s_Radius,s_FatalityLayers);
foreach (Collider collider in colliderfatal)
{
inKillzone = true;
rigidbody = (Rigidbody) collider.gameObject.GetComponent (typeof (Rigidbody));
if (rigidbody ==null)
{
continue;
}
rigidbody.AddExplosionForce (s_Force * -1, transform.position + s_Position,s_Radius);
Debug.Log("hasbeenkilled");
}
}
if(hasBeenhit == false){
revealenemy1.Hidden();
//revealenemy2.Hidden2();
//revealenemy3.Hidden3 ();
hasBeenhit = false;
}
if(inKillzone == true){
//EnemyCube1.GetComponentInChildren (typeof(Invisible1));
hasBeenhit = true;
//revealenemy.renderer.enabled = true;
// makeDead.isdead = true;
//(typeof(Invisible1));
}
if(makeDead.isdead == true){
revealenemy1.Reveal1();
}
}
void OnDrawGizmosSelected () {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position + m_Position, m_Radius);
//Gizmos.DrawWireSphere (transform.position + s_Position, s_Radius);
}
void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere (transform.position + s_Position, s_Radius);
}
}
Why not simply activate/deactivate the object renderers when they enter the zones? You stipulate that objects that have entered the 'Fatal' zone are permanently visible, I took this to mean they are visible even if they leave that zone.
Visibility class to be placed on any object whose visibility you want to change:
public class Visibility : MonoBehaviour {
public bool LockVisibility = false;
public void SetVisible(bool state){
if(LockVisibility)return;
renderer.enabled = state;
}
}
And the collision detection class.
public class CollisionRender : MonoBehaviour {
//example collision types
public enum CollisionTypes { Fatal,InSight };
public CollisionTypes CollisionType = CollisionTypes.InSight;
//turn renderer on.
void OnTriggerEnter(Collider other) {
Visibility vis = other.gameObject.GetComponent<Visibility>();
if(CollisionType == CollisionTypes.InSight){
vis.SetVisible(true);
}else if(CollisionType == CollisionTypes.Fatal){
//if in 'fatal' zone, make visible and lock visibility.
vis.SetVisible(true);
vis.LockVisibility = true;
}
}
void OnTriggerExit(Collider other) {
Visibility vis = other.gameObject.GetComponent<Visibility>();
vis.SetVisible(false);
}
}
I'm using triggers so your collider will need to have 'IsTrigger' checked to work.

Categories