0
\$\begingroup\$

I'm trying to figure out a good solution in a third-person RPG to determine if the character is facing and close enough to an object for it to highlight and be shown as a usable item - a door, or a chest, or any other usable object in the scene.

I imagine the best approach is ray-casting, but I've yet to figure out how this would actually work. I plan to have a usable script on all usable objects that defines what happens during use (a door or chest opens, a coin goes into your inventory, etc), but I need to know whether the player can use the item, highlight it, and also determine which object is the "best choice" based on facing direction and distance if multiple items are in range.

\$\endgroup\$
1
\$\begingroup\$

You can figure out how much the player faces an object by taking the normalized vector pointing from the player to the object and the player's directional vector and using dot product on them. If the player faces the object exactly, then it'll return 1, if the player's looking in the other direction, then -1.

\$\endgroup\$
1
\$\begingroup\$

A simple BoxCast(NonAlloc) used to create a box at a reasonable distance in front of the character will do the job. If you can afford using a LayerMask (let's say all your interactive objects are tagged as interactive) only the right objects will be returned. Then you can apply your logic to determine the most relevant one.

\$\endgroup\$
  • \$\begingroup\$ Hmmm, I will have to give this a shot. I've not even seen this in the docs before. I use layers extensively, but also haven't used layerMasks. Is there a way to set the mask using the name of the layer(s) rather than their numeric value - in the event that a layer is moved? \$\endgroup\$ – Jesse Williams Mar 5 '17 at 17:35
  • 1
    \$\begingroup\$ @JesseWilliams Absolutely! You can use NameToLayer ;) \$\endgroup\$ – lvictorino Mar 5 '17 at 17:45
-2
\$\begingroup\$

I think the simplest way to solve this is using a collider.

  1. Create a collider originating at the player's camera.
  2. Extend this collider in front of the player to simulate the player's field of view.
  3. Mark the collider as trigger.
  4. On the OnTriggerEnter method, check if the other object has for example a script component named UsableObject
  5. Call a Highlight method that you defined on that class
  6. On the OnTriggerExit method, call another method on that class that turns off the highlight.

As for the collider's shape - it is best if you create a frustrum shape or a cone/pyramid. However these cannot be natively created in Unity and you'll have to import a model from Blender or similar. If you need more help with that let me know.

\$\endgroup\$
  • \$\begingroup\$ This seems like a pretty expensive method. Maybe I'm wrong, but I suspect that this wouldn't be super quick. \$\endgroup\$ – Jesse Williams Mar 5 '17 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.