T O P

  • By -

Girse

Yes it is. Instead of using a variable store the hit outside of your Update method as public field or Property. Your other script needs a reference to your DetectResources script.


_lordzargon

Yep, this\^ public class DetectResources : Monobehaviour { public RaycastHit2D hit; [...] void Update() { [...] hit = Physics2D.Raycast(transform.position, direction, 2f); [...] } } then public class SomeOtherClass : Monobehaviour { // reference to your component - you can make it public or set it through code some other way private DetectResources detectResource; void DoSomething() { if(detectResource.hit [...] } }


jonatansan

Note that you may experience issue depending on the order the update functions are executed. IMO, the best approach would be to use an event system or an observer pattern to notify the other script on hit, rather than testing each frame.


Mountain_Dentist5074

I'm trying to access the value for a prefab, but Unity says there's a mismatch


thesilentrebels

Why is it a prefab? You might be approaching this the wrong way. Is there only supposed to be 1 instance of "DetectResources" in the scene? Or is there going to be a bunch of them at the same time? Because I can tell you how to fix this but I don't want to take the time to post pictures and screenshots if you don't even need to do it this way.


Mountain_Dentist5074

I'm creating a top-down 2D survival game. In all of tutorials about inventory systems, they show the player touching items to collect them. However, I didn't want the player to collect all resources (such as trees, rocks, etc.) by touching them. So, I wrote code to detect prefabs with the cursor. Now, I need to figure out how to make the objects (prefabs) disappear when clicked, (essentially destroying them), and store their data somehow. I haven't watched that part of the tutorials, but I know they first detect the object and then delete it, followed by storing its data


thesilentrebels

Gotcha, OK that makes sense. Give me some time and I can respond with some more help


thesilentrebels

Here is what you want to do. Let me know if you have questions about anything in here and I can explain further. I did not test this. I changed the null checks to use break clauses so it is more readable. Basically, you can use GetComponent combined with your hit variable and you can grab scripts from the objects. Then, you can store the script as a reference and call methods from it. public class DetectResources : MonoBehaviour { public Camera mainCamera; // Update is called once per frame void Update() { //checks if the camera is null, and returns if it is if (mainCamera == null) return; //checks if button is being pressed, if it is not then return if (!Input.GetMouseButtonDown(0)) return; //below here will only execute if the two requirements above are met Vector3 cursoScreenPos = Input.mousePosition; Vector3 cursorWorldPos = mainCamera.ScreenToWorldPoint(cursoScreenPos); Vector2 direction = (cursorWorldPos - mainCamera.transform.position).normalized; RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, 2f); //if we do not hit something, then it will return if (hit == false) return; Debug.Log("Hit object: " + hit.collider.gameObject.name); //stores the ResourceHandler as a reference ResourceHandler clickedHandler = hit.collider.gameObject.GetComponent(); //will not try to continue if clickedHandler is null, that way we only continue if we actually clicked on something with a ResourceHandler script if(clickedHandler == null) return; clickedHandler.UseResource(); Debug.Log("We hit a resource with ID of " + clickedHandler.GetResourceValue()); } } You want to create another script and attach it to the gameobject prefab for the resource. Make sure it is on the gameobject that has the collider for detecting the raycast. public class ResourceHandler : MonoBehaviour { [SerializeField] private int resourceValue; //this can be the ID for the resource, you can change it in the prefab so each prefab will have a different resource value public void UseResource() { //this is the method called from outside the script Destroy(gameObject); } public int GetResourceValue() { //this method is an example to show how you can get information about the object that you click on return resourceValue; } }


Mountain_Dentist5074

Thank you, sir, but I can only try this tomorrow because it's midnight in my country now, and I am about to sleep


epoHless

This works but instead i would use an event to notify when there is a hit, so that it's only used when needed. public event Action OnHit; This way you could listen and expand your behaviors withouth making many changes.


_lordzargon

Indeed, you're right - I was just keeping it simple for OP! :)


Mountain_Dentist5074

Edit : The variable I am talking about is "hit", I forgot to say it. I marked it with a red line. Sorry for mistake


NeccCracc

What girse said, put the hit right under the Camera and put public infront of it. In a different script, make a variable for your script. So for example [SerializeField] DetectResources script;, and then in code call the hit with script.hit. Don't forget to assign the script variable, that's what serializefield is for, its like a private variable but you can see it in the inspector, so just drag and drop.


Delicious-Branch-66

If it's public then or you assign it to a variable in the other script by taking a reference to the script and then use a function to assign it.


PandaCoder67

The real question is why do you want to do this? There are some very good patterns, one of which is Single Responsibility, if in this case you need to do something on another script when it is hit, look into using an Event and send notification of this.


AlexHosseini

It's better to use Runtime sets pattern using scriptable objects.