Why OnDrop is not called? (Unity) - c#

I have had problems with the OnDrop method, it is that it is not called, I was reading and maybe it has something to do with a Raycaster component, but I'm not sure, I don't even have knowledge of it, if someone could explain this to me I would greatly appreciate it.
Here is my code in c # plus an image of my hierarchy in Unity2D:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Drop : MonoBehaviour, IDropHandler
{
public void OnDrop(PointerEventData eventData)
{
if (eventData.pointerDrag != null)
{
Debug.Log("Aqui esta");
}
}
}
From already thank you very much.

OnDrop method is not called
To ensure the Method gets called you need to ensure that both the name and inherited class you use is correct.
As it seems you need to use override for each function and instead of IDropHandler and MonoBehaviour inherit from EventTrigger.
Example:
using UnityEngine;
using UnityEngine.EventSystems;
public class Drop : EventTrigger {
public override void OnDrop(PointerEventData eventData) {
// Check if the eventData is Null.
if (eventData.pointerDrag != null) {
Debug.Log("OnDrop called.");
}
}
}
EventTrigger

Related

Why Coroutine in Non-MonoBehaviour Script is not Working?

i want to call coroutine in a non-monobehavior script but this approach is not working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Attacking : BaseState
{
private MovementSM _sm;
public float movementSpeed;
public MonoBehaviour mono; //here i calling monobehaviour
public bool attackBool;
public Attacking(MovementSM stateMachine) : base("Attacking", stateMachine)
{
_sm = stateMachine;
}
public override void Enter()
{
base.Enter();
_sm.animator.SetTrigger("attack");
}
public override void UpdateLogic()
{
base.UpdateLogic();
mono.StartCoroutine(DelayFunction()); //calling couroutine
}
IEnumerator DelayFunction()
{
yield return new WaitForSeconds(2);
Debug.Log("Test!");
}
}
i tried to acces the monobehaviour using parser method. but it is not clear and didnt work. how to solve this problem. what is wrong in this code.
I tried the other method shown in stackoverflow but not working.
Inheritance and MonoBehaviour aren't friends. In C# you can't inherit from two base classes. There are good reasons for that, but we have to deal with the inconvenience from time to time.
Problem with your script is that the mono variable is null and therefore you will get an error on the StartCoroutine line. Typically you would resolve that by constructing the missing class like this:
public MonoBehaviour mono = new MonoBehaviour();
Only problem with that, there is no constructor for MonoBehaviour (at least not one that is accessible). Sadly I don't have a document to quote, so take it with a grain of salt.
There is a workaround, that basically involves running the Coroutine thru your MonoBehaviour derived base class. I'm assuming that your BaseState is derived from MonoBehaviour.
public override void UpdateLogic()
{
base.UpdateLogic();
base.StartCoroutine(DelayFunction());
}

Tranform.Find Isn't Getting the Correct GameObject

I feel like this is a poor question to ask, but I couldn't figure out what the issue was.
I was making a ScoreController and I wanted to make it so that a coin object, when hit, would add 100 to the score GUI. All the coins have this script inside of them:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CoinScoreController : MonoBehaviour
{
public void OnTriggerEnter2D(Collider2D collider)
{
transform.parent.parent.parent.Find("Canvas/ScoreUIController").CollectCoin();
}
}
I can recognize that this is a very poor way of getting an object but I can't figure out what the issue is. Here is the script that I was trying to reference:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreController : MonoBehaviour
{
public static int score = 0; //Number of coins
public static GameObject scoreUI; //A gameObject for the CoinUI
// Update is called once per frame
void Start()
{
scoreUI = GameObject.Find("ScoreUI"); //Automatically sets all coins to have their coinUI GameObject equal the CoinUI UI.
}
public void CollectCoin() //Runs when a coin is collected. Makes it disapear and adds one to the counter.
{
gameObject.SetActive(false);
score += 100;
scoreUI.GetComponent<Text>().text = "Score: " + score.ToString();
}
public void KilledMonster()
{
score += 1000;
}
}
The ScoreControllerUI is inside Canvas so I don't think I have the wrong path. Can you not transform.Find() from the scene? Here is my scene:
As I am sure you can tell, I am new to this site and to Unity, so I apologize for any mistakes in the way I asked this question. Feel free to give me constructive criticism on that as well. I am using unity version 2020.3.24f1 and coding in C#. I don't know if this is relevant but I am coding using visual studio.
Sorry again for any dumb mistakes I made.
Instead of using
transform.parent.parent.parent.Find("Canvas/ScoreUIController").CollectCoin();
use
GameObject.Find("Canvas/ScoreUIController").GetComponent<ScoreController>().CollectCoin();
Suggestion: Define a public ScoreController ScoreUIController in your CoinScoreController (I'm assuming your coin is a prefab) then drag and drop the ScoreUIController into it to assign your script to our defined variable.
Now, you would be able to call
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CoinScoreController : MonoBehaviour
{
public ScoreController ScoreUIController;
public void OnTriggerEnter2D(Collider2D collider)
{
ScoreUIController.CollectCoin();
}
}
P.S. : Please follow tutorials and read documentation first, as I can see your code is very process heavy.

What is the right way to use get key down in this scenario?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Q : MonoBehaviour
{
void OnTriggerStay2D(Collider2D collision)
{
if (Input.GetKeyDown("q"))
{
Destroy(collision.gameObject);
}
}
}
ok so i wrote code that is supposed to detect when another object is colliding with it to allow the player to press a key to destroy the collider. the code is able to detect a collider but is not able to detect a key press while the collider is being detected. I have zero clue to as why this is happening so if anybody can help that would be great thank you
If you look at the documentation for GetKeyDown, you'll see that it needs to be in your Update callback. This would be super easy to fix though!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Q : MonoBehaviour
{
bool _qPressed;
void Update()
{
_qPressed = Input.GetkeyDown("q");
}
void OnTriggerStay2D(Collider2D collision)
{
if (_qPressed)
{
Destroy(collision.gameObject);
}
}
}

Unity Scene Manager 2018

I have tried using
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadBScene : MonoBehaviour
{
void Start()
{
Debug.Log("LoadSceneB");
}
public void LoadB(string SceneB)
{
Debug.Log("sceneName to load: " + SceneB);
SceneManager.LoadScene(SceneB);
}
}
I have not been able to get the scene to change.
Anyone have any ideas?
Please and thank you!
Looks to me like the problem here is that you simply aren't calling the LoadB() method which means that SceneManager.LoadScene() is never reached. Inside the Start method just put
LoadB("InsertSceneNameHere")

Overriding virtual function not get called in Unity C# script

I wrote the following 2 scripts in Unity 3D , PhysicsObject and PlayerPlatformerController (following this tutorial). The PlayerPlatformerController script is attached to a game object.
PhysicsObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsObject : MonoBehaviour {
void Update () {
ComputeVelocity ();
}
protected virtual void ComputeVelocity() {
}
}
PlayerPlatformerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerPlatformerController : PhysicsObject {
void Update () {
}
protected override void ComputeVelocity() {
}
}
The codes look simple, but the ComputeVelocity() in PlayerPlatformerController does not get called (proved by adding Debug.Log()). Why?
If I change to the following codes, the function works perfectly:
PhysicsObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsObject : MonoBehaviour {
void Update () {
//ComputeVelocity ();
}
/*protected virtual void ComputeVelocity() {
}*/
}
PlayerPlatformerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerPlatformerController : PhysicsObject {
void Update() {
ComputeVelocity();
}
void ComputeVelocity() {
}
}
What did I miss?
It happened to me that I had two scripts:
Health.cs
HealthModified.cs -> This was overriding function of Health.cs
In my GameObject I was testing HealthModified (enabled) and I also had the Health.cs in the gameobject but disabled.
The code was using the Halth.cs compoenent also when it was disabled, I had to remove the component from the gameobject to get the HealthModified behaviour.
It may happen because you use Update method in child-class (PlayerPlatformerController). If it true, you will mark update as protected and virtual, and override it in child class. It may look like this:
public class PhysicsObject : MonoBehaviour
{
protected virtual void Update()
{
ComputeVelocity();
Debug.LogFormat("PhysicsObject Update");
}
protected virtual void ComputeVelocity()
{
Debug.LogFormat("PhysicsObject ComputeVelocity");
}
}
public class PlayerPlatformerController : PhysicsObject
{
protected override void Update()
{
base.Update();
Debug.LogFormat("PlayerPlatformerController Update");
}
protected override void ComputeVelocity()
{
base.ComputeVelocity();
Debug.LogFormat("PlayerPlatformerController ComputeVelocity");
}
}
I finally found out the problem. In the PlayerPlatformerController class, if I remove the Update() method, the override ComputeVelocity() will start working.
Thanks all for your efforts helping me.
When you have a class that inherits from another you need to be wary of accidentally overriding the parent's methods.
In this case, creating empty Start() and Update() methods will replace those from the parent. This is an easy mistake to make since new classes are normally created with those methods by default.
Removing the methods from the child class will ensure the parent is called instead. Or if you want to keep the child methods while also calling the parent's, you can use base.Start() (or whichever method you are overriding).

Categories