x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Resize Actor/mesh depending on viewport size

Hello, I'm trying to resize an actor and it's mesh component according to the current viewport size. So here's what I'm doing:

First to get the viewport size and call the resize function:

 if (GetWorld())
 {
     FVector2D ViewportSize = FVector2D::ZeroVector;
     GetWorld()->GetGameViewport()->GetViewportSize(ViewportSize);
     Field->ResizeTo2DViewport(ViewportSize.X, ViewportSize.Y);
 }

Now in my ResizeTo2DViewport function I'm just setting the scale of the actor and it's mesh:

 void ACardField::ResizeTo2DViewport(int32 Width, int32 Height)
 {
     this->SetActorScale3D(FVector(Width / 38, Height / 38, 1));
     this->FieldMesh->SetWorldScale3D(FVector(Width / 38, Height / 38, 1));
 }

I'm dividing by 38 because unreal's units are equivalent to 1cm and 1cm is kind of 38 pixels. So i'm dividing the viewport size by 38 to convert it to units so i can set the scale. When i do that, the actor and the mesh fill the screen but even when i divide by 100 or higher number it keeps filling the whole screen.

What i want to do is to scale the actor and set some margins between the viewport and the actor, Imagine if it's a plane or a cube, i want it to fill the screen minus 10% of the viewport size to each side.

How could i do that? is my approach a good approach? What better solution would you recommend?

Product Version: Not Selected
Tags:
more ▼

asked Sep 07 '14 at 09:39 AM in C++ Programming

avatar image

DylanVelez
198 38 36 43

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

First of all, the call of SetWorldScale3D after SetActorScale3D should be kinda reduntant, asuming your FieldMesh is a subcomponent of your Actors RootComponent, or is itself the RootComponent.

ActorScale3D

Furthermore, the Scale Value should be a multiple of the Standard Value. Imagine this: Your Mesh is made by an Designer and is imported into UE4 such that it is 50cm*70cm*30cm (X*Y*Z). This will be his standard Value when placing into the World -> Scale = 1.

So if you call SetActorScale3D(1.5, 2, 0.5) on a Actor with this Mesh Component, your Mesh will be 75cm*140cm*15cm (50*1.5, 70*2, 30*0.5).

I would suggest you, to take any reasonable Screensize Value as your Standard Value.

For example let FVector2D(640.f, 480.f) be your standard Value. Now just divide the Components (.X, .Y) of your actual ScreenSize by the Components your Standard Value and you will get appropriate Scale Values.

Please let me know if this works, or if anything is total bullshit i just wrote.

more ▼

answered Sep 07 '14 at 04:57 PM

avatar image

RiumEqua
114 8 3 9

avatar image DylanVelez Sep 07 '14 at 10:11 PM

Yeah this totally make sense but i seem to be facing problems as to my logic because i'm not getting the desired results.

First i'm getting the viewport size as i was doing in the first place:

 if (GetWorld())
     {
         FVector2D ViewportSize = FVector2D::ZeroVector;
         GetWorld()->GetGameViewport()->GetViewportSize(ViewportSize);
         Field->ResizeTo2DViewport(ViewportSize.X, ViewportSize.Y);
     }

After that, to resize the actor I'm trying to get the actor bounds (the real size in units and taking that as my standard value, so i have the following:

 FVector Origins;
 FVector FieldSize;
 this->GetActorBounds(true, Origins, FieldSize);
 FieldSize *= 2;
 FVector NewScale = FVector(Width / FieldSize.X, Height / FieldSize.Y, 1);
 this->FieldMesh->SetRelativeScale3D(NewScale );

So far so good, the actual scale is the same as the viewport, but when i try to set the scale to that of the viewport minus for example 20% it's still taking the whole screen this->FieldMesh->SetRelativeScale3D(NewScale * 0.8);

the above line doesn't work, for it to leave space between the viewport and the mesh i have to multiply for something like 0.4 and that doesn't seem to make sense to me.

avatar image RiumEqua Sep 09 '14 at 01:35 PM

Where do you implement this code? I would guess in BeginPlay()? If you implement it instead into some tick function (to resize the Actor on Game Runtime), then the GetActorBounds would be fatal, because it changes everytime when SetRelativeScale3D is called.

Another thing i can see is, that you divide the Width and Height directly by your FieldSize.X and Y. This can not work out... Here is why:

Every Vector is only meaningfull with respect to some basis (origin) which span his vectorspace. The basis for FieldSize is the World Origin of your Map with the orthogonal unit Vectors (length one UE = 1 cm) X, Y and Z. The basis for Viewportsize on the other hand is the upper left (i think) corner of of the viewport with the orthogonal unit Vectors (length one pixel = ?? cm).

Because their basis is not the same, you cant just simply divide them and get a meaningfull result.

I would recommend that you make 2 new UPROPERTY in your actor which are StandardWidth and StandardHeight (both represent Vectors w.r.t. your screen) and use them as your standard values. With these Propertys you can play around in the Editor to Resive the size you want on your viewport.

Then, if you scale your viewport everything should just scale fine.

avatar image RiumEqua Sep 09 '14 at 01:48 PM

Note that these Standard Values will not represent the actual size on your viewport at all.

You can also look at ProjectWorldLocationToScreen (is a function inside APlayerController) with this function and GetActorBounds you could possibly get the real pixelsize of your actor, which than could be resized in such a way that it will allways be some proportion of your viewportsize.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question