Need help understanding how to initalize a particular example

It all sounds a bit confusing. Maybe you would do well to post the code, without removing anything (if it’s always the same, it’s short), so that someone can possibly help you.

Oh, that’s what I did, I pasted only the particular line of code I am getting an errror on, and nothing else cause that’s the part that actually matters.

For example, beneath that particular snippet is this line that comes by default with the example, which compiles perfectly.

constructor TViewMain.Create(AOwner: TComponent);

If I made sure to define the TThirdPersonNavigation class in the same way as the TViewMain class, like use the same syntax formatting for both classes, then why the
heck is it telling me a method identifier is expected when it doesn’t expect it for this specific line?

And my point with the link is to show you that it tells me that is in fact the correct formatting for the constructor of ThirdPersonNavigation classes.

Maybe I didn’t explain myself. If you publish all the code you help others help you.

I was trying to point out that for the particular error I am getting, any other code you see is wrong won’t help with this particular line, cause that’s not the only error I am getting but it’s the very first, but as you wish:

{
  Copyright 2023-2023 Michalis Kamburelis.

  This file is part of "Castle Game Engine".

  "Castle Game Engine" is free software; see the file COPYING.txt,
  included in this distribution, for details about the copyright.

  "Castle Game Engine" is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  ----------------------------------------------------------------------------
}

{ Main view, where most of the application logic takes place. }
unit GameViewMain;

interface

uses Classes,
  CastleVectors, CastleComponentSerialize,
  CastleUIControls, CastleControls, CastleKeysMouse,
  CastleThirdPersonNavigation, CastleViewport, CastleScene,
  CastleCameras, CastleTransform, CastleInputs,
  CastleSceneCore, CastleDebugTransform;

type
  TMyThirdPersonNavigation = class(TCastleThirdPersonNavigation)
  protected
  procedure AssignAvatar;
  published
    SceneHumanLegs1, SceneHumanBase: TCastleScene;
    HumanBase1: TCastleTransform;
  end;

  { Main view, where most of the application logic takes place. }
  TViewMain = class(TCastleView)
  published
    { Components designed using CGE editor.
      These fields will be automatically initialized at Start. }
    LabelFps: TCastleLabel;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Start; override;
    procedure Update(const SecondsPassed: Single; var HandleInput: Boolean); override;
    function Press(const Event: TInputPressRelease): Boolean; override;
  end;

var
  ViewMain: TViewMain;
  MyThirdPersonNavigation: TCastleThirdPersonNavigation;

implementation

uses SysUtils;

constructor TMyThirdPersonNavigation.Create(AOwner: TComponent);

procedure TMyThirdPersonNavigation.AssignAvatar;
begin
  MyThirdPersonNavigation.AvatarHierarchy := HumanBase1;
end;

{ TViewMain ----------------------------------------------------------------- }

constructor TViewMain.Create(AOwner: TComponent);
begin
  inherited;
  DesignUrl := 'castle-data:/gameviewmain.castle-user-interface';
end;

procedure TViewMain.Start;
begin
  TMyThirdPersonNavigation.AssignAvatar;
  inherited;
end;

procedure TViewMain.Update(const SecondsPassed: Single; var HandleInput: Boolean);
begin
  inherited;
  { This virtual method is executed every frame (many times per second). }
  Assert(LabelFps <> nil, 'If you remove LabelFps from the design, remember to remove also the assignment "LabelFps.Caption := ..." from code');
  LabelFps.Caption := 'FPS: ' + Container.Fps.ToString;
end;

function TViewMain.Press(const Event: TInputPressRelease): Boolean;
begin
  Result := inherited;
  if Result then Exit; // allow the ancestor to handle keys

  { This virtual method is executed when user presses
    a key, a mouse button, or touches a touch-screen.

    Note that each UI control has also events like OnPress and OnClick.
    These events can be used to handle the "press", if it should do something
    specific when used in that UI control.
    The TViewMain.Press method should be used to handle keys
    not handled in children controls.
  }

  // Use this to handle keys:
  {
  if Event.IsKey(keyXxx) then
  begin
    // DoSomething;
    Exit(true); // key was handled
  end;
  }
end;

end.

MyThirdPersonNavigation: TCastleThirdPersonNavigation;

This was fine before, now you’ve changed it

constructor TMyThirdPersonNavigation.Create(AOwner: TComponent);

This alone means nothing, furthermore it is not declared in the class.

This is so weird… I know that it needs to be initalized with a constructor, and so I do the logical thing and look up what the constructor is for the class, and now you’re telling me it was unnecessary to add it? What the actual heck?

However, I will follow your most recent suggestion with removing the constructor and seeing what happens afterward.

Okay, I did that (which again makes no sense if you follow how it’s done for TViewMain!) and unfortunately am told on line (73, 40) “Only class methods, class properties and class variables can be accessed in class methods”.

Last time I checked, I did in fact declare AssignAvatar as a class method/procedure earlier of the particular class I want, so why the heck isn’t it working?

You should read more carefully :slightly_smiling_face:
I didn’t say it’s useless, but that written like this doesn’t make sense.

Which I will shout to the heavens is BS, because I showed you that the manual tells you to type word for word “Constructor class name.create(AOwner: TComponent);”. Look at the page I linked for actual proof!

On top of that, I just put it in the program in the same exact way that it works for TViewMain, but kept the sections seperate/organized, so the Third Person Navigation and Main procedures I declared using the same exact syntax, just in different parts/lines of the code.

If you didn’t click the link, the particular piece of code it shows you in the API for the constructor says, and I quote 100% word for word!:

constructor Create(AOwner: TComponent);

And I know for a fact you are supposed to format it logically as classname.constuctor because it’s done that way for TViewMain as well.

TCastleView to reference the actual class and not just the name specific to the program, to be more correct/precise about the actual part that matters.

Or I meant “constructor classname.create”, to be more accurate again.

Stupid mistypes

I know for the TViewMain constructor, there is a begin and end but I don’t see in
the API reference any explanations of why that is there, so I decided to omit it because
I thought it was irrelevant to the actual construction. Is your point that it is not though?

Again, if that’s the case it’s never explained very well for that particular class,
or for that matter it is never explained in the API page on TCastleView either!

For example on the TCastleView page, it tells you like this:

constructor Create(AOwner: TComponent); override;
Create an instance of the view. You willl typically create one instance of each view class (like TViewMain, TViewPlay) at the application initialization (e.g. in Application.OnInitialize callback), like

ViewMainMenu := TViewMainMenu.Create(Application); ViewPlay := TViewPlay.Create(Application);

Later you switch between views using TCastleContainer.View or TCastleContainer.PushView or TCastleContainer.PopView, like this:

Container.View := ViewMain;

See Managing Views | Manual | Castle Game Engine and numerous engine examples.

But nowhere is it explained why the begin and end functions are used, although I know in general begin means beginning of a block of code and end means ending, I just don’t understand why I would need that if I want to just to construct an instance of a class.

I think from what I can gather though, judging by the example in the code above with TViewMain, the logic behind it is that under the inherited section, you declare the actual thing you are initalizing from the game?

Eureka! That’s probably what you meant by the line by itself makes no sense, although the API pages don’t make that clear at all is my point.

Again, my point with the error report earlier was that the error doesn’t care if I add a beginning and end to it, it still stubbornly insists that I need a method identifier on that one line even though I made sure to use the correct syntax, and that’s where I object that is nonsense/BS.

Okay, from researching the “DesignUrl” line it seems that one can only use castle-transform files and nothing else, like it’s coded specifically for that, and it’s reserved only for TViewMain and isn’t a property of other classes.

I can tell though, researching the TCastleThirdPersonNavigation properties, that there is “Avatar” properties and “AvatarHiearchy” properties, as well as “AnimationWalk” properties amongst other things.

I would assume I should use “Avatar” rather than “DesignUrl” in my intialization, and probably use the “inherited” keyword as well, because I know that means it inherits properties from the actual class, like in the CastleViewMain initializer, if you didn’t “inherit” the DesignURL, it wouldn’t work.

Maybe I just lack appreciation of the nuances of classes, like still not enough knowledge, which is probably going to be michaelis’ next point though?

So all in all, my point is that by again, actually following the examples, which I know to do and not make random assumptions,

I get errors about how my class is structured, even though I made sure to be specific about formatting it in the same exact way as one that is known to work already.

It doesn’t make sense, for a non-programming math analogy, for a function to do different formulas/patterns depending on what its input is, it should always be 100% consistent through and through. Same deal for computer programming.