Access violation when adding a scene to viewport items

I have a simple procedure that looks like this, with some WriteLnLog calls to help with debugging:

procedure TViewMain.AddCar;
begin
  WriteLnLog('start');
  Car := TCastleScene.Create(FreeAtStop);
  WriteLnLog('after create');
  Car.Load('castle-data:/car.gltf');
  WriteLnLog('after load');
  Car.Translation := Vector3(Car.Translation.X, 4, Car.Translation.Z);
  WriteLnLog('after translate');
  MainViewport.Items.Add(Car);
  WriteLnLog('after add');
end;

“Car” is defined as a private field on TViewMain.
I also call this procedure like this:

if Event.IsKey(keyP) then
begin
  AddCar;
  Exit(true);
end;

When I run the game and press the P key, this is what appears in the console:

start
after create
after load
after translate
An unhandled exception occurred at $00000001014A10B5:
EAccessViolation: Access violation
  $00000001014A10B5
  $00000001014A11DD
  $0000000100A31150
  $0000000100A30ECE
  $00000001007E1E70
  $00000001007DCC26
  $00007FF811425764
  $00007FF81142548F
  $00000001007DF5DA
  $00000001007DF696

Exception "Exception":
Process "/Volumes/Data/dev/pascal/viewport-3d-tut/castle-engine-output/macos/Viewport 3D.app/Contents/MacOS/viewport-3d-tut" (absolute path "/Volumes/Data/dev/pascal/viewport-3d-tut/castle-engine-output/macos/Viewport 3D.app/Contents/MacOS/viewport-3d-tut") failed with exit status 217

I’m confused as to why this is happening, since there is a demo (in examples/viewports_and_scenes/cars_demo) with seemingly the exact same scene creation code. Any ideas?

The Car seems to be initialized OK in the code you show.

Are you sure the MainViewport is initialized OK?

The cars_demo doesn’t initialize it explicitly, but it gets initialized by Castle Game Engine because:

  • MainViewport: TCastleViewport is in the published section of the view
  • MainViewport was created using CGE editor, it is loaded from the castle-data:/gameviewmain.castle-user-interface.

See Writing code to modify scenes and transformations | Manual | Castle Game Engine , in particular the section “Refer to the designed components”.

You can add more debug to test whether my guess is correct:

WritelnLog('Car assigned? %s', [BoolToStr(Car <> nil, true)]);
WritelnLog('MainViewport assigned? %s', [BoolToStr(MainViewport <> nil, true)]);
MainViewport.Items.Add(Car);

If my guess is right, you will see Car assigned? true but then MainViewport assigned? false.

It this doesn’t help, then please submit the testcase – I can investigate and help better :slight_smile:

1 Like

Turns out the component that I thought was called “MainViewport” was actually called “Viewport1”…

I changed the name to “MainViewport” and everything works correctly.

2 Likes