Proximity Selector World Space Button

Announcements, support questions, and discussion for the Dialogue System.
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Proximity Selector World Space Button

Post by EnigmaFactory »

Hey all,

I have a couple paths forward, but looks for suggestions on most elegant way to implement the follow:

My project is mobile and uses ClickToMove on a NavMesh. For interactions, I'm using ProximitySelector with Touch Enabled on legacy UI settings. I plan to convert to UGUI (with DoozyUI) elements.

How I'd ideally want it to work is when you are in proximity a world space UI Button appears above the object / NPC (such as a talking bubble icon above NPC) and then you click (or touch) using a raycast to touch point to trigger the Action (OnUse message).

I'm trying to work out the best way to handle this with as little overhead as possible, with as few added components as possible, and dynamic as possible so it's easy to integrate new interactables going forward.

Love to hear any thoughts especially what @Tony things!
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Proximity Selector World Space Button

Post by Tony Li »

Hi,

Especially since you're going to use DoozyUI, it's probably best to write a very small script. For example, something like this:

WorldSpaceUsableButton.cs

Code: Select all

using UnityEngine;
public class WorldSpaceUsableButton : MonoBehaviour
{
    public void ClickedUseButton()
    {
        FindObjectOfType<PixelCrushers.DialogueSystem.ProximitySelector>().UseCurrentSelection();
    }
}
(You could optimize this by caching the ProximitySelector at start.)

Then:

1. Add a world space UI button to your NPC/object. Set it inactive.

2. Add the script above.

3. Add a Usable component.
3a. Configure the OnSelect() event to activate the world space UI button.
3b. Configure the OnDeselect() event to deactivate the world space UI button.

4. Configure the UI button to call WorldSpaceUsableButton.ClickedUseButton().

If you want to do more than simply activate and deactivate the world space UI button (for example, call some Doozy methods), you can add another method to WorldSpaceUsableButton and call that in the OnSelect() event.
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Re: Proximity Selector World Space Button

Post by EnigmaFactory »

Hi Tony and all!

So I was not expecting that to get implemented so easily!

Image

Check it out in action: https://www.twitch.tv/videos/674505575

For anyone curious, I did the following

1) Created World Space Canvas via Doozy UI and added it to my NPC's Head Bone:
Image

2) Copy and Pasted Tony's script above to create a new script of WorldSpaceUsableButton.cs

3) Added WorldSpaceUsableButton to Button - DailougeUseable GameObject

4) In the DoozyUI control panel for the Button, added a call to WorldSpaceUsableButton.ClickedUseButton() on Button Click event:
Image

5) On NPC's root object (Receptionist) Usable component, I added events to change the World Space Canvas SetActive status based on On Select, On Deselect, and On Use.
Image

Future Homework

A) Add Method to WorldSpaceUsableButton to animate or fade when selected / deselected instead of just toggling it's Active Status on and off.
B) Dynamically adjust WorldSpaceUsableButton Icon Image depending on the type of object being selected (ex: Keyboard Icon when object selected is a computer) Perhaps I will use the Usable components Override Name and / or Override Use Message to accomplish this or, may be it is smarter to use the Tag System of the Standard UI (since I need to convert my selectors anyways) as seen here: https://www.pixelcrushers.com/dialogue_ ... ments.html
C) I Set the World Space Canvas SetActive to False on use. This hides the button when in a dialogue, which is good, but then it does not reactivate unless you leave trigger proximity and return. Usually this is a good thing, but sometimes I might want you to have the ability to repeat the conversation without moving away and back in. I can think of a few ways to do this, but they would all take additional set up when making new interactables. This one might take more thought / build out because it would be nice to only show the UI when the interactable has a valid Conversation to play based on conditions. I'll think this one out more, and then bother Tony :lol:
D) Can't remember how to organize Response menu. Think it's something simple like [1] sorta deal, but gotta remember / refind how to do that! Think I have it in a 3 year old email with Tony. haha

Unrelated Issues

- My project is Mobile focused so moving around is annoying. I'm using a Click/Touch to Move system using a Plane on a NavMesh for performance. I'm currently offering a Follow Camera and an Isometric Camera. I will likely also be adding fix point (Resident Evil) cameras with tracking rotation depending on room you are in. That said, I still will mostly be using Menus / Conversations to usher you between the interactive elements of the game. Currently, I'm using Sequencer Events like NavMeshAgent(NavReception01,listener); to move the player to empty GameObjects in the world. This does not respect rotation however. I may need to customize the navigation anyways, but I want to make sure I can have sequencer commands that can accomplish what I want here.

Pras

So it's been a little bit since I been deep in a project, but I just gotta say, Tony's support is top notch. Every year or so I come with something and provides the most elegant solution. Dialogue System is so powerful that no matter what my project is, it's always the first asset I import and I own thousands of dollars worth of assets at this point. Thanks so much Tony and community!
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Proximity Selector World Space Button

Post by Tony Li »

Thanks for taking the time to write up what's essentially a detailed tutorial! Once again I wish this forum software had a Like button.

To reorder the response menu at design time (e.g., in the Dialogue Editor), inspect the preceding node. The inspector's "Links To:" section will show all of the responses the node links to. Each response has up/down arrows that you can use to reorder them.

To reorder the response menu at runtime, add an OnConversationResponseMenu(Response[]) method to a script, typically on the Dialogue System. You can reorder the responses, but you can't add or remove responses.
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Re: Proximity Selector World Space Button

Post by EnigmaFactory »

Expect a lot more of this kinda thing from me (and stupid questions!) as I'm deep diving back into Dialogue System.

Thanks for the help with that and the response order. New stupid questions brewing!

Also, here is "Thank" button for phpbb3.2: https://www.phpbb.com/community/viewtop ... #p15052481
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Proximity Selector World Space Button

Post by Tony Li »

Thanks!
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Re: Proximity Selector World Space Button

Post by EnigmaFactory »

Dude there (could be) a button for that :lol:
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Re: Proximity Selector World Space Button

Post by EnigmaFactory »

Good morning Tony!

So here's my new bug. I've added a Rival character actor that comes into the office at the same time you do. The Rival has a Sphere Collider that is a trigger for when later he'll be usable. When they walk into office, the Player is within the Rival's Sphere. The World Space button can be hovered and the DoozyUI effects play, but when you click it, nothing happens. When I drag the Rival away, you can then talk to the Receptionist. Once you've talked to her once, even if you are back in the Rival's sphere, you can talk to her again. Any thoughts?

Here is a video of the issue: https://www.twitch.tv/videos/675545074

I'm assuming it's something like, since we're using:

FindObjectOfType<PixelCrushers.DialogueSystem.ProximitySelector>().UseCurrentSelection();

It doesn't know what "CurrentSelection" is. You are entering Receptionists, but then the Rival walks up and now you are in his.

Thanks in advance!
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Proximity Selector World Space Button

Post by Tony Li »

Exactly. ProximitySelector always uses the most recent Usable trigger entered. It keeps track of all triggers that it's currently inside, so when the most recent one leaves, it switches to the previous one.

If you want to prioritize Usables, you could:

1. Make a subclass of Usable with a priority value:

Code: Select all

public int priority;
2. Make a subclass of ProximitySelector that overrides UseCurrentSelection() to use the Usable with the highest priority:

Code: Select all

public override void UseCurrentSelection()
{
    currentUsable = /* choose the element in usablesInRange with the highest priority */
    base.UseCurrentSelection();
}
EnigmaFactory
Posts: 9
Joined: Sat Apr 27, 2019 5:14 am

Re: Proximity Selector World Space Button

Post by EnigmaFactory »

Hi Tony!

That's an idea and might be worth implementing for me, but for my project, I'm thinking that's not ideal. Since I'm using the world space buttons to trigger UseCurrentSelection, what I'd perfer is you see buttons for all Usables you are in range for and then the OnClick can tell them what Usable was actually hit. In your documentation I found SetCurrentUsable and thought I was golden, but here is how I updated ClickedUseButton() and I'm getting errors. It's likely that I'm just too rusty on my C# and it's not optimized or how I'd ideally like it, but it gets what I'm going for across:

Code: Select all

    public void ClickedUseButton()
    {
     FindObjectOfType<PixelCrushers.DialogueSystem.ProximitySelector>().SetCurrentUsable(GetComponentInParent<Usable>);
     FindObjectOfType<PixelCrushers.DialogueSystem.ProximitySelector>().UseCurrentSelection();
    }
The error I get for SetCurrentUsable is "inaccessible due to it's protection level" and then for the GetComponent<Usable> I'm getting "Type or namespace not found" likely because I just don't remember how to find it on the root object in my hierarchy and would like to avoid putting a reference in there as it's another thing I'd have to add on every ScreenSpaceButton interactable I add to my scene.
Post Reply