Toggle "bOwnerNoSee" ingame?

Hi,

I have currently a project that allow me to switch between a first person view and a third person camera view. I split the body and the head of my character to avoid camera issue with the head when the player is in first person view. Here is my setup :

		//Visible by player

		MeshBody = PCIP.CreateDefaultSubobject(this, TEXT("MeshBody"));
		MeshBody->AttachParent = RootComponent;
		MeshBody->SkeletalMesh = skMeshBody.Object;
		MeshBody->AnimationBlueprint = skAnimBody.Object;
		MeshBody->RelativeLocation = FVector(0.0f, 0.0f, -48.0f);
		MeshBody->RelativeRotation = FRotator(0.0f, -90.0f, 0.0f);
		MeshBody->CastShadow = true;
		MeshBody->bCastInsetShadow = true; 
		Components.Add(MeshBody);	


		//Invisible by player

		MeshHead = PCIP.CreateDefaultSubobject(this, TEXT("MeshHead"));
		MeshHead->SetMasterPoseComponent(MeshBody);
		MeshHead->AttachParent = RootComponent;
		MeshHead->SkeletalMesh = skMeshHead.Object;
		MeshHead->RelativeLocation = FVector(0.0f, 0.0f, -48.0f);
		MeshHead->RelativeRotation = FRotator(0.0f, -90.0f, 0.0f);
		MeshHead->bOwnerNoSee = true;
		MeshHead->CastShadow = true;
		MeshHead->bCastInsetShadow = true;
		MeshHead->bCastHiddenShadow = true; 		
		Components.Add(MeshHead);

The idea is to hide the head while keeping its shadow. Unfortunately, when I toggle the camera mode I would like to be able to see the head. I tried to change the value of the bOwnerNoSee boolean but it has no effect ingame (or because it’s outside of the constructor ?). I also tried other booleans such as the deprecated “bHidden” and some visibility functions without any success.

Is there an other way to toggle the visibility of my mesh component ?

You can set bOwnerNoSee in game, but you need to mark render state dirty so that the renderer will reflect that change.

MyComponent->bOwnerNoSee = true;
MyComponent->MarkRenderStateDirty();

Thanks a lot ! It’s exactly what I needed ! :slight_smile:

Dear Fabrice,

Hi there!

Have you tried

MeshHead->SetHiddenInGame(false);

you might want to also check out, from SceneComponent.h

/** 
	 * Set visibility of the component, if during game use this to turn on/off
	 */
	UFUNCTION(BlueprintCallable, Category="Rendering")
	virtual void SetVisibility(bool bNewVisibility, bool bPropagateToChildren=false);

	/** 
	 * Toggle visibility of the component
	 */
	UFUNCTION(BlueprintCallable, Category="Rendering")
	void ToggleVisibility(bool bPropagateToChildren=false);

My Method for Showing/Hiding Actor Skeletal and Static Mesh Components

I have a multiple-weapon system where I have a whole lot of components that I attach to and remove from my character’s root mesh depending on what weapon they should have equipped.

Since you made your character’s head into a separate component, you made your life very easy in the long run in terms of your goal :slight_smile:


Keeping the Head Shadow

Regarding your goal of keeping the head shadow, perhaps you could experiment with using an alternative head component that is using a completely 0 opacity material? If none of the lower-level workarounds seem to be working?

Then my code below could easily be used to toggle which head component you are using

I know it’s less-low level, but it could be a last resort :slight_smile:


To Make Head Disappear

Detach the component from the root whenever you want to hide it

if(MeshHead) MeshHead->DetachFromParent();

To Make Head Appear

Reattach the component any time!

 if(MeshHead) 
     {
      MeshHead->AttachTo(Mesh);
       //you may have to re-apply your relative loc and rot, or you can use a socket
       MeshHead->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -48.0f), FRotator(0.0f, -90.0f, 0.0f))
     }

or

MeshHead->AttachTo(Mesh, FName(TEXT("HeadSocketName")));  

One Function to Set Head Visibility

void AYourCharacter::SetHeadIsVisible(bool MakeVisible)
{
       //always check pointers
       if(!MeshHead) return;
       if(!Mesh) return;

       if(MakeVisible) 
       {
              MeshHead->AttachTo(Mesh);
              MeshHead->SetHiddenInGame(false);
              //you may have to re-apply your relative loc and rot, 
              //or you can use a socket
              MeshHead->SetRelativeLocationAndRotation(
                  FVector(0.0f, 0.0f, -48.0f), FRotator(0.0f, -90.0f, 0.0f));
       }
       else 
      {
           MeshHead->DetachFromParent();
      }

}

Let me know if this works for you!

Enjoy!


Rama

Thanks for the multiple solutions ! :slight_smile:

I can already say that ToggleVisibility()/SetVisibility() and SetHiddenInGame() are not working, I already tried them. I thought about detaching the component and respawning a new one but I didn’t succeeded yet with this method. With the few lines of code you write and might be able to, I will try that.

The opacity shader sounds like a nice idea, but I’m not sure that regarding performances (overdraw) and other features (such as the DOF) it will be the best.

you dont have to respawn the component after detaching it, you can just re-attach it as is :slight_smile:

I agree the opacity idea may not be the most optimal, but for your goal of keeping the shadow it might be a working solution

working solutions are generally better than no solutions :slight_smile:


Alternative Solutions Less Complicated

personally, I have 1st person setup in my game too, and I just move the camera to in front of the head, while staying in third person and keep its update speed fast so it never gets in the way of the head, I’ve had no problems with this method, and I get to keep the whole shadow :slight_smile:

unless your pawn is a Tyrannosaurus Rex who has a really big head and small arms that you still want to see, this method could work for you too

:slight_smile:

Well, I tried the attach/detach unfortunately this method seems to be ignoring the mesh offset and rotation that I give, making the placement of the head incorrect.

I think I will have to kill the mesh and create a new one each time unfortunately (I have to figure how to kill the mesh without crashing Rocket haha). I also can’t offset the camera as you suggest since I’m working on a realistic first person view. The forward offset would be too much noticeable.

Update 2: Here’s the code I use to add components mostly through c++, see my comments below for the additional steps to get this going in-game

//Royal Sword
	static ConstructorHelpers::FObjectFinder SkeletalMeshOb(TEXT("SkeletalMesh'/Game/Character/RoyalSwordSkelMesh.RoyalSwordSkelMesh'"));
	RoyalSwordAsset = SkeletalMeshOb.Object;
	
	//Was Sword Asset Found?
	if (RoyalSwordAsset != NULL)
	{
		
		//create new object
		RoyalSword = PCIP.CreateDefaultSubobject < USkeletalMeshComponent > (this, TEXT("RoyalSwordMesh"));
		Components.Add(RoyalSword);

		RoyalSword->SetSkeletalMesh(RoyalSwordAsset);
	
		//RoyalSword->AttachParent = CapsuleComponent;
		RoyalSword->bOwnerNoSee = false;
		RoyalSword->bCastDynamicShadow = true;
		RoyalSword->PrimaryComponentTick.TickGroup = TG_PrePhysics;
		RoyalSword->SkinnedMeshUpdateFlag = SMU_OnlyTickPoseWhenRendered;
		RoyalSword->bChartDistanceFactor = true;
		RoyalSword->bReceivesDecals = false;
		RoyalSword->CastShadow = true;
		RoyalSword->BodyInstance.SetMovementChannel(ECC_Dynamic);
		RoyalSword->BodyInstance.SetCollisionEnabled(ECollisionEnabled::NoCollision);
		
		//for fun
		//RoyalSword->SetForceWireframe(true);
		
		//socket name on character mesh
		RoyalSword->AttachTo(Mesh, FName(TEXT("RoyalSword"))); 
		RoyalSword->SetHiddenInGame(false);		
	}

Update: Very important suggestion for you I forgot to mention:

Sounds like something is fundamentally amiss here

Make sure you’ve recompiled your Blueprint in the editor after adding your head component in the C++ code, so that when you go to the components tab, the head mesh does not show up as MISSING or have any errors

I had problems getting all my armor components to show up on my warrior till I did the above after each new C++ code additions.

[/important suggestion]


are you saying that SetRelativeLocation is not working?

 MeshHead->AttachTo(Mesh);
 MeshHead->SetHiddenInGame(false);
  MeshHead->SetRelativeLocationAndRotation(
      FVector(0.0f, 0.0f, -48.0f), FRotator(0.0f, -90.0f, 0.0f));

there must be something fundamentally wrong with your component because I use SetRelativeLocation constantly for my camera boom, which is at the component level, literally calling it with every mousescroll input received (many times per second sometimes)

all these things that are not working, I suggest you start over with a new component to try and get perspective on these issues

because all the things I am offering as solutions do work for me, with the latest rocket build, and are core functions used by Epic,

I know when testing a beta there can be this feeling “is it me or is it the Beta”

but in this case I’m pretty sure your head mesh component is dancing to the tune of its own drummer


please do show us your .h file for how your head mesh is setup, and try starting with a different mesh


maybe adding the mesh directly in the Blueprint in the editor rather than in code?

try some fundamental different things cause something is definitely amiss here

let us all know how it goes!

Rama

PS: this is what I would do anyway, cause sometimes it’s just 1 line of missing code and other times it’s a larger issue

I don’t use any blueprint components, everything is done with static class in my constructor. Maybe the problem is here, since I use a static ConstructorHelpers::FObjectFinder.

Does SetHiddenInGame() works for you ?

I use a objectfinder too, but I can highly recommend blueprinting your character class!

I added my code I use for adding removable sword to my character’s hand to my answer above (better color formatting in a main answer/post)


You’re saying you are not using a blueprinted Character class?

if you are, then check its components for your headmesh

if you are not, please do blueprint your character class, and then click the compile button

there you will be able to tell whether your headmesh is getting properly added by checking the components tab

try running the game at least once after

  1. compiling your code with any changes
  2. blueprinting your character class in editor
  3. clicking compile button on the blueprinted class

then after running game, go check the editor again and make sure the character class components show your head component, compiling again if necessary


This may sound convoluted but it’s what I had to do to get all my armor parts to show up

I have more than 20 static/skeletal add/removable components added to my warrior mostly through c++ code, so that I can add/remove them at will depending on game conditions.

I say this mainly to point out that it is all very possible you just have to get the fundamental structure all setup

The above steps are what enabled me to do this

:slight_smile:

Rama

Works the same as it did in UE3, just using C++ equivalent.

Class construction:

    	// The characters 'mesh' will be their head.
    	// Hide it from anyone viewing this character from a first person perspective.
    	// Visible otherwise.
    	if (Mesh)
    	{
    		Mesh->bCastHiddenShadow=true;
    	}

YourChar::SetHeadVisibilty function:

    /**
     *  Show/hide head.
     *  Should be called each time this character is made the view target of a client.
     */
    void AYourCharacter::SetHeadVisibility(bool bIsVisible)
    {
    	if (Mesh)
    	{
    		Mesh->SetOwnerNoSee(!bIsVisible);
    	}
    }

Added to your camera class definition:

	/** Old Camera Mode */
	FName OldCameraStyle;

Add to your of YouCamera::UpdateViewTarget() function:

	bool bHeadVisible = true;
	
>>	Manipulate CameraModes, set bHeadVisible appropriately
>>	eg.
>>	else if (CameraStyle == NAME_FirstPerson)
>>	{
>>		// Simple first person, view through viewtarget's 'eyes'
>>		OutVT.Target->GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
>>		bHeadVisible = false;
>>	}
>>	else
	
	if (OldCameraStyle != CameraStyle)
	{
		AYourCharacter* YourChar = Cast(OutVT.Target);
		if ((YourChar != NULL) && (YourChar->Mesh != NULL))
		{
			YourChar->SetHeadVisibility(bHeadVisible);
		}
		OldCameraStyle = CameraStyle;
	}

I’d show some example pics except I am changing the way body parts are handled, so I’m currently just a floating head or shadow thereof :slight_smile: