CollisionOnEnter how to detect if an object is colliding? - c#

im pretty new to C# and Unity and i try to make an Angry Birds clone, and im stuck on this problem.
I want to change the mass of the mass of the Gameobject(in my case the woodblock) when the bird is flying and hits the object, it should change from Mass: 1 to Mass: 0.2
here is a screenshot of the scene
I created two Methods and it works in a weird way but every time i start the game the Mass gets not to 1 rather in 0.2. It should only change when the bird collides with the woodblock.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wall : MonoBehaviour
private float wallMass;
private bool isHit;
private Rigidbody2D rb;
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
wallMass = 1.0f;
isHit = false;
}
void Update()
{
CollisionOn(isHit);
}
private void CollisionOn(bool isTrue)
{
rb.GetComponent<Rigidbody2D>().mass = wallMass;
if (isTrue)
{
DecreaseMass();
}
}
void DecreaseMass()
{
rb.GetComponent<Rigidbody2D>().mass = 0.2f;
}

Use these 2 events on a MonoBehaviour, that's attached to the box.
Called when collision occurs
void OnCollisionEnter2D(Collision2D col)
{
GetComponent<Rigidbody2D>().mass = wallMass;
}
Same way when Collision ends.
void OnCollisionExit2D(Collision2D other)
{
GetComponent<Rigidbody2D>().mass = 0.2f;
}

Related

collision between player and a limiter is not 100% functional

In the game I'm developing, the player moves left and right avoiding obstacles that fall from above, but when the player reaches the left or right limit, a collision bug may occur and he simply leaves the screen. I'm using the rigidbody.velocity and the trigger to check for collision but even so, there are times when it manages to cross the wall. Here the script.(And I'm not using FixedUpdate because it's not responding well when I tap the screen.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
public bool isRight;
public float speed;
public Transform pointR;
public Transform pointL;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if(isRight)
{
rb.velocity = new Vector2(speed, 0);
}
else
{
rb.velocity = new Vector2(-speed, 0);
}
if(Input.GetMouseButtonDown(0))
{
isRight = !isRight;
}
}
void OnTriggerEnter2D(Collider2D collider)
{
if(collider.CompareTag("ColisorEs"))
{
isRight = !isRight;
}
if(collider.CompareTag("colisorR"))
{
isRight = !isRight;
}
}
}
Rigidbody changes should be handled in the FixedUpdate methode. It's better for Unitys Physics.
You can leave your Input.GetMouseButtonDown in Update.

Getting error when player collides with and object. Unity [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 2 years ago.
I'm in search of problem solution for a game I'm making.
There is a player that needs to evade obstacles and I want to make my Score to stop when player collides with obstacle and also further I want to make a highscore count.
But for now I'm getting an error when the player collides with an obstacle.
the code for the player is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Player : MonoBehaviour
{
public GameObject deathcanvas;
public float moveSpeed = 600f;
public Text scoreText;
float movement = 0f;
private bool isDead = false;
// Update is called once per frame
void Update()
{
movement = Input.GetAxisRaw("Horizontal");
}
private void FixedUpdate()
{
if (isDead)
return;
transform.RotateAround(Vector3.zero, Vector3.forward, movement * Time.fixedDeltaTime * -moveSpeed);
}
private void OnTriggerEnter2D(Collider2D collision)
{
Death();
}
private void Death()
{
isDead = true;
GetComponent<Score> ().OnDeath();
deathcanvas.SetActive(true);
}
}
also there is a code for score counter that is
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public int Player_Score;
public Text txt;
private float clock;
private bool isDead = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (isDead)
return;
txt.text = "Score: " + Player_Score;
clock += 1 * Time.deltaTime;
if (clock > 1)
{
Player_Score += 1;
clock = 0;
}
}
public void OnDeath()
{
isDead = true;
}
}
and there is also a code for obstacle spawner, but i don't think that it is needed.
And the error for when the player collides with an obstacle is
NullReferenceException: Object reference not set to an instance of an object
Player.Death () (at Assets/scripts/Player.cs:36)
Player.OnTriggerEnter2D (UnityEngine.Collider2D collision) (at Assets/scripts/Player.cs:31)
What should i do?
There are some strange things here, why do you have 2 functions of death and 2 book of death? It's useful, since Score is on player like the other script you can put everything inside the Player script and access to the canvas and score text without using public functions and a lot of variables. If it's still an error then we can see something else

Unity Sword Collision Attack

Hey guys I want to make a sword attack. But I get the error of:
NullReferenceException: Object reference not set to an instance of an
object
These are my codes:
My weaponattack script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weaponattack : MonoBehaviour
{
Enemy Enemy;
public float power;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void OnTriggerEnter(Collider col)
{
if(col.tag == "Enemy")
{
var kılıc = GetComponent<Enemy>();
Enemy.currentHealt -= 10;
Enemy.TakeDamage();
Debug.Log("Düşman Vuruldu");
}
}
}
This is my Enemy Health scrpt:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
public float currentHealt;
public float maxHealth;
// Use this for initialization
void Start () {
currentHealt = maxHealth;
}
// Update is called once per frame
void Update () {
}
public void TakeDamage()
{
currentHealt -= 10;
if(currentHealt < 0)
{
die();
}
}
void die()
{
Destroy(gameObject);
}
}
Can you helo em I couldnt understan why these codes are not working why am I getting that error.
I think your problem is in this line here GetComponent<Enemy>(); This needs a game object to get the component of
Enemy = col.GetComponent<Enemy>();
Should be what you're doing
You also may have issue calling your variable Enemy exactly the same as your class Enemy, I would change this to Enemy enemy; and
enemy = col.GetComponent<Enemy>();
respectivley
It seems pretty straightforward. You don't assign an Enemy to Weaponattack and so it's barfing when you first reference Enemy (Enemy.currentHealt). Either make Enemy public or a SerializedField so you can assign it in the Inspector, or however else you want to get an Enemy into Weaponattack.
Also don't name your property the same name as your script (Enemy Enemy). Surprised you didn't get a compile error.
EDIT Based on comments:
Enemy enemy;
public void OnTriggerEnter(Collider col)
{
if(col.tag == "Enemy")
{
var kılıc = GetComponent<Enemy>();
kilic.currentHealt -= 10;
kilic.TakeDamage();
Debug.Log("Düşman Vuruldu");
}
}
This also assumes you have an Enemy attached to your Weaponattack (GetComponent)

Unity problem activating a function with parameters in camera from another script in GameObject Enemy

I have a script that makes the camera do a shake by putting a button because
It is a public access function, if I do it that way when placing a button it works well but what I cannot achieve is to call the function so that every time my player collides with an enemy he makes the shake. I hope you can help me.
The shake code in camera is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScreenShaker : MonoBehaviour {
private float shakeAmount = 0.5f;
private float shakeTime = 0.0f;
private Vector3 initialPosition;
private bool isScreenShaking = false;
void Update () {
if(shakeTime > 0)
{
this.transform.position = Random.insideUnitSphere * shakeAmount + initialPosition;
shakeTime -= Time.deltaTime;
}
else if(isScreenShaking)
{
isScreenShaking = false;
shakeTime = 0.0f;
this.transform.position = initialPosition;
}
}
public void ScreenShakeForTime(float time)
{
initialPosition = this.transform.position;
shakeTime = time;
isScreenShaking = true;
}
}
The enemy code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ControladorEnemigoCirculoMediano : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
Here I don't know what to call the public void function ScreenShakeForTime (float time);
I already tried many things online but when my character comes into contact with the character, I don't do the shake in the camera.
}
}
}
You can create Unity-singleton in your ScreenShaker class like:
class ScreenShaker
{
public static ScreenShaker Instance {private set; get;};
void Awake() {
Instance = this;
}
}
And than from any place to call like:
ScreenShaker.Instance.ScreenShakeForTime(2f);
This is the easiest way, but maybe it's better to create standard singeleton(it's up to you).
And also don;t forget to destroy it on OnDestroy()
can you tell me in enemy game object collider isTrigger is enable or not
if it is not enable then use OnColliderEnter2D(Collision2D other){} for collision detection

Getting a NullReferenceException when accessing a component that I've created and retrieved

First of all, how original of me to post another dreaded
NullReferenceException: Object reference not set to an instance of an object
but I have scoured the web looking for a solution for like 2 hours now and have come up with nothing... Here is are the two scripts i have :
GROUNDED:
using UnityEngine;
using System.Collections;
public class GroundCheck : MonoBehaviour {
private Player player;
void Start()
{
player = GetComponent<Player>();
}
void OnTriggerEnter2D(Collider2D col)
{
player.grounded = true;
}
void OnTriggerExit2D(Collider2D col)
{
player.grounded = false;
}
}
PLAYER:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float maxSpeed = 3;
public float speed = 50f;
public float jumpPower = 150f;
public bool grounded;
private Rigidbody2D rb2d;
private Animator anim;
// Use this for initialization
void Start () {
rb2d = gameObject.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
anim.SetBool("Grounded", grounded);
anim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
rb2d.AddForce((Vector2.right * speed) * h);
if (rb2d.velocity.x > maxSpeed)
{
rb2d.velocity = new Vector2(maxSpeed, rb2d.velocity.y);
}
if (rb2d.velocity.x < -maxSpeed)
{
rb2d.velocity = new Vector2(-maxSpeed, rb2d.velocity.y);
}
}
}
The exact error is:
NullReferenceException: Object reference not set to an instance of an object
GroundCheck.OnTriggerEnter2D (UnityEngine.Collider2D col)
(atAssets/scripts/GroundCheck.cs:15)
Here is my scene:
Here is my boxcollider (if it helps):
If both of the GroundCheck and PLAYER classes are on same GameObject then change the Start() method of GroundCheck class like this:
void Start()
{
player = gameObject.GetComponent<Player>();
}
If they are not on same GameObject then use the following code:
void Start()
{
GameObject playerObj = GameObject.Find("Name of gameObject that player script is in that");
player = playerObj.GetComponent<Player>();
}
In PLAYER class add static modifier to defination of grounded:
public static bool grounded;
Your ground check script isn't on the same object as the player script, that means you can't use getcomponent to get the player script. So you haven't set the player var to anything which is causing the error. Set the player var to the gameobject that has the player script in the editor then in your start method use player.GetComponent();
void OnTriggerEnter2D(Collider2D col) <-- in collider param request gameObject, getcomponent to col is prefered, only control if object collision is player. col.gameObject.getcomponent<Player>().grounded=true;
if(col.Name.Equals("Player")
{
col.gameObject.getcomponent<Player>().grounded=true;
}
I had a similar problem. I hope it's helps
http://docs.unity3d.com/ScriptReference/Collision2D.html
Collider2d have gameobject component, trigger enter get Collider this object.
in http://docs.unity3d.com/ScriptReference/Collider2D.OnCollisionEnter2D.html
see example use in collider (not trigger is only example) to use, acces gameObject.
Not necessary findtag when object(player) is passing for parameter in event OnTriggerEnter, Exit or Stay

Categories

Resources