OnCollisionEnter breaks when an else statement is added - c#

In an attempt to create the basics of a game i'm creating in unity i have encountered a strange problem,
This code works just fine (materialstate is set to 0 in start()) and the object itself indeed changes material
void OnCollisionEnter(Collision col){
if (col.gameObject.name == "Player" && Materialstate == 0) {
renderComp.material = goal;
Materialstate = 1;
}
}
However as soon as i add an else statement it just breaks, the collision occurs( I know because i've checked it with a print statement for Materialstate in update()) But this time not even the initial collision(That was working fine before the else was added) works:
void OnCollisionEnter(Collision col){
if (col.gameObject.name == "Player" && Materialstate == 0) {
renderComp.material = goal;
Materialstate = 1;
} else {
if (col.gameObject.name == "Player") {
renderComp.material = starting;
Materialstate = 0;
}
}
}

Can you try this code out?
void OnCollisionEnter(Collision col) {
if (col.gameObject.name == "Player") {
if (Materialstate == 0) {
renderComp.material = goal;
Materialstate = 1;
return;
}
renderComp.material = starting;
Materialstate = 0;
}
}
This removes the else which basically checks for whether col.GameObject.name == "Player" twice. This might actually speed up your game code as well as that extra check is removed. It also performs the needed operations properly within the original condition (col.GameObject.name == "Player" is true).
It is written with the assumption that Materialstate will only be 0 or 1, however, if you plan on having more states, a switch statement might be your best bet in making this work as intended.
void OnCollisionEnter(Collision col) {
if (col.gameObject.name == "Player") {
switch (Materialstate)
{
case 0:
renderComp.material = goal;
Materialstate = 1;
break;
case 1:
renderComp.material = starting;
Materialstate = 0;
break;
default:
// Invalid Materialstate throw exception/error
}
}
}
I hope this helps!

Related

Syntax for OnTriggerEnter validation

Why won't these if statements work? When the object with this script attached collides with the object named "Resistor" for example why won't it work?
Code:
private void OnTriggerEnter(Collider collider)
{
Debug.Log("AAAAAAAA");
if (collider.gameObject.name == "Resistor")
{
resistance = SliderScript.slider.value;
}
else if (collider.gameObject.name == "LDR")
{
LDRresistance = LDRSliderScript.sliderForLight.value;
}
else if (collider.gameObject.name == "Lightbulb")
{
Debug.Log("lol");
GameObject lightGameObject = new GameObject("Light spawned because of collision with a battery");
Light lightComp = lightGameObject.AddComponent<Light>();
lightComp.intensity = current;
lightComp.color = Color.white;
lightGameObject.transform.position = Lightbulb.transform.position;
Destroy(lightGameObject, 15);
}
else if (collider.gameObject.name == "Battery")
{
Debug.Log("Batteryname works");
Destroy(gameObject);
}
}
Thank you!
Just in case anyone else ever encounters this problem in the future:
The correct syntax is:
Private void OnTriggerEnter(Collider other)
{
If (other.gameObject.name == “whatever”)
{
Debug.Log(“anything”)
}
}

Trying to get a variable changed on Collision

I'm trying to make flappy bird and I'm trying to make it when the bird hits the "floor" a variable changes and then the script for the movement is not able to go.
Kinda hard for me to explain but here is the code i have:
void Update()
{
void OnCollisionEnter2D(Collider2D col)
{
if (col.gameObject.tag == "floor") // || col.gameObject.tag == "Pipe")
{
active = 0;
}
}
if (active == 1)
if (Input.GetKeyDown("space"))
{
GetComponent<Rigidbody2D>().velocity = new Vector3(0, 10, 0);
}
}
That is my code ^
Please help : )
void Update()
{
if (active == 1)
{
if (Input.GetKeyDown("space"))
{
GetComponent<Rigidbody2D>().velocity = new Vector3(0, 10, 0);
}
}
}
void OnCollisionEnter2D(Collider2D col)
{
if (col.gameObject.tag == "floor") // || col.gameObject.tag == "Pipe")
{
active = 0;
}
}
This code works fine for me, make sure you add Rigidbody2d to the player + add the box collider and the tag to the floor
First of all you have the OnCollisionEnter2D nested under Update as a local function. Unity doesn't find and call it this way, it needs to be at class level.
And then you set
active = 0;
but check for
active == 1
this seems odd. I would expect you check for the same value.
In general rather use a bool flag:
private bool active;
// reference via the Inspector if possible
[SerializeField] private Rigidbody2D _rigidbody;
private void Awake()
{
// as fallback get it ONCE on runtime
if(!_rigidbody) _rigidbody = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (active)
{
if (Input.GetKeyDown("space"))
{
// only change the Y velocity, keep the rest
// that's needed e.g. if you are moving sideways currently
_rigidbody.velocity = new Vector3(_rigidbody.velocity.x, 10);
// immediately disable jumping
active = false;
}
}
}
private void OnCollisionEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("floor") || col.gameObject.CompareTag("Pipe"))
{
active = true;
}
}
// also disable jumping when exiting just in case
void OnCollisionExit2D(Collider2D col)
{
if (col.gameObject.CompareTag("floor") || col.gameObject.CompareTag("Pipe"))
{
active = false;
}
}

Unity Gun Ammo not Decreasing Problem in Multiplayer (Maybe Related To my Multiplayer System: Photon)

I have a problem in which my ammo won't decrease when I shoot until I wait for a certain Amount of time. I'm currently using Photon as my Network System for my game and my gun code from Brackeys (https://www.youtube.com/watch?v=kAx5g9V5bcM&lc=UghlAulu5dH90HgCoAEC). This is maybe related to internet problems and delays but I'll show you the code I use:
void Update()
{
if(!photonView.IsMine) return;
if (!canShowAmmo)
{
ammoText.text = "Ammo: " + currentAmmo;
}
if (isStarted && (owner.openPanel || MultiplayerManager.main.roomManager.gameDone))
{
if (isScoped)
{
Scope();
}
return;
}
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(autoOrSemi == true){
if(Input.GetButton("Fire1") && Time.time >= nextTime){
nextTime = Time.time + 1f/fireRate;
Shoot();
}
}
if(autoOrSemi == false){
if(Input.GetButtonDown("Fire1") && Time.time >= nextTime){
nextTime = Time.time + 1f/fireRate;
Shoot();
}
}
if (Input.GetButtonDown("Fire2"))
{
Scope();
}
}
public void Shoot(){
MuzzleFlash.Play();
currentAmmo--;
AudioSource.PlayClipAtPoint(shotSound, transform.position);
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
Debug.Log(hit.transform.name);
IDamageable target = hit.collider.gameObject.GetComponent<IDamageable>();
if (target != null)
{
if (hit.collider != owner.GetComponent<Collider>())
{
target.TakeDamage(damage);
owner.score += (int) damage;
owner.ScoreUpdate();
}
}
if(hit.rigidbody != null){
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject effect = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(effect, 2f);
}
}
public IEnumerator Reload(){
isReloading = true;
Debug.Log("Reloading");
canShowAmmo = true;
ammoText.text = "Reloading...";
yield return new WaitForSeconds(reloadTime - .25f);
yield return new WaitForSeconds(.25f);
canShowAmmo = false;
currentAmmo = maxAmmo;
isReloading = false;
}
so if I was correct and it's caused by lag or I was wrong and didn't have any relation to the Network, please I need a solution. Thanks.
Sorry my bad, I may just found a solution: just add a new private bool and set it to true inside the if function derHugo presented below or above this comment and if bool is false then shooting is disabled then after reloading inside the enumerator after isReloading = false, make the bool to false
I think you issue are concurrent Coroutines!
you are doing
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
This will start a new routine every frame while the condition is met.
You rather want to do e.g.
if (!isReloading && currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(isReloading) return;

Shooting extra balls - Block breaker game bug (Unity 2D)

I'm making a block breaker game that the player can get extra balls and shoot those balls with the original one.
Does anyone knows what is wrong? If there is not enough information, just tell me and I can provide it here.
Thanks
=========== CHANGED THE CODE TO BE MORE CLEAN ===========
Created my own pool logic to get more control and created a ExtraBallManager.cs to handle only functions related to that.
Here is how it is now (also I figured out that I didn't have to use coroutine):
public class ExtraBallManager : MonoBehaviour
{
private Ball ballController;
private GameManager gameManager;
public float ballWaitTime;
private float ballWaitTimeSeconds;
public int numberOfExtraBalls;
public int numberOfBallsToFire;
public ObjectPool objectPool;
//public TextAlignment numberOfBallsText;
// Start is called before the first frame update
void Start()
{
ballController = FindObjectOfType<Ball>();
gameManager = FindObjectOfType<GameManager>();
ballWaitTimeSeconds = ballWaitTime;
numberOfExtraBalls = 0;
numberOfBallsToFire = 0;
}
void Update() {
if(ballController.currentBallState == Ball.ballState.fire || ballController.currentBallState == Ball.ballState.wait){
if(numberOfBallsToFire > 0){
ballWaitTimeSeconds -= Time.deltaTime;
if(ballWaitTimeSeconds <= 0){
GameObject tempBall = objectPool.GetPooledObject("Temp Ball");
if(tempBall != null){
tempBall.transform.position = ballController.ballLaunchPosition;
tempBall.SetActive(true);
//It seems the error occurs in here
//sometimes it just don't add this tempBall to the
//list
gameManager.ballsInScene.Add(tempBall);
tempBall.GetComponent<Rigidbody2D>().velocity = ballController.initialBallVelocity;
ballWaitTimeSeconds = ballWaitTime;
numberOfBallsToFire--;
}
ballWaitTimeSeconds = ballWaitTime;
}
}
}
if(ballController.currentBallState == Ball.ballState.endShot){
numberOfBallsToFire = numberOfExtraBalls;
}
}
}
My Ball.cs part where switch the Ball State:
void Start()
{
arrow.SetActive(false);
currentBallState = ballState.aim;
rigidBody = GetComponent<Rigidbody2D>();
ballTransform = GetComponent<Transform>();
lineRenderer = arrow.GetComponent<LineRenderer>();
gameManager = FindObjectOfType<GameManager>();
stoppedPosition = transform.position;
currentBallState = Ball.ballState.aim;
gameManager.ballsInScene.Add(this.gameObject);
}
// Update is called once per frame
void Update()
{
switch(currentBallState) {
case ballState.aim:
if (Input.GetMouseButtonDown(0) && gameObject.tag == "Ball"){
MouseClicked();
}
if(Input.GetMouseButton(0) && gameObject.tag == "Ball"){
MouseDragged();
}
if(Input.GetMouseButtonUp(0) && gameObject.tag == "Ball"){
ReleaseMouse();
}
break;
case ballState.fire:
break;
case ballState.wait:
stoppedPosition = transform.position;
/*
if(gameManager.IsThereAnyExtraBallOnScene()){
currentBallState = ballState.endShot;
}*/
if(gameManager.ballsInScene.Count == 1){
currentBallState = Ball.ballState.endShot;
}
break;
case ballState.endShot:
for(int i = 0; i < gameManager.blocksInScene.Count; i++){
if(gameManager.blocksInScene[i]){
gameManager.blocksInScene[i].GetComponent<BlockMovementController>().currentState = BlockMovementController.blockState.move;
}
}
gameManager.level += 1;
gameManager.SpawnBlocks();
currentBallState = ballState.aim;
break;
default:
break;
}
}

Unity2D my character jump more than one when i press jump key

https://pasteboard.co/IrKZbCV.png
void OnCollisionEnter2D(Collision2D col)
{
float angle = Vector3.Angle(Vector3.up, col.contacts[0].normal);
if (col.transform.gameObject.tag == "enemyWalk")
{
Physics2D.IgnoreCollision(col.gameObject.GetComponent<Collider2D>(), GetComponent<Collider2D>(), true);
}
else
{
Physics2D.IgnoreCollision(col.gameObject.GetComponent<Collider2D>(), GetComponent<Collider2D>(), false);
}
if (col.transform.gameObject.tag == "stone")
{
angle = Vector3.Angle(Vector3.up, col.contacts[0].normal);
if (Mathf.Approximately(angle, 0))
{
isGround = true;
taş = true;
}
}
else if (col.transform.gameObject.tag == "ground")
{
angle = Vector3.Angle(Vector3.up, col.contacts[0].normal);
if (Mathf.Approximately(angle, 0))
{
isGround = true;
çimen = true;
}
}
}
if ((isJump.jmp || Input.GetKeyDown(KeyCode.Space)) && !isDeath && isGround)
{
rgd.AddForce(new Vector2(0, 2.750f), ForceMode2D.Impulse);
jumpAudio.Play();
isGround = false;
}
İ want to jump my character only one times when i press jump key,but as i show this situation on picture,sometimes my character jumping too high when i jumped at near of the bottom of the rock.İ mean,as if my jump code working many times at same time.
i'm waiting for your helps.

Categories

Resources