Get parts in front of another part?

So I’m making a recreation of the game Portal and previously the portals I had programmed used Viewports to display the other side of the portal. However, viewports aren’t great for this purpose being as they need to render large areas quickly and in realtime, plus they’re lower quality.

My new system is this: Clone the entire map, position it to the corresponding portal then delete any parts that aren’t in front of the portal.

Here is a testing room I designed that has portals placed in a way that would demonstrate this well:

The portals work correctly and are positioned fine, but here’s the issue: with a room like this, the cloned map appears overlaying the current map because some parts that shouldn’t be visible are visible.

Example:

Those dark grey parts are walls that shouldn’t be visible, but they are.

This is what I want to do:

Check through the parts of the map and see which ones are visible (raycasting) ✓
Check if parts are a certain distance away, if they are too far away delete them ✓
Check what angle the parts are from the portal, taking into account the player’s camera angle as well :heavy_multiplication_x:

I have looked this up on the DevForum before, to no success. I did try using this method I read up on:

local dir = (script.Parent:GetPrimaryPartCFrame().p - otherPart.CFrame.p).unit
	
local angle = math.deg( math.acos( otherPart.CFrame.LookVector:Dot(dir) ))

However I used this for a Turret to create peripheral vision and it said that my player was visible behind the part (angle behind was the same as in the front)

How would I be able to get the angle of a part from my player’s character, and from the front of another part?

1 Like

Hey Blok,

I believe the way you’re trying to do it will be pretty lag inducing/straining for the client and will only work in specific environments. I understand that you don’t want to use viewportframes, due to their lower quality, however It’ll work better in this situation.

However, you’re in luck as egomoose (the maddest lad) has already created a system for this and its world is available for download! In fact, I have the link right here.

Sadly though, if you still want to continue with the world duplication, be prepared for lag.

2 Likes

I believe the OP has the rendering figured out alrdy, and is now simply best trying to figure out how to cull the world in the viewportframe.

Efficiency will always be somewhat of an issue, but for small maps like in portal i believe it can be reasonably done with the right technique. Of course that’s the whole point of this post though; what is the right technique?

So a few options and considerations… (I apologize in advance as im typing this on mobile so i cannot draw any pictures which i think would be of great benefit).

The first is do to a frustrum cull. That is find the exact geometric bounds that the camera can see through the portal and clone every part inside it. This is probably the worst option we could pick even though it sounds like it would be most accurate. Firstly, it would require us to do this calculation everytime our camera moved which is frankly wasteful. Secondly, in come cases depending on the map a part that may be in the frustrum may actually come between the viewportframe camera and the window part thus blocking the view (this is the same reason we can’t just clone the whole world)

Our other option is to split the world with a plane. This is more efficient as it means we dont have to recalculate and clone every frame, but we still have the potential view blocking problem. So this is truly only a half solution.

The question that needs to be answered here is how you could slice objects in half intersecting with that plane. CSG is an option but it may not be viable speed wise. You could try the glass hack, but it’s as stated a hack that’s supposedly going to be fixed one day.

I don’t know the solution, but i believe this is the discussion you’re looking for.

2 Likes

Thanks for the info! If I really have to, I can alter the scripting to make it non - realtime to reduce strain (maybe 0.5 - 2 seconds, or more)

The glass hack sounds interesting, haven’t heard anything about it before.
I did think about using CSG but wasn’t sure how I would implement it, especially since they can be kinda hit and miss at times. Also, I don’t think CSG at runtime is a thing yet, correct me if I’m wrong.

Ok, thanks for the link! I’ll check it out tomorrow when I can use my computer again (on mobile rn)
If it does lag a lot, and the worst comes to the worst, I’ll just make it non realtime and only update when portals move.

Okay, I’ve been messing around with SubtractAsync() to see how it works, and to be frankly honest I hate it. It doesn’t seem to work properly for me at all. Half the time it errors, doesn’t tell me when it errors / what the error is, or the results are just… not right. It doesn’t feel like its stable enough or flexible enough to be used in the way I want it to.

One method I was trying to use before was to split the whole map into 1x1x1 or 2x2x2 cubes as apposed to solid walls, however this method would be an awful one as the amount of calculations needed would be insane, plus editing maps would be a pain in the neck. Also, I tried this and it lags a lot more than just a few parts.

I’m not really sure how to solve this issue. I really don’t want to resort to ViewportFrames, but I feel like I might have to unless I can get this CSG stuff to work, which I can’t seem to be able to.

This is what I have so far. It’s good, but not great.

Essentially how this works is it copeis the entire world and moves it to the other portal. It scans all the parts and calls camera:WorldToViewportPoint on them to see if they are visible, if they are’nt, delete them. If they are, it will do a raycast to check it is visible (Not yet implemented)

However, The WorldToViewportPoint method means larger parts like the walls and floor may be invisible if the center position is off screen but a part of it is on screen. You can see this in the video when I turn my camera standing next to the orange portal, the center of the portal goes off screen so the entire environment behind disappears too.

Any ideas how I can use a better alternative to WorldToViewportPoint so I can keep parts visible even if they are technically off screen, or a way to check the angles of those parts to see if they are visible through the portal only?

Also, if anyone can help with a CSG method please let me know, I really don’t understand how the CSG method works

Ok, I’ve decided to scrap my approach as your method is 10x better, and I’m going with the Viewport method. Also, is there any way to fix the blurriness that happens up close? I’m ok with it if there’s no way to fix it.

I’m not sure you could eliminate the blurriness entirely, but you could reduce it by adjusting the portal part size to better fit your viewport and thus squeeze out more resolution.

We discuss it in the portal thread, but nobody in the thread has implemented it yet.

1 Like

Ok, it’s not too big of a deal so I don’t mind.

Also, I’ve been trying to do this for a while but is there a way to set the Portal positions through a specific CFrame and not the mouse.hit? I’m trying to make manual portals but whatever I do seems to make the portals face the wrong way and if they face the right way the room disappears and only my player is visible.


Here I moved the portals in game with the move handles and you can see its not right. The player in the blue portal is in the floor and the orange portal room isn’t visible.


You can see the room is there but its off by a large distance

Is there a way I can set their CFrames manually so they are accurate and not where they used to be?

2 Likes

I’ve been looking at this for some time now and it doesn’t seem to ever work when I reposition the viewports. The camera acts as though it hasn’t moved properly and the room is offset by a large distance. @EgoMoose how would I be able to position the portals to a CFrame that isn’t my mouse?