Hologram | Roblox's First 3D ProximityPrompt System from games like Detroit: Become Human | v0.1.9

This is amazing! Is there a way to disable viewing from certain sides? For example, I want some prompts to only be visible from the top. Is there a way to change the size of the UI? It’s pretty big for my use case

1 Like

There isn’t a way to disable viewing from certain sides yet, but I can work on that functionality.

You can change the size and customise the Hologram deeply by taking out the model ‘PromptTemplate’ and putting it in workspace. Don’t forget to return it!

Screenshot 2025-01-30 at 8.11.15 pm

1 Like

That functionally could be replaced by just rotating the prompt to always face the character.

Kind of like how the 2D version doesn’t change location but you can always see it pointing towards your direction.

Anyways… I think you should try to implement 1 or the other. Both would be a little time consuming.

Also. One more feature I can suggest is being able to customize certain proximity prompts by tagging or attributing them with certain things. It would be really useful for games with the need to identify different types of prompts.

Oh and size customization! It’s way to big as it is right now. Would be nice if it was smaller.

There already is a feature that makes it rotate to always face the character.

Hologram:SetBillboardActive(true)

I’ll look into customisation.

For size, you can resize it yourself as I’ve already stated.

Does it face the character or the camera position / angle ?

Test it for yourself: Holograms

Hiya!

I absolutely love the resource; few suggestions though:

  1. While testing, I noticed that all of the ProximityPrompts’ ‘Style’ were set to ‘Default’ and yet, still displayed this “Holographic” effect, would it be possible to make this configure-able? (i.e., an option for this style to only appear on a ProximityPrompt when their ‘Style’ is set to ‘Custom’)
    Note: I also noticed that despite setting a ProximityPrompt’s ‘Style’ to ‘Custom’, the holographic effect was still shown.

  2. It’d be amazing if you could add an option for it to continuously track your camera’s position and have it adaptively display the effect at whatever angle your camera is positioned/pointed at the object, instead of the effect popping up and staying at the position your camera was looking at the object prior to proximity.

  3. Minor, but still would be very cool if you added this: an option for it to track your head’s direction, instead of your camera’s, and have the effect appear on the object based on the direction at which your avatar’s head was positioned/pointed at the object.

Aside from those suggestions, to reiterate: it is an amazing resource—exemplary; would love to see it constantly updated!

1 Like

Thank you for the feedback!

  1. I have pushed an update to fix this. Before, it would force the style to custom, so even if it was Default, it would auto-set it to Custom. I have changed this so now it only warns you.

  2. It is a good idea, I’m working on it, might take a while though.

  3. I can add this, but I don’t really see any use cases for it. I suggest modifying the module on your own, you just have to change the GetClosestFace function in the module to use the Head’s CFrame position instead of the Camera’s. So here, you’d just replace CameraPos with Character.Head.CFrame.Position.
    Screenshot 2025-01-31 at 3.18.02 pm

1 Like

image
I’m getting some duplicate prompts for some reason?

Here’s my code:




My proximity prompts have the tag
image

This is because you have initialised a Hologram twice. Hologram.InitailiseGlobally() initialises (and hence creates a new connection) for every ProximityPrompt. On top of that, you initialised the same prompt again, which creates another connection, making two detections. If you want to see how initialise globally is used, check out the uncopylocked place-file: Hologram Test

Hi,
This is nice, thank for sharing.

A few questions:

  1. Does this update real time, like lets say I have a chest in serverstorage and during the game it clones it and drops it into the workspace. Will it work? From the local script and definitions, my guess is not since that is where they are defined… or has the test place not been updated.

  2. Can the right side of the thing have a custom background image ID? Like lets say you want a picture, instead of words… or maybe even both…
    image

  3. What does the beam properties not have a texture ID? I tried putting one of mine in it…but it did not show up… what is the beam used for?

  4. Does it read through the workspace now to find all proximity prompts, instead of hard coded in the localscript? (Perhaps the test place is not updates for 11 days?

  5. I am wondering if it is still using the local script if it would perhaps better to have the attributes defined inside of the p p , then you could just read them , instead of hardcoded for every single one that is made (and or done game play live)

  1. could the outer blue color , have a feature where it could change or tween like to shades of blue or to one color or another, like kinda animated color changes ?
    (1)
  2. could the inner color blue that when you hold down E be a different color then the outer blue color and or have a gradient or fade from one color to the next? (2)
    image

Thanks

  1. This does not update in real time. If you clone and add a new proximityprompt into workspace, you’d have to initialise that one manually.
  2. Yeah, it can, you just have to take out the 3DPrompt model from the Hologram module and insert it into workspace. Then you can edit it as much as you want.
  3. There’s no such setting as a beam property. The beam is simply there for coolness.
  4. Yes, you can use Hologram.InitialiseGlobally() to convert every single Prompt in workspace.
  5. I mean, you can still change the colour during runtime, it’d just require the module. I don’t really see a point to having attributes.
  6. That is a very niche feature request, it’d be better if you coded it yourself. The module is super easy to understand, so it won’t be very hard.
  7. Same as #6.
1 Like

Woah, this is brilliant. I feel like I’ll use and customize it in the near future! Thanks for working on the resource!

1 Like

I’ve always loved the idea of 3D User Interfaces and also really liked the consept and implemented it into my project, however when I was testing with PS5 or PS4 gamepads I realised their button images are not supported, so I made it supported myself and wanted to share here:

First of all we identify all the KeyCode textures for the PlayStation gamepads from the local textures, I also made it so that we get 3x resolution ones for both because the default ones get kind of pixelated since the prompt image is still pretty big even though I made the model a bit smaller in my project. This is even more of a problem when you consider that most console players play on big screens.
--// Prompt Images
local XboxButtonImages = {
	[Enum.KeyCode.ButtonX] = "rbxasset://textures/ui/Controls/xboxX@3x.png",
	[Enum.KeyCode.ButtonY] = "rbxasset://textures/ui/Controls/xboxY@3x.png",
	[Enum.KeyCode.ButtonA] = "rbxasset://textures/ui/Controls/xboxA@3x.png",
	[Enum.KeyCode.ButtonB] = "rbxasset://textures/ui/Controls/xboxB@3x.png",
	[Enum.KeyCode.DPadLeft] = "rbxasset://textures/ui/Controls/dpadLeft@3x.png",
	[Enum.KeyCode.DPadRight] = "rbxasset://textures/ui/Controls/dpadRight@3x.png",
	[Enum.KeyCode.DPadUp] = "rbxasset://textures/ui/Controls/dpadUp@3x.png",
	[Enum.KeyCode.DPadDown] = "rbxasset://textures/ui/Controls/dpadDown@3x.png",
	[Enum.KeyCode.ButtonSelect] = "rbxasset://textures/ui/Controls/xboxView@3x.png",
	[Enum.KeyCode.ButtonStart] = "rbxasset://textures/ui/Controls/xboxmenu@3x.png",
	[Enum.KeyCode.ButtonL1] = "rbxasset://textures/ui/Controls/xboxLB@3x.png",
	[Enum.KeyCode.ButtonR1] = "rbxasset://textures/ui/Controls/xboxRB@3x.png",
	[Enum.KeyCode.ButtonL2] = "rbxasset://textures/ui/Controls/xboxLT@3x.png",
	[Enum.KeyCode.ButtonR2] = "rbxasset://textures/ui/Controls/xboxRT@3x.png",
	[Enum.KeyCode.ButtonL3] = "rbxasset://textures/ui/Controls/xboxLS@3x.png",
	[Enum.KeyCode.ButtonR3] = "rbxasset://textures/ui/Controls/xboxRS@3x.png",
	[Enum.KeyCode.Thumbstick1] = "rbxasset://textures/ui/Controls/xboxLSDirectional@3x.png",
	[Enum.KeyCode.Thumbstick2] = "rbxasset://textures/ui/Controls/xboxRSDirectional@3x.png",
}
local PlaystationButtonImages = {
	[Enum.KeyCode.ButtonX] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonSquare@3x.png",
	[Enum.KeyCode.ButtonY] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonTriangle@3x.png",
	[Enum.KeyCode.ButtonA] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonCross@3x.png",
	[Enum.KeyCode.ButtonB] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonCircle@3x.png",
	[Enum.KeyCode.DPadLeft] = "rbxasset://textures/ui/Controls/PlayStationController/DPadLeft@3x.png",
	[Enum.KeyCode.DPadRight] = "rbxasset://textures/ui/Controls/PlayStationController/DPadRight@3x.png",
	[Enum.KeyCode.DPadUp] = "rbxasset://textures/ui/Controls/PlayStationController/DPadUp@3x.png",
	[Enum.KeyCode.DPadDown] = "rbxasset://textures/ui/Controls/PlayStationController/DPadDown@3x.png",
	[Enum.KeyCode.ButtonSelect] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonTouchpad@3x.png",
	[Enum.KeyCode.ButtonStart] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonOptions@3x.png",
	[Enum.KeyCode.ButtonL1] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonL1@3x.png",
	[Enum.KeyCode.ButtonR1] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonR1@3x.png",
	[Enum.KeyCode.ButtonL2] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonL2@3x.png",
	[Enum.KeyCode.ButtonR2] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonR2@3x.png",
	[Enum.KeyCode.ButtonL3] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonL3@3x.png",
	[Enum.KeyCode.ButtonR3] = "rbxasset://textures/ui/Controls/PlayStationController/ButtonR3@3x.png",
	[Enum.KeyCode.Thumbstick1] = "rbxasset://textures/ui/Controls/PlayStationController/Thumbstick1@3x.png",
	[Enum.KeyCode.Thumbstick2] = "rbxasset://textures/ui/Controls/PlayStationController/Thumbstick2@3x.png",
}

Then we use UserInputService:GetStringForKeyCode() method to see which string does the UserInputService return for the Enum.KeyCode.ButtonX accordingly to the most recently connected gamepad. We use the ButtonX Enum because it is one of the couple KeyCodes which return different values for PlayStation gamepads:

if InputType == Enum.ProximityPromptInputType.Gamepad then
local str = UserInputService:GetStringForKeyCode(Enum.KeyCode.ButtonX)

if str == "ButtonX" and XboxButtonImages[self.Prompt.GamepadKeyCode] then
	self.KeyCodeImage.Image = XboxButtonImages[self.Prompt.GamepadKeyCode]

elseif str == "ButtonSquare" and PlaystationButtonImages[self.Prompt.GamepadKeyCode] then
	self.KeyCodeImage.Image = PlaystationButtonImages[self.Prompt.GamepadKeyCode]

end

Result:

Also besides everything I know this is somewhat an old thread but if you haven’t completely abondoned this project I really would love a built-in feature about this:

LockingProblem

Thank you so much for the feedback. I didn’t realise PS4 & PS5 had custom icons, will definitely implement them.

As for the feature, I totally forgot about it lmao. I’ll definitely work on it soon, just gotta get by my exams. Expect an update in a week or two, is that alright?

2 Likes

That’s good news! You can work on it whenever you want man keep up the great quality.

1 Like

Would be great if you could let us change its size and make the progress corners not rounded. (I’m sorry I didn’t know you could do this.)
Edit2: it couldnt get bodyfrontattachment

Great work on this!

1 Like

I had the same issue because my places avatar type was R6 and fixed that by changing

self.Beam.Attachment1 = Character:WaitForChild("UpperTorso", 10).BodyFrontAttachment or Character:WaitForChild("Torso", 10).BodyFrontAttachment

to this:

local Humanoid = Character:WaitForChild("Humanoid", 10)
		if Humanoid and Humanoid.RigType == Enum.HumanoidRigType.R15 then
			self.Beam.Attachment1 = Character.UpperTorso.BodyFrontAttachment
		elseif  Humanoid then
			self.Beam.Attachment1 = Character.Torso.BodyFrontAttachment
		end

When the :WaitForChild() times out it throws an error instead of returning nil in the original code, because when it times out it returns nil and it tries to get BodyFrontAttachment in nil.

[Edit:] I realised the first code i gave would error if the WaitForChild timed out so I edited it.

2 Likes

I just got the root attachment, which fixed it. Thanks for your help anyways!

2 Likes

Version 0.1.6

Fixes

  • R6 Beam Configuration has been fixed.

Upgrades

  • PlayStation Icon Support
  • Increased resolution for all gamepad icons

Now available on the Creator Store.

Thanks to @proturk_yt for the code suggestions.

1 Like