Recent

Author Topic: Castle Game Engine (Cross Platform) - Need Help with Drawing a Raycast Vector  (Read 12861 times)

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Thank you for that reminder - I just meant the general idea in my posts, and didn't read through what exactly the keyboard shortcut you gave me was, but that reminder is useful because CTRL + C will probably do something different than what you actually said word for word.

Lansdowne

  • New Member
  • *
  • Posts: 32
now I am getting errors about all the functions being declared, starting on line 60, about being unsolved forward declarations, even though I remember the way the example initially was, and by following all the other examples, that this is the way you are supposed to define the procedures to use later on in the code.

Why is this telling me the forward declaration is unsolved on each and every single line in that particular section (lines 60 to 77, ignore everything before and after)?

Looking very briefly at that code:

The procedure that starts on line 188
has begin on line 213
and end; on line 250.
Then on line 252 you have
end.

That is end. not end; and that should signify the end of your program.

I suppose the compiler ignores everything in the .pas file after that end.. Which is why it has not found your event handler procedures.

There are one or more further instances of end. later in the code you displayed.

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
This is exactly what I was guessing at myself; however, I stated earlier that when I don't include the extra "end."'s like that with the period, I get a missing period error. Does anyone know why this is, given that, again like I said earlier, the periods weren't included in the official examples until the very last line, and this is probably why?

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Yeah, same exact problem when I try about missing periods. I get a period expected but semicolon found error on line 252, after I replaced the period with a semicolon, even though the examples I saw, like the platformer game or FPS game, when you open its gameviewplay.pas, have semicolons before function declarations and compile and run just fine.


What gives? Code rules in general shouldn't only work in one example and not work in another example; they should apply the same always, regardless of what language you are using.

Lansdowne

  • New Member
  • *
  • Posts: 32
If you simply delete the end. in 252, at least it will compile the next batch of lines.

But the begin...end block starting 239, and the else at 237, look out of place - as if something is missing.
« Last Edit: February 18, 2024, 01:22:14 am by Lansdowne »

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Okay, so maybe the problem is a redundant amount of "begins" and "ends", like I know I had before? That makes a ton more sense and solves everything about that problem, I think, but I will have to try first.

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Now it compiles and runs correctly, but again the line to check if the player is touching the ground still isn't drawn.

For anyone who wants to help me understand how to draw the raycast vector I am using to check the ground, open the gamemymesh.pas I have in my project that I posted in the first post of this thread, and then open the original version of the code in the "test rendering opengl capabilities" in the "research special rendering methods" folder/subdirectory, and compare the two, making sure to read every last line.

Can someone please explain to me why the rendering doesn't work, even after I make sure to follow the way it was in the original example to a T, just with a slight difference of having custom parameters for one of the procedures that wasn't there initially (SetVertices in particular)?

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
For reference, this is what the code looks like in full, omitting no lines at all, for gamemymesh.pas in my project:

Code: Pascal  [Select][+][-]
  1. {
  2.   Copyright 2023-2023 Michalis Kamburelis.
  3.  
  4.   This file is part of "Castle Game Engine".
  5.  
  6.   "Castle Game Engine" is free software; see the file COPYING.txt,
  7.   included in this distribution, for details about the copyright.
  8.  
  9.   "Castle Game Engine" is distributed in the hope that it will be useful,
  10.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12.  
  13.   ----------------------------------------------------------------------------
  14. }
  15.  
  16. { TCastleTransform descendant that renders unlit mesh using TCastleRenderUnlitMesh. }
  17. unit GameMyMesh;
  18.  
  19. interface
  20.  
  21. uses SysUtils,
  22.   CastleRenderPrimitives, CastleBoxes, CastleTransform;
  23.  
  24. type
  25.   { Mesh rendered using TCastleRenderUnlitMesh, not using TCastleScene.
  26.     This is not generally advised, TCastleScene has much more features
  27.     and is easier to use than TCastleRenderUnlitMesh.
  28.     We do this only to test TCastleRenderUnlitMesh with rcForceFixedFunction here. }
  29.   TMyMesh = class(TCastleTransform)
  30.   strict private
  31.     Mesh: TCastleRenderUnlitMesh;
  32.   public
  33.     procedure LocalRender(const Params: TRenderParams); override;
  34.     procedure GLContextClose; override;
  35.     function LocalBoundingBox: TBox3D; override;
  36.   end;
  37.  
  38. implementation
  39.  
  40. uses CastleVectors, CastleRenderContext, CastleColors, CastleGLUtils;
  41.  
  42. { TMyMesh -------------------------------------------------------------------- }
  43.  
  44. function TMyMesh.LocalBoundingBox: TBox3D;
  45. begin
  46.   Result := inherited;
  47.   Result := Result + Box3D(
  48.     Vector3(-1, -1, -1),
  49.     Vector3( 1,  1,  1)
  50.   );
  51. end;
  52.  
  53. procedure TMyMesh.LocalRender(const Params: TRenderParams);
  54.  
  55.   procedure CreateMesh(const AvatarTransform: TCastleTransform);
  56.   begin
  57.     Mesh := TCastleRenderUnlitMesh.Create(true);
  58.     Mesh.SetVertexes([
  59.       Vector4(0.0, AvatarTransform.Translation.Y, 0.0, 1.0),
  60.       Vector4(0.0, (AvatarTransform.Translation.Y - AvatarTransform.Direction.Y), 0.0, 1.0)
  61.     ], false);
  62.     Mesh.SetIndexes([
  63.       // line loop on Z = -1
  64.       0, 1
  65.     ]);
  66.     Mesh.Color := Yellow;
  67.   end;
  68.  
  69. var
  70.   SavedDepthTest: Boolean;
  71.   SavedLineWidth: Single;
  72. begin
  73.   inherited;
  74.   SavedDepthTest := RenderContext.DepthTest;
  75.   SavedLineWidth := RenderContext.LineWidth;
  76.   RenderContext.DepthTest := true;
  77.   RenderContext.LineWidth := 5;
  78.  
  79.   if Mesh = nil then
  80.     CreateMesh(AvatarTransform);
  81.   Mesh.ModelViewProjection := RenderContext.ProjectionMatrix *
  82.     Params.RenderingCamera.CurrentMatrix * WorldTransform;
  83.   Mesh.Render(pmLines);
  84.  
  85.   RenderContext.DepthTest := SavedDepthTest;
  86.   RenderContext.LineWidth := SavedLineWidth;
  87. end;
  88.  
  89. procedure TMyMesh.GLContextClose;
  90. begin
  91.   FreeAndNil(Mesh);
  92.   inherited;
  93. end;
  94.  
  95. end.

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
I can guess maybe the problem is that I have the variable placeholder name for the input as the same name as the actual input I pass to the function later on, so it confuses the program; I can try re-naming it and see what happens.

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Okay, still the same exact results, namely it doesn't draw anything - does anyone else have any ideas on why this doesn't work at all?

michalis

  • Full Member
  • ***
  • Posts: 143
    • Castle Game Engine
Okay, still the same exact results, namely it doesn't draw anything - does anyone else have any ideas on why this doesn't work at all?

Looking at your code on https://drive.google.com/file/d/1HicqpXh9fk4jk6tWHzXEh4CB4zrhJnXS/view?usp=sharing , you do not use TMyMesh class anywhere outside of the GameMyMesh unit. You also do not use the unit GameMyMesh in the project.

And just adding the GameMyMesh to any uses clause (like of GameInitialize) shows that the unit doesn't compile -- the line "CreateMesh(AvatarTransform);" accesses "AvatarTransform", but there's no such identifier.

You have to

- pass the instance AvatarTransform somehow to the code inside GameMyMesh. For example, add a field "AvatarTransform: TCastleTransform" to TMyMesh
- create instance of TMyMesh inside GameViewMenu . Create it, set its "AvatarTransform" field, add it to the viewport.

The example I pointed out earlier, https://github.com/castle-engine/castle-engine/tree/master/examples/research_special_rendering_methods/test_rendering_opengl_capabilities , shows how to add TMyMesh instance to a parent TCastleTransform, so that it becomes visible. The exact line is https://github.com/castle-engine/castle-engine/blob/master/examples/research_special_rendering_methods/test_rendering_opengl_capabilities/code/gameviewmain.pas#L83 .

More information about Castle Game Engine viewport and TCastleTransform hierarchy starts in https://castle-engine.io/viewport_and_scenes .

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Now it makes sense why it compiles but doesn't draw - because I didn't actually use the correct reference to the AvatarTransform first.

michalis

  • Full Member
  • ***
  • Posts: 143
    • Castle Game Engine
Now it makes sense why it compiles but doesn't draw - because I didn't actually use the correct reference to the AvatarTransform first.

To be clear, your unit GameMyMesh doesn't compile. (because it doesn't know what's "AvatarTransform").

Your project, in the state from https://drive.google.com/file/d/1HicqpXh9fk4jk6tWHzXEh4CB4zrhJnXS/view?usp=sharing , compiles, but it doesn't use the unit GameMyMesh.

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
Hi, unfortunately I get an error about "Identifier not found TMyMesh" when I do this code, even though in the original example I am using code from TMyMesh wasn't an object in the scene hiearchy either and was created in the code itself:

Code: Pascal  [Select][+][-]
  1. {
  2.   Copyright 2020-2023 Michalis Kamburelis.
  3.  
  4.   This file is part of "Castle Game Engine".
  5.  
  6.   "Castle Game Engine" is free software; see the file COPYING.txt,
  7.   included in this distribution, for details about the copyright.
  8.  
  9.   "Castle Game Engine" is distributed in the hope that it will be useful,
  10.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12.  
  13.   ----------------------------------------------------------------------------
  14. }
  15.  
  16. { Main "playing game" view, where most of the game logic takes place. }
  17. unit GameViewPlay;
  18.  
  19. { Unit for GameMesh renderer features. }
  20.  
  21. {.$define CASTLE_UNFINISHED_CHANGE_TRANSFORMATION_BY_FORCE}
  22.  
  23. interface
  24.  
  25. uses Classes,
  26.   CastleComponentSerialize, CastleUIControls, CastleControls,
  27.   CastleKeysMouse, CastleViewport, CastleScene, CastleVectors, CastleCameras,
  28.   CastleTransform, CastleInputs, CastleThirdPersonNavigation, CastleDebugTransform,
  29.   CastleSceneCore, SysUtils, CastleRenderPrimitives, CastleBoxes,
  30.   GameEnemy;
  31.  
  32. type
  33.  
  34.   { Main "playing game" view, where most of the game logic takes place. }
  35.   TViewPlay = class(TCastleView)
  36.   published
  37.     { Components designed using CGE editor.
  38.       These fields will be automatically initialized at Start. }
  39.     LabelFps: TCastleLabel;
  40.     MainViewport: TCastleViewport;
  41.     AvatarTransform: TCastleTransform;
  42.     SandyLegs, SandyHead, SandyTorso, SceneLevel: TCastleScene;
  43.     AvatarRigidBody: TCastleRigidBody;
  44.     CheckboxCameraFollows: TCastleCheckbox;
  45.     CheckboxAimAvatar: TCastleCheckbox;
  46.     CheckboxDebugAvatarColliders: TCastleCheckbox;
  47.     CheckboxImmediatelyFixBlockedCamera: TCastleCheckbox;
  48.     SliderAirRotationControl: TCastleFloatSlider;
  49.     SliderAirMovementControl: TCastleFloatSlider;
  50.     ButtonChangeTransformationAuto,
  51.     ButtonChangeTransformationDirect,
  52.     ButtonChangeTransformationVelocity,
  53.     ButtonChangeTransformationForce: TCastleButton;
  54.   private
  55.     { Enemies behaviors }
  56.     Enemies: TEnemyList;
  57.  
  58.     DebugAvatar: TDebugTransform;
  59.     { Change things after ThirdPersonNavigation.ChangeTransformation changed. }
  60.     procedure UpdateAfterChangeTransformation;
  61.     procedure ChangeCheckboxCameraFollows(Sender: TObject);
  62.     procedure ChangeCheckboxAimAvatar(Sender: TObject);
  63.     procedure ChangeCheckboxDebugAvatarColliders(Sender: TObject);
  64.     procedure ChangeCheckboxImmediatelyFixBlockedCamera(Sender: TObject);
  65.     procedure ChangeAirRotationControl(Sender: TObject);
  66.     procedure ChangeAirMovementControl(Sender: TObject);
  67.     procedure ClickChangeTransformationAuto(Sender: TObject);
  68.     procedure ClickChangeTransformationDirect(Sender: TObject);
  69.     procedure ClickChangeTransformationVelocity(Sender: TObject);
  70.     procedure ClickChangeTransformationForce(Sender: TObject);
  71.   public
  72.     constructor Create(AOwner: TComponent); override;
  73.     procedure Start; override;
  74.     procedure Stop; override;
  75.     procedure Update(const SecondsPassed: Single; var HandleInput: Boolean); override;
  76.     function Press(const Event: TInputPressRelease): Boolean; override;
  77.     function Release(const Event: TInputPressRelease): Boolean; override;
  78.   end;
  79.  
  80.   TMyThirdPersonNavigation = class(TCastleThirdPersonNavigation)
  81.   protected
  82.     procedure SetAnimation(const AnimationNames: array of String); override;
  83.   end;
  84.  
  85. var
  86.   ViewPlay: TViewPlay;
  87.   MyThirdPersonNavigation: TMyThirdPersonNavigation;
  88.   GroundRayCast: TPhysicsRayCastResult;
  89.   StandOnGround: Boolean;
  90.   SandyInRunning: Boolean;
  91.   MaxDistance: Integer;
  92.  
  93. implementation
  94.  
  95. uses Math, StrUtils, CastleRenderContext, CastleColors,
  96.   CastleSoundEngine, CastleLog, CastleStringUtils, CastleFilesUtils,
  97.   GameViewMenu;
  98.  
  99. { TViewPlay ----------------------------------------------------------------- }
  100.  
  101. constructor TViewPlay.Create(AOwner: TComponent);
  102. begin
  103.   inherited;
  104.   DesignUrl := 'castle-data:/gameviewplay.castle-user-interface';
  105. end;
  106.  
  107. procedure TMyThirdPersonNavigation.SetAnimation(const AnimationNames: array of String);
  108. begin
  109.  
  110. end;
  111.  
  112. procedure TViewPlay.Start;
  113. var
  114.   SoldierScene: TCastleScene;
  115.   Enemy: TEnemy;
  116.   I: Integer;
  117.   MyMesh: TMyMesh;
  118. begin
  119.   inherited;
  120.  
  121.   MyMesh := TMyMesh.Create(FreeAtStop);
  122.   UnlitMeshParent.Add(MyMesh);
  123.  
  124.   MyThirdPersonNavigation := TMyThirdPersonNavigation.Create(FreeAtStop);
  125.   { Create TEnemy instances, add them to Enemies list }
  126.   Enemies := TEnemyList.Create(true);
  127.      for I := 1 to 4 do
  128.      begin
  129.         SoldierScene := DesignedComponent('SceneSoldier' + IntToStr(I)) as TCastleScene;
  130.         { Below using nil as Owner of TEnemy, as the Enemies list already "owns"
  131.         instances of this class, i.e. it will free them. }
  132.         Enemy := TEnemy.Create(nil);
  133.         SoldierScene.AddBehavior(Enemy);
  134.         Enemies.Add(Enemy);
  135.      end;
  136.  
  137.   { synchronize state -> UI }
  138.   SliderAirRotationControl.Value := MyThirdPersonNavigation.AirRotationControl;
  139.   SliderAirMovementControl.Value := MyThirdPersonNavigation.AirMovementControl;
  140.   UpdateAfterChangeTransformation;
  141.  
  142.   CheckboxCameraFollows.OnChange := {$ifdef FPC}@{$endif} ChangeCheckboxCameraFollows;
  143.   CheckboxAimAvatar.OnChange := {$ifdef FPC}@{$endif} ChangeCheckboxAimAvatar;
  144.   CheckboxDebugAvatarColliders.OnChange := {$ifdef FPC}@{$endif} ChangeCheckboxDebugAvatarColliders;
  145.   CheckboxImmediatelyFixBlockedCamera.OnChange := {$ifdef FPC}@{$endif} ChangeCheckboxImmediatelyFixBlockedCamera;
  146.   SliderAirRotationControl.OnChange := {$ifdef FPC}@{$endif} ChangeAirRotationControl;
  147.   SliderAirMovementControl.OnChange := {$ifdef FPC}@{$endif} ChangeAirMovementControl;
  148.   ButtonChangeTransformationAuto.OnClick := {$ifdef FPC}@{$endif} ClickChangeTransformationAuto;
  149.   ButtonChangeTransformationDirect.OnClick := {$ifdef FPC}@{$endif} ClickChangeTransformationDirect;
  150.   ButtonChangeTransformationVelocity.OnClick := {$ifdef FPC}@{$endif} ClickChangeTransformationVelocity;
  151.   ButtonChangeTransformationForce.OnClick := {$ifdef FPC}@{$endif} ClickChangeTransformationForce;
  152.  
  153.   {$ifndef CASTLE_UNFINISHED_CHANGE_TRANSFORMATION_BY_FORCE}
  154.   { Hide UI to test ChangeTransformation = ctForce, it is not finished now,
  155.     not really useful for normal usage. }
  156.   ButtonChangeTransformationForce.Exists := false;
  157.   {$endif}
  158.  
  159.   { This configures SceneAvatar.Middle point, used for shooting.
  160.     In case of old physics (ChangeTransformation = ctDirect) this is also the center
  161.     of SceneAvatar.CollisionSphereRadius. }
  162.   // SceneAvatar.MiddleHeight := 0.9;
  163.  
  164.   { Configure some parameters of old simple physics,
  165.     these only matter when SceneAvatar.Gravity = true.
  166.     Don't use these deprecated things if you don't plan to use ChangeTransformation = ctDirect! }
  167.   // SceneAvatar.GrowSpeed := 10.0;
  168.   // SceneAvatar.FallSpeed := 10.0;
  169.   { When avatar collides as sphere it can climb stairs,
  170.     because legs can temporarily collide with objects. }
  171.   // SceneAvatar.CollisionSphereRadius := 0.5;
  172.  
  173.   { Visualize SceneAvatar bounding box, sphere, middle point, direction etc. }
  174.   DebugAvatar := TDebugTransform.Create(FreeAtStop);
  175.   // DebugAvatar.Parent := SceneAvatar;
  176.  
  177.   { Configure MyThirdPersonNavigation keys (for now, we don't expose doing this in CGE editor). }
  178.   MyThirdPersonNavigation.Input_LeftStrafe.Assign(keyQ);
  179.   MyThirdPersonNavigation.Input_RightStrafe.Assign(keyE);
  180.   MyThirdPersonNavigation.MouseLook := true; // TODO: assigning it from editor doesn't make mouse hidden in mouse look
  181.   MyThirdPersonNavigation.Init;
  182.   MyThirdPersonNavigation.AvatarHierarchy := AvatarTransform;
  183.   SandyLegs.AutoAnimation := 'LEGS_IDLE';
  184.   SandyTorso.AutoAnimation := 'TORSO_IDLE';
  185. end;
  186.  
  187. procedure TViewPlay.Stop;
  188. begin
  189.   FreeAndNil(Enemies);
  190.   inherited;
  191. end;
  192.  
  193. procedure TViewPlay.Update(const SecondsPassed: Single; var HandleInput: Boolean);
  194.  
  195.   // Test: use this to make AimAvatar only when *holding* right mouse button.
  196.   (*
  197.   procedure UpdateAimAvatar;
  198.   begin
  199.     if buttonRight in Container.MousePressed then
  200.       ThirdPersonNavigation.AimAvatar := aaHorizontal
  201.     else
  202.       ThirdPersonNavigation.AimAvatar := aaNone;
  203.  
  204.     { In this case CheckboxAimAvatar only serves to visualize whether
  205.       the right mouse button is pressed now. }
  206.     CheckboxAimAvatar.Checked := ThirdPersonNavigation.AimAvatar <> aaNone;
  207.   end;
  208.   *)
  209.  
  210. var
  211.   SandyAnims: array of String;
  212.   RayCastResult: TPhysicsRayCastResult;
  213.   MoveAmount: TVector3;
  214.   RayCastDirection: TVector3;
  215.   MaxDistance: Single;
  216.   SandyAirborne: Integer;
  217.   SandyIdling: Integer;
  218. begin
  219.   inherited;
  220.   { This virtual method is executed every frame (many times per second). }
  221.   SandyIdling := 0;
  222.   SandyAirborne := 0;
  223.   MaxDistance := 0.3;
  224.   MoveAmount := Vector3(0, -5, 0);
  225.   RayCastDirection := Vector3(0, -1, 0);
  226.   RayCastResult := AvatarRigidBody.PhysicsRayCast(
  227.   (AvatarTransform.Translation),
  228.   RayCastDirection,
  229.   0.3
  230.   );
  231.   if RayCastResult.Hit then
  232.   begin
  233.        SandyAirborne := 0;
  234.        LabelFps.Caption := 'FPS: PLACEHOLDER';
  235.       if SandyIdling = 0 then
  236.       begin
  237.            SandyIdling := 1;
  238.            SandyLegs.PlayAnimation('LEGS_IDLE', true);
  239.            SandyTorso.PlayAnimation('TORSO_IDLE', true);
  240.       end;
  241.   end
  242.   else
  243.       SandyIdling := 0;
  244.       begin
  245.            if SandyAirborne = 0 then
  246.            begin
  247.                 SandyAirborne := 1;
  248.                 SandyTorso.PlayAnimation('TORSO_AIRBORNE', true);
  249.                 SandyLegs.PlayAnimation('LEGS_AIRBORNE', true);
  250.             end;
  251.        AvatarTransform.Move(MoveAmount, false, true);
  252.        LabelFps.Caption := 'FPS: ' + Container.Fps.ToString
  253.        end;
  254.   // UpdateAimAvatar;
  255.   end;
  256.  
  257. function TViewPlay.Press(const Event: TInputPressRelease): Boolean;
  258. var
  259.   HitByAvatar: TCastleTransform;
  260.   HitEnemy: TEnemy;
  261. begin
  262.   Result := inherited;
  263.   if Result then Exit; // allow the ancestor to handle keys
  264.  
  265.   { This virtual method is executed when user presses
  266.     a key, a mouse button, or touches a touch-screen.
  267.  
  268.     Note that each UI control has also events like OnPress and OnClick.
  269.     These events can be used to handle the "press", if it should do something
  270.     specific when used in that UI control.
  271.     The TViewPlay.Press method should be used to handle keys
  272.     not handled in children controls.
  273.   }
  274.  
  275.   if Event.IsMouseButton(buttonLeft) then
  276.   begin
  277.     SoundEngine.Play(SoundEngine.SoundFromName('shoot_sound'));
  278.   end;
  279.  
  280.   if Event.IsMouseButton(buttonRight) then
  281.   begin
  282.     MyThirdPersonNavigation.MouseLook := not MyThirdPersonNavigation.MouseLook;
  283.     Exit(true);
  284.   end;
  285.  
  286.   if Event.IsKey(keyF5) then
  287.   begin
  288.     Container.SaveScreenToDefaultFile;
  289.     Exit(true);
  290.   end;
  291.  
  292.   if Event.IsKey(keyEscape) then
  293.   begin
  294.     Container.View := ViewMenu;
  295.     Exit(true);
  296.   end;
  297.  
  298.   if (Event.IsKey(keyArrowUp) and SandyInRunning = false) then
  299.   begin
  300.     SandyInRunning := true;
  301.     SandyLegs.PlayAnimation('LEGS_RUN', true);
  302.     SandyTorso.PlayAnimation('TORSO_RUN', true);
  303.   end;
  304. end;
  305.  
  306. function TViewPlay.Release(const Event: TInputPressRelease): Boolean;
  307. begin
  308.   Result := inherited;
  309.   if Result then Exit; // allow the ancestor to handle keys
  310.  
  311.   { This virtual method is executed when user releases
  312.     a key, a mouse button, or touches a touch-screen.
  313.  
  314.     Note that each UI control has also events like OnPress and OnClick.
  315.     These events can be used to handle the "press", if it should do something
  316.     specific when used in that UI control.
  317.     The TViewPlay.Release method should be used to handle keys
  318.     not handled in children controls.
  319.   }
  320.  
  321.   if (Event.IsKey(keyArrowUp) and SandyInRunning = true) then
  322.   begin
  323.     SandyInRunning := false;
  324.     SandyLegs.PlayAnimation('BOTH_IDLE', true);
  325.     SandyTorso.PlayAnimation('BOTH_IDLE', true);
  326.   end;
  327. end;
  328.  
  329. procedure TViewPlay.ChangeCheckboxCameraFollows(Sender: TObject);
  330. begin
  331.   MyThirdPersonNavigation.CameraFollows := CheckboxCameraFollows.Checked;
  332. end;
  333.  
  334. procedure TViewPlay.ChangeCheckboxAimAvatar(Sender: TObject);
  335. begin
  336.   if CheckboxAimAvatar.Checked then
  337.     MyThirdPersonNavigation.AimAvatar := aaHorizontal
  338.   else
  339.     MyThirdPersonNavigation.AimAvatar := aaNone;
  340.  
  341.   { The 3rd option, aaFlying, doesn't make sense for this case,
  342.     when avatar walks on the ground and has Gravity = true. }
  343. end;
  344.  
  345. procedure TViewPlay.ChangeCheckboxDebugAvatarColliders(Sender: TObject);
  346. begin
  347.   DebugAvatar.Exists := CheckboxDebugAvatarColliders.Checked;
  348. end;
  349.  
  350. procedure TViewPlay.ChangeCheckboxImmediatelyFixBlockedCamera(Sender: TObject);
  351. begin
  352.   MyThirdPersonNavigation.ImmediatelyFixBlockedCamera := CheckboxImmediatelyFixBlockedCamera.Checked;
  353. end;
  354.  
  355. procedure TViewPlay.ChangeAirRotationControl(Sender: TObject);
  356. begin
  357.   MyThirdPersonNavigation.AirRotationControl := SliderAirRotationControl.Value;
  358. end;
  359.  
  360. procedure TViewPlay.ChangeAirMovementControl(Sender: TObject);
  361. begin
  362.   MyThirdPersonNavigation.AirMovementControl := SliderAirMovementControl.Value;
  363. end;
  364.  
  365. procedure TViewPlay.UpdateAfterChangeTransformation;
  366. begin
  367.   ButtonChangeTransformationAuto.Pressed := MyThirdPersonNavigation.ChangeTransformation = ctAuto;
  368.   ButtonChangeTransformationDirect.Pressed := MyThirdPersonNavigation.ChangeTransformation =  ctDirect;
  369.   ButtonChangeTransformationVelocity.Pressed := MyThirdPersonNavigation.ChangeTransformation =  ctVelocity;
  370.   {$ifdef CASTLE_UNFINISHED_CHANGE_TRANSFORMATION_BY_FORCE}
  371.   ButtonChangeTransformationForce.Pressed := ThirdPersonNavigation.ChangeTransformation = ctForce;
  372.   {$endif}
  373.  
  374.   { ctDirect requires to set up gravity without physics engine,
  375.     using deprecated TCastleTransform.Gravity.
  376.     See https://castle-engine.io/physics#_old_system_for_collisions_and_gravity }
  377.   AvatarRigidBody.Exists := MyThirdPersonNavigation.ChangeTransformation <> ctDirect;
  378.  
  379.   { Gravity means that object tries to maintain a constant height
  380.     (SceneAvatar.PreferredHeight) above the ground.
  381.     GrowSpeed means that object raises properly (makes walking up the stairs work).
  382.     FallSpeed means that object falls properly (makes walking down the stairs,
  383.     falling down pit etc. work). }
  384.   SandyTorso.Gravity := not AvatarRigidBody.Exists;
  385.   SandyLegs.Gravity := not AvatarRigidBody.Exists;
  386.   SandyHead.Gravity := not AvatarRigidBody.Exists;
  387. end;
  388.  
  389. procedure TViewPlay.ClickChangeTransformationAuto(Sender: TObject);
  390. begin
  391.   MyThirdPersonNavigation.ChangeTransformation := ctAuto;
  392.   UpdateAfterChangeTransformation;
  393. end;
  394.  
  395. procedure TViewPlay.ClickChangeTransformationDirect(Sender: TObject);
  396. begin
  397.   MyThirdPersonNavigation.ChangeTransformation := ctDirect;
  398.   UpdateAfterChangeTransformation;
  399. end;
  400.  
  401. procedure TViewPlay.ClickChangeTransformationVelocity(Sender: TObject);
  402. begin
  403.   MyThirdPersonNavigation.ChangeTransformation := ctVelocity;
  404.   UpdateAfterChangeTransformation;
  405. end;
  406.  
  407. procedure TViewPlay.ClickChangeTransformationForce(Sender: TObject);
  408. begin
  409.   {$ifdef CASTLE_UNFINISHED_CHANGE_TRANSFORMATION_BY_FORCE}
  410.   ThirdPersonNavigation.ChangeTransformation := ctForce;
  411.   {$endif}
  412.   UpdateAfterChangeTransformation;
  413. end;
  414.  
  415. end.

Does anyone know what I am doing wrong now?

JPF12141999

  • Jr. Member
  • **
  • Posts: 88
And this is what my GameMyMesh looks like now:

Code: Pascal  [Select][+][-]
  1. {
  2.   Copyright 2023-2023 Michalis Kamburelis.
  3.  
  4.   This file is part of "Castle Game Engine".
  5.  
  6.   "Castle Game Engine" is free software; see the file COPYING.txt,
  7.   included in this distribution, for details about the copyright.
  8.  
  9.   "Castle Game Engine" is distributed in the hope that it will be useful,
  10.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12.  
  13.   ----------------------------------------------------------------------------
  14. }
  15.  
  16. { TCastleTransform descendant that renders unlit mesh using TCastleRenderUnlitMesh. }
  17. unit GameMyMesh;
  18.  
  19. interface
  20.  
  21. uses SysUtils,
  22.   CastleRenderPrimitives, CastleBoxes, CastleTransform;
  23.  
  24. type
  25.   { Mesh rendered using TCastleRenderUnlitMesh, not using TCastleScene.
  26.     This is not generally advised, TCastleScene has much more features
  27.     and is easier to use than TCastleRenderUnlitMesh.
  28.     We do this only to test TCastleRenderUnlitMesh with rcForceFixedFunction here. }
  29.   TMyMesh = class(TCastleTransform)
  30.   published
  31.     AvatarTransform: TCastleTransform;
  32.   strict private
  33.     Mesh: TCastleRenderUnlitMesh;
  34.   public
  35.     procedure LocalRender(const Params: TRenderParams); override;
  36.     procedure GLContextClose; override;
  37.     function LocalBoundingBox: TBox3D; override;
  38.   end;
  39.  
  40. implementation
  41.  
  42. uses CastleVectors, CastleRenderContext, CastleColors, CastleGLUtils;
  43.  
  44. { TMyMesh -------------------------------------------------------------------- }
  45.  
  46. function TMyMesh.LocalBoundingBox: TBox3D;
  47. begin
  48.   Result := inherited;
  49.   Result := Result + Box3D(
  50.     Vector3(-1, -1, -1),
  51.     Vector3( 1,  1,  1)
  52.   );
  53. end;
  54.  
  55. procedure TMyMesh.LocalRender(const Params: TRenderParams);
  56.  
  57.   procedure CreateMesh(const PlayerTransform: TCastleTransform);
  58.   begin
  59.     Mesh := TCastleRenderUnlitMesh.Create(true);
  60.     Mesh.SetVertexes([
  61.       Vector4(0.0, PlayerTransform.Translation.Y, 0.0, 1.0),
  62.       Vector4(0.0, (PlayerTransform.Translation.Y - PlayerTransform.Direction.Y), 0.0, 1.0)
  63.     ], false);
  64.     Mesh.SetIndexes([
  65.       // line loop on Z = -1
  66.       0, 1
  67.     ]);
  68.     Mesh.Color := Yellow;
  69.   end;
  70.  
  71. var
  72.   SavedDepthTest: Boolean;
  73.   SavedLineWidth: Single;
  74. begin
  75.   inherited;
  76.   SavedDepthTest := RenderContext.DepthTest;
  77.   SavedLineWidth := RenderContext.LineWidth;
  78.   RenderContext.DepthTest := true;
  79.   RenderContext.LineWidth := 5;
  80.  
  81.   if Mesh = nil then
  82.     CreateMesh(AvatarTransform);
  83.   Mesh.ModelViewProjection := RenderContext.ProjectionMatrix *
  84.     Params.RenderingCamera.CurrentMatrix * WorldTransform;
  85.   Mesh.Render(pmLines);
  86.  
  87.   RenderContext.DepthTest := SavedDepthTest;
  88.   RenderContext.LineWidth := SavedLineWidth;
  89. end;
  90.  
  91. procedure TMyMesh.GLContextClose;
  92. begin
  93.   FreeAndNil(Mesh);
  94.   inherited;
  95. end;
  96.  
  97. end.

 

TinyPortal © 2005-2018