I made a simple "radiation" field through a trigger but it works only when player in move. Function countes two decimal values.
What could be the problem?
decimal radIntensity = 0.001m;
decimal currentDose;
private void OnTriggerStay2D(Collider2D area)
{
if (area.gameObject.tag == "Player")
{
currentDose += radIntensity;
}
print($"Current dose: {currentDose} R");
}
In the RigidBody2D component there's an option to disable or enable the sleeping mode.
Try to disable it with the RigidbodySleepMode2D.NeverSleep option.
Also can use a boolean-flag and OnTriggerEnter2D and OnTriggerExit2D. But never sleeping rigidbody is much better
bool _flag;
private void Update()
{
if (_flag)
{
currentDose += radIntensity;
}
print($"Current dose {currentDose} R");
}
private void OnTriggerEnter2D(Collider2D area)
{
if (area.gameObject.tag == "Player")
{
_flag = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
_flag = !true;
}
Related
I am trying to get input when my player collides with another object. But the problem is i am not getting any input. I am getting inputs in update function but not in OnCollisonEnter2D,OnCollisionExit2D and OnCollisionStay2D.
Here is my script
public class PlayerInteractions : MonoBehaviour {
[SerializeField] private GameObject chestHelperMessage;
private void OnCollisionEnter2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Chest")) {
chestHelperMessage.SetActive(true);
if (Input.GetKeyDown(KeyCode.E)) {
Debug.Log("You got a weapon");
}
}
}
private void OnCollisionExit2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Chest")) {
chestHelperMessage.SetActive(false);
}
}
private void OnCollisionStay2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Chest")) {
if (Input.GetKeyDown(KeyCode.E)) {
Debug.Log("Chest opened");
}
}
}
}
none of the function is giving inputs.
Please help.
Thanks
for OnCollisonEnter2D and OnCollisionExit it is pretty unlikely that you press the key down exactly in the very same frame where the collision event happens.
Also for OnCollisionStay2D the call happens together with FixedUpdate, the physics routine. They are not happening every frame so it can happen that also here you miss the one or other input.
In general you should get user input in Update and do e.g.
// In case you need the chest reference itself
private GameObject currentChest;
IEnumerator CheckInputRoutine()
{
if (chestHelperMessage.activeSelf && Input.GetKeyDown(KeyCode.E))
// Or also
//if(currentChest && Input.GetKeyDown(KeyCode.E))
{
Debug.Log("You got a weapon");
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Chest"))
{
chestHelperMessage.SetActive(true);
currentChest = collision.gameObject;
StartCorouine (CheckInputRoutine());
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Chest"))
{
chestHelperMessage.SetActive(false);
currentChest = null;
StopAllCoroutines ();
}
}
This is a piece of code from my game that works for me:
void OnTriggerEnter(Collider other) // you can check if the collider is a player but I did not in this instance
{
HelperMessage.SetActive(true);
canOpenChest = true;
}
void Update()
{
if (canOpenChest && Input.GetKeyDown(KeyCode.E))
{
HelperMessage.SetActive(false); // set active to false because the chest is now open
Destroy(gameObject); // instead of this play an animation or whatever and, you can also remove the collider from the chest
}
}
void OnTriggerExit(Collider other)
{
Text.SetActive(false);
canPickup = false;
}`
The answer by derHugo is technically right but I don't like IEnumerators so I never use them
Thanks #RoberStan, the code given by you is not working for my game, but some changes made it work.
Here is the new code
// text on the screen to help the player which key to press to pick up the item
[SerializeField] private GameObject chestHelperMessage;
private GameObject currentChest;
private void CheckInput() {
// checking that if the helperMessage is active and getting key inputs
if (chestHelperMessage.activeSelf && Input.GetKeyDown(KeyCode.E)) {
Debug.Log("You got a weapon");
}
}
private void OnCollisionEnter2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Chest")) {
chestHelperMessage.SetActive(true);
currentChest = collision.gameObject;
}
}
private void OnCollisionExit2D(Collision2D collision) {
if (collision.gameObject.CompareTag("Chest")) {
chestHelperMessage.SetActive(false);
currentChest = null;
}
}
private void Update() {
CheckKeyPress();
}
private void CheckKeyPress() {
if (chestHelperMessage.activeSelf) {
CheckInput();
}
}
So I am trying to find a way to make a player move infinitely just by clicking the right arrow key ones and if it touches another game object it stops at the game objects postion and if button clicked again it moves again.
Note: I just started using unity also just started programming in c# so please try to explain things in an easy and understanding way.
Heres the code:
Rigidbody2D rb2d;
public float speed = 10;
public const string RIGHT = "right";
public const string LEFT = "left";
string buttonPressed;
public GameObject Rainbow_1;
public GameObject Rainbow_0;
bool isCol = false;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow)) { buttonPressed = RIGHT; }
else if (Input.GetKey(KeyCode.LeftArrow)) { buttonPressed = LEFT; }
else { buttonPressed = null; }
}
private void FixedUpdate()
{
if(buttonPressed == RIGHT)
{
if(isCol)
{
StartCoroutine(sfos());
}
else if(!isCol)
{
rb2d.velocity = new Vector2(speed, 0);
}
}
}
IEnumerator sfos()
{
Rainbow_0.transform.position = Rainbow_1.transform.position;
yield return new WaitForSeconds(3);
}
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("Collision detected");
isCol = isCol;
}
private void OnCollisionExit2D(Collision2D other) { isCol = !isCol; }
What you want to do is stop your player:
rb2d.velocity = new Vector2(0, 0);
You also need to signal a collision:
isCol = true;
Collision
You're not setting your isCol variable to true at any point outside of initialization. This means that your first collision will register, but all subsequent collisions will not; to fix this, change:
private void OnTriggerEnter2D(Collider2D other) {
Debug.Log("Collision detected");
isCol = isCol;
}
private void OnCollisionExit2D(Collision2D other) { isCol = !isCol; }
To:
private void OnTriggerEnter2D(Collider2D other) {
Debug.Log("Collision detected");
isCol = true;
}
private void OnCollisionExit2D(Collision2D other) { isCol = false; }
It's easier to see when it's explicit like this.
Velocity
For velocity, your FixedUpdate method is conditionally setting the velocity to speed, 0, but you never set it to anything else:
private void FixedUpdate() {
if(buttonPressed == RIGHT) {
if(isCol) {
StartCoroutine(sfos());
}
else if(!isCol) {
rb2d.velocity = new Vector2(speed, 0);
}
}
}
You need to set your velocity to zero if you're not supposed to be moving; so if isCol is true:
private void FixedUpdate() {
if(buttonPressed == RIGHT) {
if(isCol) {
rb2d.velocity = new Vector2(0, 0);
StartCoroutine(sfos());
}
else if(!isCol) {
rb2d.velocity = new Vector2(speed, 0);
}
}
}
Additionally, for simplicity's sake, I believe Unity's 2D vector contains a property/field named zero, so the following may also work, but without direct access to Unity at the moment I won't promise anything. 🙃
rb2d.velocity = Vector2.zero
I want to log in console when a cube passes through an another cube, the another cube has mesh collider with Convex and isTrigger is set to true.
using UnityEngine;
public class score_addations : MonoBehaviour
{
//[SerializeField]
//private int SCORE = 0;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "score")
{
Debug.Log("Pass");
}
else
{
Debug.Log("Fail");
}
}
private void Start()
{
//Cursor.lockState = CursorLockMode.Locked;
//Cursor.visible = false;
}
}
Here is an image of my game
for triggers you use OnTriggerEnter(Collider) Use this code
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.tag == "score")
{
Debug.Log("Pass");
}
else
{
Debug.Log("Fail");
}
}
I am trying to have my player walk onto a GameObject and if they are on that object and they press the space key show a debug log.
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Level_1" && Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Both Conditions Reached");
}
}
This would only trigger if they were holding down the space bar as they entered the object. You would do better to check if they were currently colliding with the object when the spacebar is pressed. (or do the check for both in Update)
Call this in your player object:
private void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.tag == "Level_1") {
player.isInside = true;
}
}
private void OnTriggerExit2D(Collider2D other) {
if (other.gameObject.tag == "Level_1") {
player.isInside = false;
}
}
And use this to check for the spacebar:
public void Update() {
if (Input.GetKeyDown(KeyCode.Space) && player.isInside == true) {
Debug.Log("Both Conditions Reached");
}
}
How can I activate part of the code in other script?
Attention: I don't need to activate all scripts. For example, a bunch of bullets flies around a player. And when one collide with a player, then need to activate part of the script of the collided object (that touched the player).
PlayerControl.cs
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Bullet1")
{
lasthit = 1f;
// I need to activate Destroyy() in Bullet1 script
}
}
Bullet1.cs
public void Destroyy()
{
Debug.Log("Destroyed!"); // I need to activate this part of the code
} // ONLY in Bullet1.cs
The code below shows how to do it:
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Bullet1")
{
lasthit = 1f;
// I need to activate Destroyy() in Bullet1 script
// HERE'S HOW:
if(col.gameObject.GetComponent<Bullet1>() != null)
col.gameObject.GetComponent<Bullet1>().Destroyy();
}
}
Just getComponent is be easier
void OnCollisionEnter2D(Collision2D col)
{
Bullet1 b = col.gameObject.GetComponent<Bullet1>();
if (b == null)
{
return;
}
lasthit = 1f;
b.Destroyy();
}
Actiovating bool in Bullet1 script
Player.cs
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Bullet1")
{
col.gameObject.GetComponent<Bullet1pt().booldestroy = true;
}
}
Bullet1.cs
public bool booldestroy;
private void Update()
{
if (booldestroy)
{
Destroyy();
}
}