Need Help Understanding how to Assign a Transform as an Avatar of a Third Person Navigation Camera, After Following Instructions

Okay, so I tried figuring out how to correct the problem myself because you basically already specified what it was (the camera being orthogonal to a side vector of the avatar), by rotating the camera to face the player correctly, and it actually works!

So yeah, I think I am all set for that one now, all I have to do now is actually make the character moveable as it currently isn’t right now, but I think those details I can figure out on my own given that I know what a procedure is conecptually, as well as how to assign it a specific function/duty, and all of that.

Okay, actually I was only partially right; when I try changing “Distance to Avatar Target” property of the third person navigation, I don’t get any changes and I still get the camera stuck between the character’s legs, after I point the camera in the correct direction.

I will wait patiently for your solution instead, as I am assuming there is something extra I am missing that I don’t understand how to figure out myself.

Sorry for delay, it took me some time because I decided to implement a new feature, not related to your question in this thread, but I think it will be useful to you anyway: to easier navigate in a larger design like yours I implemented ability to easily find component by name.

  • You can now use editor menu item “Edit → Find” (Ctrl + F) to show / hide a text box where you can type component name.

  • Typing a name there, like “camera”, will search and select the first component matching given name (as a substring, so e.g. it will find Camera1).

  • Pressing F3 (or using menu item “Edit → Find Next”) searches for next occurrence.

  • This should allow to move around in a larger design much easier. E.g. you can search for “camera” or “submarine” to easily select components with matching names.

  • The feature will be available in a few hours in downloads on Download | Castle Game Engine . To know when it’s available, you can observe this page: Comparing snapshot...master · castle-engine/castle-engine · GitHub . When it will no longer show the commit titled “Find (Ctrl+F) and Find Next (F3) in editor…” it means that given feature is available now in editor. You can then download the latest engine version and try it out.

This post is a bit off-topic – I know it’s not a feature related to your question. But I hope it will be useful to navigate a larger design for you.

I will investigate and answer the actual question here (how to use 3rd person navigation so it doesn’t result in blank screen or block) soon, in next post.

I have a few notes, but I also discovered some things I want to improve in the engine. Your AvatarTransform has a rotation for which our code was not prepared for – making what we like to consider “direction” match “up”. I’m adding additional properties to enable configuring it nicely in the engine.

I have a working camera “orbiting” around and zooming with mouse wheel around Sandy’s head. I still have to investigate why actual movement (AWSD) doesn’t work out-of-the-box, probably also because of direction / up mixup.

Hold on tight, I’ll get back to this thread with detailed answer tomorrow!

Yes, I intentionally did it using a transform with multiple scenes because as I discussed earlier in another thread, I cannot seem to animate mutliple parts independently of each other, like a human skeleton works, for single scenes.

Do you know if there is a way to do, using single scenes, something like animating the arms shooting while the legs run from seperate animations, or is there no way to do that?

There is a way to play multiple animations on one 3D model, see example examples/animations/simultaneous_animations_one_scene/ , castle-engine/examples/animations/simultaneous_animations_one_scene at master · castle-engine/castle-engine · GitHub . It requires to design animation in a special way (each animation must “touch” different bones). Frankly I wouldn’t advise you to go with this change – multiple model parts should be good also, and you have them already set up, you will just have to handle SetAnimation.

And as for avatar transformation, that’s something I will want to fix on CGE side, I’m working on it. We should cope with any AvatarTransfom initial transformation on CGE — it’s a bug that we don’t by default. I’ll get back here when it’s done.

I tried matching the “Up” and “Direction” myself, but unfortunately one changes automatically when I change the other so they end up never being exactly the same.

I assume this is intentional for the current public version, and your aim is to correct it later.

Okay, that makes sense too about the avatar transform thing. Thank you for explaining that it was a bug and not something wrong I am doing! :slight_smile:

This is intentional and correct, not planned to change. Direction and Up must be orthogonal, changing one (sometimes) must change the other. In total, they both actually just set Rotation. See the Direction docs ( Castle Game Engine: CastleTransform: Class TCastleTransform ) to understand how it works.

Anyhow, we should cope with any rotation for AvatarTransform. I’m investigating/fixing this in CGE, I’ll get back here.

Okay. Thank you for clarifying that as well.

Do you know how you got the camera to work correctly?

I know I can just set the animations manually, which you explained how to do already using the overriden SetAnimation function, as well as move the character manually using the appropriate code (like move by a specific Vector3 when the player presses a key).

Or are you stating in the next version and not my current version the camera will work correctly, IE you are developing the version right now and all I have to do is sit tight and wait patiently?

I am investigating and will get back here. I’ve done 1 improvement, but it doesn’t solve the actual issue.

So I’m saying that “I don’t know yet” :slight_smile: But I’m investigating and will get back here – with either comments what to change in your project, or fixes to CGE to behave better for your use-case, and most likely: with both. For now please wait patiently, I’m working on it right now.

The goal is to have TCastleThirdPersonNavigation that works (initial camera sensible, and avatar movement) and that is intuitive to use.

Oh, that makes sense - you need more time to investigate in more detail about what exactly is wrong, and there isn’t a definite answer about what exactly I need to do yet.

So I know to just wait patiently as you continue the great work :slight_smile:

1 Like

Sorry for delay. I got sick last week and am still recovering. But I have answers.

  1. First of all:

    Onward to describe things I found that needed fixing in your project:

  2. Your application had effectively 2 instances of TCastleThirdPersonNavigation. One is ThirdPersonNavigation, the one you have designed in editor, and another is ThirdPersonNav, the one you have created at run-time. They will both try to control the camera – it will not work OK.

    I did mention this before in the past threads (that you will have to configure all your navigation at run-time), but all in all I think that this approach is just too difficult. I decided to simplify it for you by making it easier in the engine – you don’t need to create TCastleThirdPersonNavigation descendant anymore.

    So, new advise: just remove your TThirdPersonNav from your code. Remove the ThirdPersonNav local variable from Start. Remove also the global ThirdPersonNav, this was unused (only confusing to humans, and not used by the compiler for anything since you obscured it by local variable). Remove these lines from Start:

    ThirdPersonNav := TThirdPersonNav.Create(FreeAtStop);
    MainViewport.InsertBack(ThirdPersonNav);
    

    Instead, use the one and only one navigation you made at design-time: ThirdPersonNavigation. To configure animations, assign in view Start:

    ThirdPersonNavigation.OnSetAnimation := @NavigationSetAnimation

    and define in your TViewMain class a private method

    procedure TViewMain.NavigationSetAnimation(const Sender: TCastleThirdPersonNavigation;
      const AnimationNames: array of String);
    begin
    end;
    

    Forget about creating descentdant of TCastleThirdPersonNavigation, this is too difficult. You will only need to implement the method NavigationSetAnimation, which can be a method inside your existsing class TViewMain, this should be much simpler.

    A sample implementation of NavigationSetAnimation (but this is only a sample – you have to finish this, only you know the details of what animations you have on your model and when to play them!) would be to control SceneLegs animation based on whether the animation is idle or not. For this, put

    SceneLegs: TCastleScene;
    

    in the published section of your TViewMain. Implement NavigationSetAnimation like this:

    procedure TViewMain.NavigationSetAnimation(const Sender: TCastleThirdPersonNavigation;
      const AnimationNames: array of String);
    begin
      { Example implementation that merely sets animation on SceneLegs,
        to either TORSO_IDLE or TORSO_RUN.
    
        Use castle-model-viewer (formerly view3dscene),
        https://castle-engine.io/castle-model-viewer,
        just double-click on MD3 file from CGE editor, to see available animations
        (in "Animations" panel).
      }
      if AnimationNames[0] = 'idle' then
        SceneLegs.AutoAnimation := 'TORSO_IDLE'
      else
        SceneLegs.AutoAnimation := 'TORSO_RUN';
    end;
    

    If this sounds difficult, remember you have a working example where I did all above from Various fixes described in forum thread by michaliskambi · Pull Request #2 · JPF12141999/Toy-Story-2-Ripoff-Game · GitHub .

  3. You need to set PreciseCollisions to true on Scene1. The camera (used by TCastleThirdPersonNavigation) is using this (old) system for collisions. See Physics | Manual | Castle Game Engine .

    This need may be removed in the future Castle Game Engine versions. Your scene (Scene1) already has TCastleMeshCollider, this is good and shall be enough. But for now, you also have to set Scene1.PreciseCollisions to true. (it’s just a checkbox in the editor, just click it, you don’t have to actually set it using Pascal code.)

    Doing this unblocks normal camera orbiting around the avatar and zoom in/out using the mouse wheel.

    As a bonus, this also makes working in editor better. Setting PreciseCollisions to true on Scene1 allows to easily pick objects when working in CGE editor.

  4. As your AvatarTransform has non-standard rotation, you have to set

    AvatarTransform.Orientation := otUpZDirectionX;
    

    from TViewMain.Start method in your code. Also declare

    AvatarTransform: TCastleTransform;
    

    in the published section of your TViewMain. As you will see, this solves the major problem with both camera orbiting and avatar movement. The default orientation assumes you have “up” in +Y and “forward” in +Z, which was completely wrong and resulted in all sorts of weird transformations for your model. Using otUpZDirectionX makes almost everything OK :slight_smile:

  5. You didn’t call Init method of the navigation. See the API docs ( Castle Game Engine: CastleThirdPersonNavigation: Class TCastleThirdPersonNavigation – “Call Init once the parameters that determine initial camera location are all set.”), we explicitly require calling this method to make initial camera sensible.

    In the end, this is Start method contents that work for me (note that this code block may have extra scrollbar, be sure to see it all):

    procedure TViewMain.Start;
    begin
      inherited;
    
      { Critical to make camera orbiting around and movement of avatar
        to follow proper direction and up.
        In the AvatarTransform local coordinate system,
        the avatar is moving in +X, and has up (head) in +Z. }
      AvatarTransform.Orientation := otUpZDirectionX;
    
      ThirdPersonNavigation.MouseLook := true;
      ThirdPersonNavigation.OnAnimation := {$ifdef FPC}@{$endif} NavigationSetAnimation;
    
      { Configure parameters to move nicely using old simple physics,
        see examples/third_person_navigation for comments.
        Uncomment these if you decide to move using "direct" method
        (when AvatarTransform.ChangeTransform = ctDirect,
        or when AvatarTransform.ChangeTransform = ctAuto and
        AvatarTransform has no rigid body and collider). }
      AvatarTransform.MiddleHeight := 0.9;
      AvatarTransform.GrowSpeed := 10.0;
      AvatarTransform.FallSpeed := 10.0;
      // a bit large, but it is scaled by AvatarTransform scale = 0.1, making it 0.5 effectively
      AvatarTransform.CollisionSphereRadius := 5;
    
      ThirdPersonNavigation.Init;
    end;
    
  6. You put TCastleMeshCollider on the avatar (as behavior of AvatarTransform). This is not good for a moving object – TCastleMeshCollider is static (see Physics | Manual | Castle Game Engine , “”“TCastleMeshCollider (using this collider forces the body to be static)”“” ).

    It also had Mesh unassigned, making it additionally not useful.

    To resolve collision with avatar using physics, you can use physics collider like TCastleBoxCollider. You can use “Change Class” context menu option in CGE editor to do this. See also how CGE examples/third_person_navigation has it set up. As in that example, set also LockRotation on avatar to [X,Z], to only allow avatar to rotate around Y (world up axis).

    … But actually, I will propose a different solution now:

    Remove from AvatarTransform rigid body and collider. This will make the avatar not affected by physics, and it will be controlled by TCastleThirdPersonNavigation directly. This is the simplest solution for avatar. You could alternatively explicitly request it setting AvatarTransform.ChangeTransform to ctDirect.

    We have alternative navigation components coming in Castle Game Engine, since a few months now, with better physics integration. Right now, with TCastleThirdPersonNavigation, it seems easier to just recommend to not use physics for 3rd person avatar. (the physics can still work in the world otherwise, of course, just not for the avatar itself.)

  7. Default speed is slow, it is applied in local transformation system and your AvatarHierachy has scale = 0.1. Set MoveSpeed to 10 on ThirdPersonNavigation to make nice speed.

Additional notes (not really related to navigations):

  1. There are still some images that are being referred to using absolute paths that only work on your computer: file:///C:/Users/Joshua/Pictures/toystoryimages/level1_background/front.jpg . Seems like they are at background. They will not work on other systems, refer to them using castle-data:/...

  2. There are a lot of textures that don’t have power-of-2. They are resized to have power-of-2 at runtime (this is necessary to have something called “mipmaps” which makes textures in 3D look good regardless of from what distance/angle you view them). You can make things load much faster by already providing textures in sizes that are power of 2.

    Note that your textures are embedded in GLB files, so admittedly the log is a bit obscure:

    Textures: Resizing 2D texture "" from 474x316 to 512x512
    Textures: Resizing 2D texture "" from 474x632 to 512x1024
    Textures: Resizing 2D texture "" from 474x632 to 512x1024
    

    We tell you that size is wrong, but we don’t tell what is the texture, all textures are named “” in this case. I know this is not very helpful, I’ll think how to improve this in the future.

    Note that, while we handle GLB, we generally advise to use separate glTF + textures (see Blender | Creating Game Data | Castle Game Engine ), then textures are in separate files (like png, jpg) and you can easily see what is resized.

  3. You have some Wavefront OBJ with invalid materials, Warning: Wavefront material "cannon_puffer_jf" specifies specular exponent (Ns) as zero, ignorin .

  4. There are a lot of warnings Warning: Using non-uniform scale 5 1 5 for physics body (collider MeshColliderOil) is not fully supported.

    Do not ignore them, unless you don’t want to use physics in the end. You really cannot use such scale with physics bodies, physics engines do not cope with non-uniform scale and results are undefined.

    “Non-uniform” means that scale is different in different directions. E.g. scale “2 2 2” is OK (uniform), scale “2 1 2” is not OK (it is not uniform).

    You have to scale objects in a different way. If this is on a mesh, then mesh vertexes have to be scaled (in Blender: “Apply Scale” operation does it). If this is a TCastleBox, then you should scale it by changing TCastleBox.Size instead of Scale. There is no universal solution, it depends on what you are scaling, but it is important that you avoid non-uniform scale on objects that are used with physics.

    This is a common limitation of physics engines.

  5. In your new project upload, you didn’t add .gitignore file. I recommend you add it, to avoid committing by accident stuff that should not be committed. Sample contents of .gitignore:

    # Files ignored by GIT version control
    
    # Build tool (and compiler) temporary output
    castle-engine-output
    
    # Unix executable
    toy-story-2-like-game
    # Windows executable
    toy-story-2-like-game.exe
    # Library files placed alongside Windows executable
    *.dll
    # Auto-updated by CGE tools when compiling Windows build
    castle-auto-generated-resources.res
    
    # May contain secret data (your Android keystore username and password)
    AndroidSigningProperties.txt
    
  6. Looking at commit logs, you seem to do a lot of things to “file upload” on GitHub. That’s an option, but it’s not very convenient way to synchronize your project in the long run. Use rather a proper “GIT client”, I recommend https://desktop.github.com/ which has a good set of features while maintaining a simple user interface.

  7. Submarine component, child of Workshop_Submarine, has rotation with zero axis but non-zero angle: 0 0 0 deg(90). This is causing warnings

    RotatePointAroundAxisRad called with rotation Axis = zero...
    

    You can fix it by just setting Submarine rotation to exact zero, 0 0 0 0. Pratically, you can also ignore this warning, it doesn’t mean any real problem in this case. (I’ll think whether to maybe just ignore these things in next engine versions, i.e. be silent instead of making warning.)

Thank you so much for all the useful feedback and suggestions! I will implement them to the best of my ability.

I would believe needing to Init a ThirdPersonNavigation is crucial to any kind of ThirdPersonNavigation, and not just one with a Transform with multiple scenes, like one that has only one Scene like in the official examples would also need to be initialized as well?

Indeed, Init is necessary for all cases of TCastleThirdPersonNavigation usage. Examples call it, e.g. this is where examples/third_person_navigation/ calls it: castle-engine/examples/third_person_navigation/code/gameviewplay.pas at master · castle-engine/castle-engine · GitHub .

Okay, awesome! Thank you for the clarification as well :slight_smile:

And I know as always the best way to learn is to just use my common sense and read what the heck the example says I should do in the first place, like always.

Okay, I merged the fix into the Github project like you said I should, and tested it the way it is - the collision box can’t go in a certain radius sphere in the center inside the treedome, despite it being able to walk literally everywhere else in the level, treating any solid walls like a joke.

Does anyone know why this is, perhaps michaelis who has so thoughtfully helped me out with every weird thing I ran into so far?

I read in his latest post about still needing to implement better physics, so I suppose this probably is something that will be addressed later on and all I have to do is sit tight and wait patiently?

I tried implementing a collision box on the Avatar Transform, using the same method I did for the other collision boxes (so right click on the parent object and add a physics box collision) but got tons of lag and a crash with this error message:

Thank you very much in advance :slight_smile:

Okay, I tried again with the collision box and rigid body method, this time by doing it with the exact numbers that the third person navigation does and the exact type of collision it uses (Capsule rather than Box; I know it should work the same in theory with the only difference the shape of the collision, but just wanted to be 100% precise about following directions),

But still got lag and a crash with a black screen error message, as well as tons of warnings about “Warning: AvatarTransform:TCastleTransform: The existence of this TCastleTransform changed multiple times in a single frame and it uses physics (has TCastleRigidBody and TCastleCollider behaviors). This is not good for performance and right now can even cause physics simulation crashes, esp. when TCastleCollider.AutoSize=true and animation may change LocalBoundingBox. Avoid changing the Exists of physical objects multiple times in a single Update.” verbatim/exact words.

Do I perhaps just have to wait patiently for better physics handling, or am I doing something wrong I am not aware of?

I would assume it is because I am using physics on a Transform rather than a Scene, as the error message suggests, and as your post stated I am not supposed to use physics on a Transform yet because you are still working on that, so I will just not use physics for now until you have the version with better physics released.

For physics to work with avatar, you would have to change ThirdPersonNavigation.ChangeTransform to ctAuto. But this goes into other problems, so I would not recommend it.

I can see the problems with collisions in the current version. Hm, I’m not sure yet what is the cause – this should not happen. I’ll investigate and get back here.

If you can share the source model (in Blender maybe?) of the level, this would make it easier to experiment for me. (but it’s not necessary, I can do some necessary experiments anyway.)