This is the code i am using and i am trying to add a wait inside of the if collision thing anyone know what to look into or a solution? i tried looking into coroutines and using bool values to try and do it that way but i couldnt figure it out any help or suggestions is appreciated!
using UnityEngine;
using System.Collections;
public class SwordDetection : MonoBehaviour
{
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy")
{
collision.rigidbody.constraints = RigidbodyConstraints.None;
}
}
}
You can call a coroutine from within OnCollisionEnter() to create a delay.
Some example code:
private void OnCollisionEnter(Collision collision) {
StartCoroutine(DelayedAction());
// coroutines must be called from StartCoroutine()
}
private IEnumerator DelayedAction() {
yield return new WaitForSeconds(5);
print("I was printed after a delay of 5 seconds!");
}
I'm not sure if this is exactly what you want, but you can use:
OnCollisionStay(Collision collision) { }
Related
I am trying to make an object that teleports the player to a different scene when clicked.
I tried following this tutorial: https://youtu.be/PpLJq6AR2J0
This is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Table : MonoBehaviour
{
[SerializeField] private GameObject UiElement;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
SceneManager.LoadScene("Table1");
}
}
}
void Update()
{
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(false);
}
}
}
But when I tried it executes everything except
if (Input.GetKeyDown(KeyCode.E))
{
SceneManager.LoadScene("Table1");
}
The code is correct and it executes when it's inside the update function. Is there a fix to this?
The physics framerate update doesn't have to match the game framerate. The Input.GetKeyDown will be true only for one frame so it won't be called. You should put input checks like Input.GetKeyDown inside the update function.
This is not the best way to do it but only to show a way to do it:
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(true);
colliderHit = true;
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
if(colliderHit)
SceneManager.LoadScene("Table1");
}
}
Thanks, here is the solution:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Table : MonoBehaviour
{
private bool collided = false;
[SerializeField] private GameObject UiElement;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
collided = true;
}
}
void Update()
{
if (collided == true)
{
UiElement.SetActive(true);
if (Input.GetKeyDown(KeyCode.E) && UiElement == true)
{
SceneManager.LoadScene("Table1");
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
collided = false;
UiElement.SetActive(false);
}
}
}
I just used a boolean called collided. That way u can check inside the Update() function.
This code is attached to my player by a script named PlayerCollision:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollision : MonoBehaviour
{
void Start()
{
}
void Update()
{
}
void OnCollisionEnter (Collision collision)
{
if (collision.collider.tag == "Finish")
{
Debug.Log("Level Finished");
}
}
}
Can Someone tell me why this code is not displaying Level Finished in the Console
If it's a 2D game, I think you want to use OnCollisionEnter2D: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html
void OnCollisionEnter2D (Collision2D collision)
{
if (collision.collider.tag == "Finish")
{
Debug.Log("Level Finished");
}
}
here is my player attach code for moving platforms:
I'm getting an error CS1001: Identifier expected for some reason ant youtube is not helping me...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttach : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
function OnTriggerEnter(other.Collider){
if (other.gameObject.tag == "player")
{
transform.parent = other.transform;
}
}
function OnTriggerExit(other.Collider){
if (other.gameObject.tag == "player")
{
transform.parent = null;
}
}
}
}
What you have is unityscript which is long deprecated and not compatible with c#!
And in general do not nest MonoBehaviour messages under Update! Otherwise the messaging system won't find them and they are never called at all.
Your class should look like
public class PlayerAttach : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
// Rather use CompareTag instead of ==
// the latter fails silently in case of s typo making your debugging live only harder
if (!other.CompareTag("player")) return;
transform.parent = other.transform;
}
private void OnTriggerExit(Collider other)
{
if (!other.CompareTag("player")) return;
transform.parent = null;
}
}
Further, a logical question: How exactly do you expect the player object leaving this collider if you make it a parent so whenever the player object moves this object moves along with it?
So i want to check if a spawned Block (prefab) collides with my trigger collider but what i wrote doesn't seem to work. Anyone knows how to correctly check if the colliding GameObject is a Block?
Thanks in Advance. :)
Check:
using System;
using GameOver;
using UnityEngine;
public class gameOver : MonoBehaviour
{
[SerializeField] public DeathScreen deathScreen;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.gameObject.GetType() == typeof(Block))
{
deathScreen.Setup();
}
}
}
Block:
using System;
using TMPro;
using UnityEngine;
public class Block : MonoBehaviour
{
private int _hitsRemaining = 5;
private SpriteRenderer _spriteRenderer;
private TextMeshPro text;
private void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
text = GetComponentInChildren<TextMeshPro>();
UpdateVisualState();
}
private void UpdateVisualState()
{
text.SetText(_hitsRemaining.ToString());
_spriteRenderer.color = Color.Lerp(new Color(0.35f, 1f, 0.67f), new Color(0.04f, 1f, 0.96f), _hitsRemaining / 10f);
}
private void OnCollisionEnter2D(Collision2D collision)
{
_hitsRemaining--;
if (_hitsRemaining > 0)
UpdateVisualState();
else
Destroy(gameObject);
}
internal void SetHits(int hits)
{
_hitsRemaining = hits;
UpdateVisualState();
}
}
Block Prefab:
Collider:
To check if the collided object is an instantiated Block (or any Block really), you check for the existence of the Block component:
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.GetComponent<Block>() != null)
{
deathScreen.Setup();
}
}
Additionally, with one of your collides being a trigger, OnCollisionEnter2D will not be called. Either switch both to non-triggers if you can, or use OnTriggerEnter2D - but then one of your objects has to have a Rigidbody2D as well (source), so it is really up to what you are designing.
i faced the problem that after some manipulations with code(Dont remember after what exactly) Physics2D.IgnoreCollision stopped working properly. I'm new to stack overflow, and dont know what else to attach here, if something else is needed to understand the situation, please tell me and i will add. Thanks in advance!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TurnOffGroundCollider : MonoBehaviour
{
[SerializeField] GameObject ground;
[SerializeField] GameObject ball;
private void OnTriggerEnter2D(Collider2D collision)
{
Physics2D.IgnoreCollision(ball.GetComponent<CircleCollider2D>(),
ground.GetComponent<BoxCollider2D>(), true);
}
private void OnTriggerExit2D(Collider2D collision)
{
Physics2D.IgnoreCollision(ball.GetComponent<CircleCollider2D>(),
ground.GetComponent<BoxCollider2D>(), false);
}
}