Unity nothing happens when a object collides - c#

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");
}
}

Related

Problems with OnCollisionEnter2D & OnCollisionExit2D

I'm trying to make the Player not jump continuously so I use isOnGrounded variable to check if the player is on the ground or not. Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
//REFERENCES
private Rigidbody2D rb2D;
//VARIABLES
[SerializeField] float moveSpeed = 0;
private float moveX;
[SerializeField] bool isOnGrounded = true;
[SerializeField] float jumpY;
// Start is called before the first frame update
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
moveX = Input.GetAxis("Horizontal");
PlayerJump();
}
private void FixedUpdate()
{
PlayerMove();
}
void PlayerMove()
{
rb2D.velocity = new Vector2(moveX * moveSpeed * Time.fixedDeltaTime, rb2D.velocity.y);
}
void PlayerJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isOnGrounded == true)
{
rb2D.AddForce(new Vector2(rb2D.velocity.x, jumpY));
}
}
private void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.CompareTag("Ground"))
{
isOnGrounded = true;
}
}
private void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.CompareTag("Ground"))
{
isOnGrounded = false;
}
}
}
The problem is when the Player is standing on Platform01 so obviously isOnGrounded = true and when the Player moves out of Platform01 isOnGrounded = false, I suppose when move in Platform02 it will automatically check the Ground and isOnGrounded = true but it still false and everything just messing up.
This is because OnCollisionEnter2D(Platform02) is triggered before OnCollisionExit2D(Platform01).
You can remember the last hit collider and compare with it when leave a platform.
public class PlayerController : MonoBehaviour
{
private Collision2D ground;
public bool IsGround => (bool)ground;
private void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.CompareTag("Ground"))
{
ground = other;
}
}
private void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.CompareTag("Ground") && other == ground)
{
ground = null;
}
}
}

How to make each script separate to each initiation?

So I am currently Trying to create a zombies game, where I have a script written that would enable a hitting animation if it was "close" to the player.
The code for this script is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ZombieNavMesh : MonoBehaviour
{
private Transform movePositionTransform;
private NavMeshAgent navMeshAgent;
private Animator animator;
static bool close;
private void Start()
{
movePositionTransform = GameObject.Find("Player").transform;
animator = GetComponent<Animator>();
}
private void Awake()
{
navMeshAgent = GetComponent<NavMeshAgent>();
}
private void Update()
{
if (!close)
{
navMeshAgent.destination = movePositionTransform.position;
animator.SetBool("Close", false);
}
if (close)
{
animator.SetBool("Close", true);
}
}
public void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
Debug.Log("Should hit");
close = true;
}
}
public void OnTriggerExit(Collider other)
{
if(other.tag == "Player")
{
Debug.Log("Should not hit");
close = false;
}
}
}
The problem in here is that, if one zombie Enters Trigger, and another zombie Exit Trigger, the bool value close would be set to false, so both would perform walking animation; it should be the "close" zombie hitting animation, and the far zombie walking animation.
Remove the word static from static bool close;
static means there is only one of that thing shared by all versions and instances of the class.

Input not registering in OnCollisonEnter2D,OnCollisionExit2D and OnCollisionStay2D

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();
}
}

I'm trying to make as so, on trigger, the player stops moving

I'm developing a TopDown 2D game in Unity.
The idea is, when the player steps on a certain tile, a UI with text pops up (already working) and the player stops moving until the player clicks a button (already programmed and working) and the UI disappears.
I was advised to turn the RigidBody2D to kinematic however it doesn't work and it just does what it used to do.
Am I doing something wrong?
Here is the code for the trigger script on the tiles:
public class TriggerScript : MonoBehaviour
{
public string popUp;
public void Start()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
Rigidbody2D Player = GameObject.Find("Player").GetComponent<Rigidbody2D>();
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
if (collision.gameObject.tag == "Player")
{
pop.PopUp(popUp);
Player.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Kinematic;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
Rigidbody2D Player = GameObject.Find("Player").GetComponent<Rigidbody2D>();
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
pop.closeBox();
Player.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Dynamic;
}
}
PopUpSystem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PopUpSystem : MonoBehaviour
{
public GameObject popUpBox;
public Animator popupanimation;
public TMP_Text popUpText;
public PLayerController mb;
public void PopUp(string text)
{
popUpBox.SetActive(true);
popUpText.text = text;
popupanimation.SetTrigger("pop");
}
public void closeBox()
{
popupanimation.SetTrigger("close");
mb.camMove = true;
}
}
PLayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PLayerController : MonoBehaviour
{
private Rigidbody2D MyRB;
private Animator myAnim;
[SerializeField]
private float speed;
public bool camMove = true;
// Start is called before the first frame update
void Start()
{
MyRB = GetComponent<Rigidbody2D>();
myAnim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (camMove)
{
MyRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")) * speed * Time.deltaTime;
myAnim.SetFloat("moveX", MyRB.velocity.x);
myAnim.SetFloat("moveY", MyRB.velocity.y);
if ((Input.GetAxisRaw("Horizontal") == 1) || (Input.GetAxisRaw("Horizontal") == -1) || (Input.GetAxisRaw("Vertical") == 1) || (Input.GetAxisRaw("Vertical") == -1))
{
myAnim.SetFloat("LastMoveX", Input.GetAxisRaw("Horizontal"));
myAnim.SetFloat("LastMoveY", Input.GetAxisRaw("Vertical"));
}
}
if (!camMove)
{
MyRB.velocity = new Vector2(0, 0);
}
}
}
TriggerScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriggerScript : MonoBehaviour
{
public string popUp;
Animator popAnim;
public PLayerController mb;
private void Start()
{
popAnim = GameObject.FindGameObjectWithTag("PopUpBox").GetComponent<Animator>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
var myp = GameObject.FindGameObjectWithTag("Player").GetComponent<PLayerController>();
if (collision.gameObject.tag == "Player")
{
pop.PopUp(popUp);
mb.camMove = false;
}
if (popAnim.GetCurrentAnimatorStateInfo(1).IsName("close"))
{
mb.camMove = true;
Debug.Log("close");
}
}
private void OnTriggerExit2D(Collider2D collision)
{
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
pop.closeBox();
}
}
Things to keep in mind:
1- Make a new tag and call it PopUpBox. then assign this tag to the Trigger GameObject.
2- To the button of the PopUpBox GameObject (the one which is disabled) assign GameManager GameObject and in its function select PopUpSystem.closeBox
3- In both Trigger GameObject and GameManager assign Player in Mb field.
Hope this help you. You can play with that more to get better results.

Activate script in collided gameObject

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();
}
}

Categories

Resources