Change the mouse upon mouse over objects with tag.

Alright, this is the C# code I’ve been trying to get to work for the last few days in Unity5, 3D mode.
What the code is supposed to do is create a hand sprite whenever the player’s actual mouse hovers over an object with the tag “Door”

In attempting to get this script to work, I’ve just been using “floor” for the texture, instead of a hand, because I still need to get the script to it actually work. The script is placed on the FPS character camera.

The syntax error I’m getting is a name space error. If you could help me fix this, it would be much appreciated. I think that the error might have to do with where the script is placed, but C# is just not very familiar to me.

void Start()
{
SetCursorTexture(cursorTextureNormal);
}

void Update()
{
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
bool useNormalCursorTexture = hit.collider.gameObject.tag.Equals(“Door”);
SetCursorTexture(useNormalCursorTexture ? cursorTextureNormal : cursorTextureNo);
}
}

void SetCursorTexture(Texture Floor)
{
Cursor.SetCursor(Floor, Vector2.zero, CursorMode.Auto);
}

Might be easier to do a GUI.Label, and simply toggle a boolean when you are looking at a door. I believe you need Cursor to be visible to change its texture(don’t quote me, just a guess).

So check out OnGUI, and let me know if it helps!

1 Like

Alright, I’ll try it.

In addition, you could use a tag “Interactable”, and use the same hand texture. Making this applicable to more than just doors, ex. chests, items, etc.

One word, but code side makes more sense in the long run in terms of tagging.

1 Like

I think I’m just going to come out and say that I’m flat out stuck. I’ve been on the GameJolt Developers chat, on and off for the last 48 hours looking for a resolution to this problem, and unfortunately I’ve found none. I’m trying to do something very simple in Unity, but I’m very new to C#; Noob new. I started using Unity because Game Maker didn’t have enough 3D support, and everyone told me that it would be a breeze. However, C# is leaps and bounds ahead of GML, it puts it to shame. I’ve worked extensively with GML, and I’ve touched upon Javascript, but C# is just another beast in itself. I’ve been to the Game maker forums, so I know that I’m not supposed to ask for things to be “done for me”, that’s why I’m distraught about doing it now. Every time someone tries to give me a solution, it either doesn’t work, or I’m left wondering exactly how to enact that solution.

This is the effect I’m trying to achieve: When the players view (the invisible mouse) hovers over certain objects (for example , a door), a hand sprite will appear in front of the player (very similar to that found in the game “Amnesia”) alerting him/her that he can activate that object. I’ve also tagged my door with the tag “Door”. But as for creating a script to implement this, I have no idea. I’m always receiving new errors, being told that I didn’t name my variables, or that the texture can not be converted into a 3D texture. Regardless, the problem seems so simple, even with Game Maker’s lack of 3D support, I could achieve this effect without a hitch. Please be aware that I have no prior experience with C#, the script above was the entire script, nothing more. And, that I did not make that script, I either found that via tutorial, or someone else crafted it for me to help me.

Due to my frustrations, I’m going to learn C# so that I can find the answer on my own. But, if anyone feels compelled to help me in the meantime, then I would much appreciate it. The game that I’m using Unity to develop wasn’t originally going to require any (or much) code, but I realized that you just can’t get bye with the standard assets provided. In this sense, I’ll be making a big investment so that I can troubleshoot things in the future for myself, instead of litterally asking others to build code for me from the ground up, and hold my hand through it. I also figure, if I could teach myself GML, and I one day hope to be in the field of computer science, I might as well learn C#.

Yes, it’s difficult learning a programming language for the first time, but it’s well worth it. C# is also a fantastic first language IMO, because it’s one of the most anal-retentive languages in the world- everything has to be perfectly explicit with perfect syntax, or it’s going to scream at you (they did introduce that “var” crap more recently, but I suggest you ignore that it exists entirely).

Some might say that Python or Javascript is easier because you can get away with more, but while that might have the near-future benefit of less visible errors and easier compilation, it’s 100x easier in those loose-languages to get invisible problems that are a total pain to debug, because you get no warnings at all.

Anyways, I’m rooting for you! Give me a minute to look over your specific problem so I might be able to offer a suggestion or two.

1 Like

Okay, problem 1 is that I can’t tell where your “ray” in your raycast is being defined. A ray is an object, and it needs to be created- it’s not a keyword or something. Also, copy the entire script into a post here and put it in [code ][/code ] tags so I can look it over. Make sure “using UnityEngine;” is defined at the top too. Write out the whole error too, or rather the part about what namespace it’s looking for or where it’s pointing at as “wrong”- not enough information.

General Overview:
Basically what you’re doing is your taking your player’s current position (could be the camera if it’s first-person) and you’re going to shoot an invisible laser right out in front of you and see what you hit. This requires several different parts, the biggest of which is that the object you’re trying to hit has a Collider attached to it. If it doesn’t have a Collider, the raycast can’t see it, so it can’t hit it. You can go into the inspector and add a component to the door object called a “Box Collider” and set it visually to be more or less overlapping the frame of the door, make sure it’s turned on, and that’s it for that.

Back in your script, you need to define a new “ray”. A ray is like a laser- it’s made up of an origin point and a direction. Luckily for us, there’s a shortcut to making a ray shoot out straight from the middle of the viewport, and it’s called Camera.ViewportPointToRay. All you have to do is feed it the viewport coordinates as a parameter (viewport coordinates are “percentage of the screen”, from 0 to 1, starting from bottom left) for the center of the screen. That’s “new Vector2(0.5f, 0.5f)” for exactly half each way. That’ll give us a ray positioned at the middle of the viewport (but in world coordinates) and pointing in the same direction as the camera. Cake!

Ray ray = Camera.ViewportPointToRay(new Vector2(0.5f, 0.5f));
RaycastHit hit;

Now the raycast is the act of shooting that ray and trying to hit something with it. That takes several parts, the first of which is the ray itself (you can also pass in the origin point and direction manually here, rather than making the ray first, and it’ll make it internally- same difference). The next parameter is your “RaycastHit” that you’ll define first. If the raycast hits anything, the information about what’s been hit will be stored in that variable. You can also specify a maximum distance to shoot the ray, and a filter for which layers the ray can interact with. The max distance is automatically set to Mathf.Infinity (go forever) if you don’t want to worry about it.

Physics.Raycast(ray, hit)
{
}

Finally, when and if a hit occurs, it’ll go into the “if” conditional you’ve set and you can check the tag of the object. What you have there looks far too complicated- you can check the tag with a simple:

if(Physics.Raycast(ray, hit))
{
   if(hit.collider.tag == "Door")
   {
   }
}

The use of a conditional operator here with:

useNormalCursorTexture ? cursorTextureNormal : cursorTextureNo

should be destroyed with all of the vehemence you can muster. This kind of thing makes for confusing code that’s hard to read, and nothing more. If you need a conditional statement, just write the whole statement out, don’t bother with this kind of shortcut. Here’s one way to do this:

if(hit.collider.tag == "Door")
{
   SetCursorTexture(cursorTextureNo);
}
else
{
   SetCursorTexture(cursorTextureNormal);
}

And you need to place the “normal” setter as an “else” case to your raycast as well, so it also changes back if the raycast hits nothing at all, and not just if it hits something but that something isn’t a “Door”.

2 Likes