#This isn t tested and it still sets the

1 messages · Page 1 of 1 (latest)

cold nimbus
#

so say you have this interface:

public IClickable {
    void OnClicked();
}

#

We can implement this interface on objects like so:

public class UtilityObject : MonoBehaviour, IClickable {
    public void OnClicked() {
        // Player clicked this utility object
    }
}

public class EquippableObject : MonoBehaviour, IClickable {
    public void OnClicked() {
        // Player clicked this equippable object
    }
}

public class InventoryObject : MonoBehaviour, IClickable {
    public void OnClicked() {
        // Player clicked this inventory object
    }
}

public class InspectableObject : MonoBehaviour, IClickable {
    public void OnClicked() {
        // Player clicked this inspectable object
    }
}
last herald
#

Ohh, so like use it to call some event from the object itself?

cold nimbus
#

You can do something like this instead of what you have in your screenshot:

void Update(){
    ray = cam.ScreenPointToRay(Input.mousePosition);
    if(Physics.Raycast(ray, out RaycastHit hit)){
        IClickable clickable = hit.transform.GetComponent<IClickable>();
        if(clickable != null) {
            clickable.OnClicked();
        }
    }
}
#

this is significantly more performant and maintainable

#

leverage the power of polymorphism! 🌩️

last herald
#

So, I have some issues with that. 1, this should happen when it's hovered over, not clicked. 2, it's kinda weird from a data design perspective to have every single object contain a script just to change the cursor

cold nimbus
#
  1. okay, the naming is not relevent, you can just rename it to OnHover
last herald
cold nimbus
#

the functionality is literally the same, it's just names of stuff

#
  1. this route allows you to extend functionality in the future. if you're ONLY looking to change the cursor. but i imagine if you're looking to have a cursor change on hover, you'll probably want cursor change on unhover, and interactions on click, or click and drag, etc.
last herald
#

Yeah, I know better. Not sure why I thought that

cold nimbus
#

if you're ONLY looking to change cursor on hover, you could just use a dictionary

#

Dictionary<string, Sprite>

#

where string is the tag

#

that would be performant enough

#

but you could also extend the interface or use a dictionary of types

#

Dictionary<Type, sprite> typeCursorSprites;

and in your code:

cursor.sprite = typeCursorSprites[typeof(clickable)];

last herald
#

I do want you to be able to left and right click to inspect or use objects, but I figured I'd use OnMouseDown, which doesn't exist for hovering. Clicking functionality has very little to do with the hovering, as well

cold nimbus
#

so think

#

how could you expand the interface to add this functionality?

last herald
cold nimbus
#

yes you're right

last herald
#

If I stuck with the current approach, I would have one main script handling hovering stuff, and one on all the objects with the clicking stuff

cold nimbus
#

i was simply using interfaces to get you to thinking down the right path when it comes to using interfaces and polymorphism rather than massive switch statements

last herald
#

Actually, now that I'm thinking of it...

cold nimbus
#

Look at this page:

#

there are a bunch of functions for "OnMouse"

#

the idea is the same though, leverage that every object is a MonoBehaviour and skip using tags or switch statements

last herald
#

Wouldn't the same objects have hovering as have clicking functionality? So in theory, using an interface would be ideal for that, so objects don't show that they can be clicked (what the cursor shows) but not actually have any clicking functionality

cold nimbus
#

yes

#

exactly

#

trust me, doing it this way

#

is 10000000% more maintainable

#

it's also more performant

#

use an interface, define any common methods to clickable objects in that interface

#

then define classes that implement that interface

#

it seems odd to have so many classes for now, but you're saving yourself alot of hassle in the future

last herald
cold nimbus
#

yes you can use those methods i mentioned. the only worry is if two objects get hovered over on the same frame

last herald
#

Yeah, I think you've convinced me

cold nimbus
#

but that's an edge case im sure you cna handle

last herald
#

Thank you a ton

cold nimbus
#

👍 good luck.

#

one more thing i'll leave you with

#

i knew right away you needed to restructure your code when i saw your switch statements. we say code "smells" when you're doing something in a way that it shouldn't

#

if you're interested in optimizing and getting better at coding, look into design patterns

#

you'll use them daily as a game programmer

#

^ a really great resource

last herald
#

Oh yeah, I knew that was done poorly but thought I pretty much ruled out my other options

#

Is it possible to have an interface contain "predefined" code? Something like the interface calling Cursor.SetCursor(newCursor, cursorHotspot, CursorMode.Auto); with its own cursor by just doing SetCursor(utility) or whatever?

cold nimbus
#

yep! they're called abstract classes

#

that's why i was mentioning them before

#

look into them and learn what they are, you'll use them alot

last herald
#

Okay, so that's what those are

#

I speedread that page you sent a few times and couldn't figure it out. I'll have to take a deeper look

cold nimbus
#
public abstract class ClickableObject : MonoBehavior {
  [SerializeField] protected Sprite cursorHoverSprite;

  public virtual void OnMouseHover(Cursor cursor){
    Cursor.SetCursorSprite(cursorHoverSprite);
  }

  public abstract void OnMouseClick();
}
#

for example

#
public class UtilityObject : ClickableObject {
  public override void OnMouseClick() {
    ...
  }
} 
last herald
#

Wait, do I just define these abstract classes in my GameManager script then?

#

Oh, are they their own script?

#

I'm just gonna find a video on them real quick, actually

#

Thank you again!

cold nimbus
#

essentially you need to know, in an abstract class:

  • if a method is marked as "virtual", then the abstract class can provide an implementation, and any classes that derive from the abstract class can override that method.
  • if a method is marked as "abstract", then the abstract class CANNOT provide an implementation, and any classes that derive from the abstract class MUST override that method and provide a implementation
#

they go in their own script file