Unity colision will not execute any logic - unity3d

A simple script doing a simple thing. Yet no matter what I cannot get it script to work.
using UnityEngine;
using System.Collections;
public class ShotScript : MonoBehaviour {
public Player pScript;
private Rigidbody2D shotRigid;
public bool enemyContact = false;
public bool enemyContactTrue = false;
void Awake() {
shotRigid = GetComponent<Rigidbody2D> ();
}
void Start() {
shotRigid = GetComponent<Rigidbody2D> ();
}
void enemyContactFunction() {
enemyContact = true;
}
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "Enemy1" ) {
Debug.Log ("shot has collided with tagged enemy");
if (enemyContact == false){
enemyContactFunction();
}
}
}
}
The debugs will go off but nothing ever happens in the game and this it taking me days to figure out. How would anyone else make something, anything happen, after a collision like this work when mine does not?

Related

Can Unity check collisions in the reference script?

As you can see in the figure, we are coding the logic of re-creating when the character falls off.
Currently, when you enter the isLeft and isRight scripts, the position becomes true and the opposite side is false.
If the collisions that fall on the floor become true, we respawn the characters where they are true.
The script that manages this isFall.
public class isFall : MonoBehaviour
{
public GameObject hood;
public bool isRight , isLeft;
public IsRight Position_Right;
public IsLeft Position_Left;
bool isDelay;
public Health hp;
private void Awake() {
isRight = isLeft = false;
isDelay = false;
}
private void Update() {
if(isDelay){
StartCoroutine(WaitForSpawn());
isDelay = false;
}
if (Position_Right.isRight)
{
isRight = true;
isLeft = false;
Position_Left.isLeft = false;
}
if (Position_Left.isLeft)
{
isLeft = true;
isRight = false;
Position_Right.isRight = false;
}
}
private void OnTriggerEnter2D(Collider2D collision) {
if (collision.gameObject.tag == "Player"){
isDelay = true;
hp.TakeDamage(1);
}
}
IEnumerator WaitForSpawn()
{
yield return new WaitForSeconds(2.0f);
if (isLeft) hood.transform.position = Position_Left.transform.position;
else hood.transform.position = Position_Right.transform.position;
}
}
//---------------------------------------------------------------------------
public class IsLeft : MonoBehaviour
{
public bool isLeft = false;
private void OnTriggerEnter2D(Collider2D collider) {
if (collider.CompareTag("Player")){
Debug.Log(" OnTriggerEnter2D = Enter");
isLeft = true;
}
}
}
Can isFall detect isLeft and isRight OnTriggerEnter2D?
The script works fine,
But I think it would be better to manage it later if I reference it with one script, so I want to know how.
No you can't achieve this with isFall alone, because the documentation of OnTriggerEnter2D says: Sent when another object enters a trigger collider attached to this object. You must attach a script on the left or right collider to trigger the callback.
So... if you create a script for the character, it is able to detect all the colliders.
public class Character: MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collider) {
if (collider.CompareTag("Left"))
isLeft = true;
else if (collider.CompareTag("Right"))
isLeft = false;
else if (collider.CompareTag("Fall"))
StartCoroutine(WaitForSpawn());
}
}
BTW a single field isLeft is enough, because the respawn position is either left or right.

I wanna disable a canvas and destroy the object when the player leaves the collider

I'm trying to make a animated UI and I wanna destroy the object after the player left the Collider and I don't really seem to find a way to do that.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
public class Crate : MonoBehaviour
{
public float duration;
public GameObject animateObject;
public GameObject crateBox;
public Text crateText;
public GameObject crateImage;
public GameObject crate;
public bool playerInRange;
private bool crateOpened = false;
// Update is called once per frame
void Update()
{
if (crateOpened == false)
{
if (Keyboard.current.eKey.wasPressedThisFrame && playerInRange)
{
if (crateBox.activeInHierarchy)
{
crateBox.SetActive(false);
}
else
{
crateBox.SetActive(true);
crateOpened = true;
Animate();
}
}
if (crateOpened == true)
{
Destroy(animateObject);
}
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.CompareTag("Player")) {
playerInRange = true;
crateImage.SetActive(true);
}
}
private void OnTriggerExit2D(Collider2D other) {
if(other.CompareTag("Player")) {
playerInRange = false;
crateBox.SetActive(false);
crateImage.SetActive(false);
}
}
private void Animate()
{
LeanTween.scale(animateObject, new Vector3(1f, 1f, 1f), duration);
}
}
I'm trying to make a animated UI and I wanna destroy the object after the player left the Collider and I don't really seem to find a way to do that.
I think the following is in the wrong place:
if (crateOpened == true)
{
Destroy(animateObject);
}
Try moving this inside the if statement in OnTriggerExit2D. What you are doing now is destroying your animateObject before it is animated. What I think you want is for animateObject to be destroyed when the player leaves the collider.

Problem with Colliders and their rotation in the Unity Game

The problem is that I what to create an openable door. This door should open when the player enter the Box Collider which is connected to the door. But the problem is when the door begins to open and to rotate, Collider starts to rotate too which brings me a lot of problems with usind such an idea. I try to create EmptyObject with its Collider but I can't connect this Collider with script and OnTriggerEnter function itself. Maybe I don't understand something, who knows, I'm just a begginer. How knows how to help, please write an answer.
My code if somebody needs it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class openDoor : MonoBehaviour {
public Vector3 Rotation_;
private int i;
public float speed;
bool opentheDoor;
bool closetheDoor;
// Use this for initialization
void Start () {
opentheDoor = false;
closetheDoor = false;
}
// Update is called once per frame
void Update () {
if (opentheDoor == true) {
this.transform.Rotate (Rotation_ * Time.deltaTime * speed);
i += 1;
if (i == 70) {
opentheDoor = false;
i = 0;
}
}
if (closetheDoor == true) {
this.transform.Rotate (-Rotation_ * Time.deltaTime * speed);
i += 1;
if (i == 70) {
closetheDoor = false;
i = 0;
}
}
}
void OnTriggerEnter (Collider other) {
if (other.gameObject.tag == "Player") { {
opentheDoor = true;
}
}
}
void OnTriggerExit (Collider other) {
if (other.gameObject.tag == "Player") {
closetheDoor = true;
}
}
}
This is how i would handle the scenerio
Take
DoorHandler.cs
public class DoorHandler : MonoBehaviour {
public Door door;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
door.OpenDoor();
}
}
}
This should be attached to Parent of the door.
Next Take
Door.cs
public class Door : MonoBehaviour {
public bool isOpened = false;
public void OpenDoor()
{
if (!isOpened)
{
isOpened = true;
Debug.Log("OPEN");
//OPEN DOOR CODE!
}
}
}
Attach this to the Door GameObject
NOTE
The hierarchy would be like DoorHandler->Door->DoorModel (where Door is just an empty gameobject pivot of the Door)
In DoorHandler GameObject attach BoxCollider and Check Mark IsTrigger.
Also Player SHOULD HAVE A RIGIDBODY (preferably Kinametic) and obviously a collider
So When Player enters the DoorHandler's Collider -> The DoorHandler's OnTriggerEnter will be triggered and finally Call the Door to OpenDoor()
Add another check in OnTriggerEnter that checks if the door is currently opening or not.
void OnTriggerEnter (Collider other) {
if (other.gameObject.tag == "Player" && !opentheDoor) {
opentheDoor = true;
}
}
attach the door to an empty object. put the trigger on the empty object. then make the ontrigger entry rotate the door, not the paent object, and the collider will remain in place.
Parent
-child(door)
-child(collider)

Unity3d Transform.LookAt also changes position

Title says it all.
I provided an NPC with the following script, which should make him look and bark at the player.
When the player comes into the NPC's reach, however, the NPC starts walking towards the player instead of just facing him.
Any thoughts?
using UnityEngine;
public class Barking : MonoBehaviour {
public AudioSource barkingAudio;
private GameObject player;
private bool barking;
void Start () {
player = GameObject.FindGameObjectWithTag("Player");
barking = false;
}
void Update () {
if (barking)
lookAtPlayer();
}
private void lookAtPlayer()
{
transform.LookAt(player.transform.position, Vector3.up);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject == player)
{
barking = true;
barkingAudio.mute = false;
barkingAudio.Play();
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject == player) {
barking = false;
barkingAudio.mute = true;
barkingAudio.Stop();
}
}
}
Since I was using a Rigidbody and rotating the transform manually, there was some unexpected behaviour.
I found some code online which I could replace the Transform.LookAt method with:
var qTo = Quaternion.LookRotation(player.transform.position - transform.position);
qTo = Quaternion.Slerp(transform.rotation, qTo, 10 * Time.deltaTime);
GetComponent<Rigidbody>().MoveRotation(qTo);
This fixed my problem!

Teleport script not working as intended

I would like to make a gameobject in my game, which when enter trigger, then it will teleport my character to an another position (otherTeleport.transform.position), however when I use the script what I have written, my character won't teleport there, while the enemy will. If I put a Debug.Log in the bounce script which will log the character's position I see that my character has been at the otherTeleport's position, but only for one debuglog, and after that it's back to the original teleport's position. The teleport's would be working two-way so if the user go to one it will port it to the second, and if he goes to the second, then it will be ported to the first.
Here is my code:
public class TeleportScript : MonoBehaviour {
public GameObject otherTeleport;
private Collider otherTeleportColl;
public bool isNeedToTeleport;
private TeleportScript otherTeleportScript;
private GameObject player;
private Bounce bounceScript;
// Use this for initialization
void Start () {
isNeedToTeleport = true;
otherTeleportColl = otherTeleport.GetComponent<Collider>();
otherTeleportScript = otherTeleport.GetComponent<TeleportScript>();
player = GameObject.Find("Player");
bounceScript = player.GetComponent<Bounce>();
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider collider) {
if (isNeedToTeleport == true) {
if (collider.tag == "Enemy") {
otherTeleportScript.setNeedToTeleport(false);
collider.transform.position = otherTeleport.transform.position;
}
if (collider.tag == "Player") {
otherTeleportScript.setNeedToTeleport(false);
bounceScript.player.transform.position = otherTeleport.transform.position;
collider.transform.position = otherTeleport.transform.position;
bounceScript.playerTransform.position = otherTeleport.transform.position;
}
}
}
void OnTriggerExit(Collider collider) {
Debug.Log ("TELEPORTED OUT");
setNeedToTeleport(true);
otherTeleportScript.setNeedToTeleport(true);
}
public void setNeedToTeleport(bool value) {
if (value == true) {
isNeedToTeleport = true;
}
else {
isNeedToTeleport = false;
}
}
}
Any help would be appreciated!
I did some changes to your code, can't test it because I don't have access to unity right now, let me know if it works...
public class TeleportScript : MonoBehaviour {
public GameObject otherTeleport;
private Collider otherTeleportColl;
public bool isNeedToTeleport;
private TeleportScript otherTeleportScript;
private GameObject player;
private Bounce bounceScript;
// Use this for initialization
void Start () {
isNeedToTeleport = true;
otherTeleportColl = otherTeleport.GetComponent<Collider>();
otherTeleportScript = otherTeleport.GetComponent<TeleportScript>();
player = GameObject.Find("Player");
bounceScript = player.GetComponent<Bounce>();
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider collider) {
if(collider.tag == "Player" && isNeedToTeleport)
{
otherTeleportScript.setNeedToTeleport(false);
collider.transform.position = otherTeleport.transform.position;
bounceScript.player.transform.position = otherTeleport.transform.position; //not sure what is this for....
}
}
void OnTriggerExit(Collider collider) {
Debug.Log ("TELEPORTED OUT");
setNeedToTeleport(true);
otherTeleportScript.setNeedToTeleport(true);
}
public void setNeedToTeleport(bool value) {
if (value == true)
isNeedToTeleport = true;
else
isNeedToTeleport = false;
}
}
Your character teleports to the other place
after that you move the collider over there aswell, notice that the collider's object of other script of teleportation has been initialized with the isNeedToTeleport = true;
The character now also bounces there, hits the collider of the other object, it checks that isNeedToTelport is in fact true in this other script and it goes into the same If condition and teleports back!
Take this line:
otherTeleportScript.setNeedToTeleport(true);
out of your OnTriggerExit, or set it to false. Actually setting it to false might be better. You want to tell the other script that someone is incoming and it shouldn't immediately teleport them back.
As an aside, you should change your setNeedToTeleport function to this:
public void setNeedToTeleport(bool value) {
isNeedToTeleport = value;
}
Those ifs are redundant.