MyScene.Url := 'castle-data:/my_model.gltf'; MyScene.Translation := Vector3(1, 2, 3); MyScene.PlayAnimation('run', true);
GameObject in Unity is (simplifying) something that exists in your world, and may be visible, and may have children that are affected by a transformation.
For game objects (not user-interface), the closest equivalent of
GameObject in Castle Game Engine is the
TCastleTransform class. Instances of
TCastleTransform can be arranged in a hierarchy, where each element transforms (moves, rotates, scales) the children. The most important class of CGE is the
TCastleScene, which is a descendant of
TCastleTransform that can actually render/animate/collide a model. Simply set
TCastleScene.Url to load your model (like a glTF file) there.
MyScene.Url := 'castle-data:/my_model.gltf'; MyScene.Translation := Vector3(1, 2, 3); MyScene.PlayAnimation('run', true);
TCastleTransform hierarchy is placed in a
TCastleViewport, which is a 2D user-interface element (descendant of
For objects that are user-interface elements, the most important base class is
TCastleUserInterface. It has many descendants, like
obvious user interface controls:
and finally a critical UI component
TCastleViewport which is a "gateway" to actually render a hierarchy of
See user interface documentation.
In the simplest case, for each 3D model, you create a
TCastleScene instance. You can do this visually, using the CGE editor, or from code.
To group (and transform as a group) a number of
TCastleScene instances you can use additional
TCastleTransform instances. The
TCastleScene is also a
TCastleTransform descendant, so it can have children too.
Follow the template "3D FPS Game" (create it by running our editor, choose "New Project" and then choose "3D FPS Game" as a starting point). In the resulting project, open the design
data/gamestateplay.castle-user-interface in the editor, to actually see what I mean (in this and previous answer).
Our goal with CGE editor is to provide an experience similar to Unity and other game engine editors. So you can drop 3D models on your design, and drag them to design a level.
There are multiple ways how you can control CGE stuff:
The equivalent of
TCastleBehavior class. So you can define a class descending from
TCastleBehavior, and add an instance of it to
type TMyBehaviorClass = class(TCastleBehavior) public procedure Update(const SecondsPassed: Single; var RemoveMe: TRemoveType); override; end;
Then add such behavior instance from code:
var MyBehavior: TMyBehaviorClass; begin MyBehavior := TMyBehaviorClass.Create(SomOwner); MyBehavior.Xxx := ...; // configure necessary parameters MyTransform.AddBehavior(MyBehavior); end;
See our template "3D FPS Game" (create it by running our editor, choose "New Project" and then choose "3D FPS Game" as a starting point) that shows exactly this approach. It defines a trivial
TEnemy class that defines the logic of an enemy, and is a
TCastleBehavior descendant. It controls the enemy movement. It also allows to check (e.g. when shooting ray) "did I hit an enemy" by checking
SomeTransform.FindBehavior(TEnemy) <> nil.
While the above examples show attaching a behavior using code, you could also add
TEnemy in editor. See editor and custom components docs for information how to register
TEnemy class in editor. This requires to restart editor within the project with menu option "Project -> Restart Editor (With Custom Components)". It is an extra step, but it makes sense for complicated behaviors, which can be configured in the editor easier.
Another way to control things in CGE is to create class descendants from existing classes. In CGE you can create descendants from almost all classes (including important
TCastleUserInterface), and override virtual methods there. E.g. you can override
TCastleTransform.Update to perform something every frame.
So you could define a class like
TMyCreature that descends from
TCastleScene. This class would control it’s own transformation (e.g. it would change it’s own
Translation to move the creature) and it would possibly load some children (more
TCastleScene instances) to show and animate the creature.
This is a classic OOP approach. This is like Unreal Engine that allows you to define your own actor classes that override the base class.
You can also assign events, like
OnPress. Most UI controls expose obvious events, like
TCastleButton.OnClick. You are free to handle these events at one central place (like an LCL
TForm descendant (only if you use
TCastleControl), or CGE
TUIState descendant) or decentralized (e.g. create a different instance of your own class to handle events of each different creature, different item).
The approach to use events is similar to using UI in Lazarus LCL or Delphi VCL.
You can also control things from outside, e.g. control all creatures from the state instance. The state like
TStatePlay (see above mentioned template "3D FPS Game") has its own methods to
Update and handle input. The state can keep references to everything you have in your world, and it can control them.
You should place your game data in the
data subdirectory of the project. See manual about the "data" directory. It will be automatically packaged and available in your games.
Everything inside your
data subdirectory is loadable at runtime. In this sense, it is actually similar to
Assets/Resources/ subdirectory of Unity, if you care about details.
Things that are not your game data (like your source code) should not be placed in the
data subdirectory. The source code should live outside of data. Only the compiler must be able to find it (you can specify your sources locations using standard Lazarus Project Options and/or (for building cross-platform projects) using
<compiler_options> in CastleEngineManifest.xml). By convention, most CGE examples place Pascal source code in the
code subdirectory (or in top-level project directory), but this is really only a convention.
The layout of a larger CGE project may be like this:
my_project/ <- the project root CastleEngineManifest.xml <- this manifest file is used by both CGE build tool and CGE editor data/ <- game data lives here; up to you how to organize this CastleSettings.xml <- defines UI scaling, default font example_image.png example_model.gltf gamestatemainmenu.castle-user-interface ... code/ <- Pascal game code lives here; up to you how to organize this gameinitialize.pas gamestatemainmenu.pas <- Pascal unit corresponding (by convention) to gamestatemainmenu.castle-user-interface ... ... <- any other subdirectories and files? Up to you. Consider docs/ and README.md.
See supported model formats. In short: glTF is the best :) This documentation page also links to instructions for various authoring tools "how to export your data".
No, and we will probably never do (unless indirectly through some universal conversion library). FBX is a proprietary model format by Autodesk. Please don’t use FBX, it’s proprietary (the Autodesk specification of FBX is "secret" deliberately, and Autodesk only sanctions using FBX through it’s paid SDK), and also not that good. Use glTF.
TODO: We work on removing the inconsistency documented below, by introducing new, editor-friendly API for creature behaviors.
examples/fps_game example shows how to use our (Deprecated) Utilities for typical 3D games that are included in
CastleItems and friend units. It is an older example, not using CGE editor to design the level.
The work to upgrade this example, to use editor to design the level and non-deprecated functionality, has started. You can define
examples/fps_game approach doesn’t map nicely to CGE editor, and is not as flexible as we want it to be (although it may be enough for a typical first-person shooter, and there are many ways to customize it — see subpages of https://castle-engine.io/manual_high_level_3d_classes.php , and see TMedKitResource and TMedKit classes in
Our template "3D FPS Game", on the other hand, presents a modern way to design 3D levels and enemies. You can design things in editor, you can use behaviors (
TCastleBehavior) to attach logic to transformations. We advise you to follow this approach, but admittedly it lacks some functionality for now (we don’t yet have a ready behavior that out-of-the-box makes a creature walk/attack behavior).
Fixing this is an important piece of our roadmap for 2022.
A short summary of the answer: Use TCastleWindow. If all you want is a cross-platform game, where everything is rendered using Castle Game Engine. If you come here and want to "just make a game using CGE", use
Details: The difference is outlined on https://castle-engine.io/manual_lazarus_control.php :
TCastleControl means that engine rendering is inside Lazarus form. That is, TCastleControl is a regular Lazarus control that can be placed on a larger form. You can use Lazarus designer to place LCL controls, and you can use CGE editor to design CGE controls (within TCastleControl).
TCastleWindow means that engine rendering is a separate window, and we’re not using LCL. You can use CGE editor to design controls. So you lose access to LCL controls, but in exchange you get perfect cross-platform code (Android, iOS, Switch work only with TCastleWindow).
In both cases, you can use Lazarus as an IDE — to write code, debug etc. In both cases, you can use CGE editor to design CGE controls (that go inside TCastleControl or TCastleWindow).
An equivalent is to set
It is specific to the given world, which is an instance of
TCastleAbstractRootTransform available in
MyViewport.Items. Simple games will just have one viewport, a
TCastleViewport instance. Multiple instances of
TCastleViewport are possible, and then can share the same world, or show a different world (just assign
There in an additional time scaling possible by
TCastleScene.TimePlayingSpeed. This is local in given
Container.Fps.SecondsPassed. See the https://castle-engine.io/manual_state_events.php for the most trivial usage example.
In you override the
TCastleTransform.Update method, then you also have an explicit parameter
SecondsPassed that contains this value. In
TCastleTransform.Update the time is already scaled (if you used
MyViewport.Items.TimeScale mentioned above).
TCastleUserInterface have a Boolean
TCastleUserInterface.Exists. By default this is
true. Simply set it to
false to make everything behave as if this component was not part of the hierarchy. Non-existing components are not visible, do not collide, do not handle any input, do not cause any events etc. So Unity
GameObject.SetActive(xxx) translates to CGE
MyTransform.Exists := xxx.
You can also control the
TCastleTransform.Visible properties of
TCastleTransform. These are useful to make something e.g. visible but non-collidable, or collidable but invisible. Note that when
false, it "overrides" them, and non-existing object never collides and is never visible.
We have UI scaling, to adjust to any screen size smartly, and it works similar to Unity canvas scaling. It allows to design assuming a specific window size, and as long as you set sensible anchors, the design will look reasonable at various screen resolutions (even with different aspect ratio). It merely scales the coordinates — the actual rendering is done for the final resolution, so it looks "sharp" always.
The scaling is configured using CastleSettings.xml file. The default CGE editor "New Project" templates set UI scaling to adjust with a reference window size of 1600x900.
Mobile services like ads, analytics, in-app purchases and more are available as Android services or iOS services. You declare them in CastleEngineManifest.xml and then build the project using our build tool. These allow to integrate your code with various 3rd-party services (from Google, Apple and others) or use mobile APIs that require special permissions (like vibrations).
The "service" means "a part of the project, in binary or source code, added during the build stage".
Android services may contain Java code, precompiled libraries for Android, Gragle configuration and more.
iOS services may contain Objective-C code, precompiled libraries for iOS, CocoaPods configuration and more.
On other platforms, so far we didn’t need a similar concept. E.g. integration of CGE with 3rd-party services on desktops is always possible by normal Pascal units that expose e.g. FMOD or Steam API. That said, it is possible that we will add "services" for other platforms some day.
You can of course replace or enhance the shaders used by our engine.
We have compositing shaders which is like Unity3d "surface shaders" but on steroids :) I’m quite proud of this, it really allows to easily write a piece of shader code and add it to some shapes, and (compared to Unity3d "surface shaders") it has some cool new features, like the ability to combine many effects (so you can write one shader effect, maybe add another shader effect), or changing shading of lights or textures or making proceduraly generated (on GPU) textures.
See examples/viewport_and_scenes/shader_effects for simple demo in Pascal that attaches an effect, coded in GLSL, to a scene loaded from glTF. The shader uniform variable can be set at runtime from Pascal of course, and thus you can configure the shader at runtime with zero cost.
See https://github.com/castle-engine/demo-models, subdirectory compositing_shaders for demos of
Effect nodes in pure X3D (you can load them all from CGE; it’s just that these demos create
Effect node by X3D code, not by Pascal code).
In Unity, your typical world is a hierarchy of 3D
Somewhere in this world, you have a
Camera component, that determines the camera parameters (like projection) and viewport sizes. The transformation of the associated
GameObject determines the camera position and rotation.
You can have multiple
Camera components on different GameObjects to have multiple viewports.
Somewhere in this world, you have a canvas that acts as a place for 2D controls like buttons and images.
In CGE, it is a bit different. Viewport (
TCastleViewport) is a 2D control, and it can render 3D world inside.
You design a hierarchy of
TCastleUserInterface components. They all have the same properties to control position and size, using anchors, using
FullSize (fill the parent etc.).
There are numerous
TCastleUserInterface descendants, like buttons, images, and viewports.
Within a viewport (
TCastleViewport) instance, you place your 3D world (in
A viewport is always connected with exactly one camera in
Viewport.Camera. This camera determines projection settings and position, rotation of the viewer.
The above describes the typical design as seen in editor templates. To see it in action, create a "New Project" in the editor, using the template like "3D FPS Game", and open the design
data/gamestateplay.castle-user-interface in the editor.
In short, in Unity "viewport" and "camera" and "UI" are just things inside your 3D world. In CGE, "viewport" (and the corresponding "camera") contains your 3D world, and "viewport" is part of your UI.
In CGE the "viewport" can be positioned/sized just like any other 2D control. See examples/viewport_and_scenes/multiple_viewports for an example that shows 4 viewports.
The Z-order (what is in front/behind) of the viewport in CGE is straightforward, it works just like all other 2D controls. You can easily place other 2D controls in front or behind a viewport (the latter is useful if the viewport has
In CGE each "viewport" may show a completely different, unrelated, 3D world. The viewports can also share the world (show the same world from different cameras), simply set them the same
Prefabs are a way to store GameObject hierarchy, with Unity components attached, in a file.
The usual equivalent in CGE is to create a
xxx.castle-transform file where you create a design with a root being
TCastleScene. This allows you to compose a transformation hierarchy of
TCastleScene instances. You can then load this
xxx.castle-transform multiple times, as a single thing. See the examples/advanced_editor, the file
data/soldier_with_cape.castle-transform there is a simplest example of this approach.
The equivalent of prefabs for Unity UI elements is a UI design file,
xxx.castle-user-interface, already mentioned above.
The equivalent of Unity AudioSource is our
TCastleSoundSource. It is a behavior, you attach it to a parent
TCastleTransform and it can play spatialized sound. Note that for non-spatial sounds, you can also just call
TSoundEngine.Play, this is simpler and there’s no need for a
See manual chapter about sound for information how to use sound in CGE.
Owner comes from from the standard
TComponent. See Manual and automatic freeing (Pascal introduction). It manages memory (owner will free the owned instance, when the owner is freed before the owned).
Owner are separate concepts, even declared in different classes.
Owner may be set to the same instance, if it is suitable in the particular situation, but in general these 2 things just perform 2 separate functions. For example, in CGE editor, owner of everything in the design is always one central
DesignOwner component. When you load the design yourself, you provide the
Owner instance explicitly (as a parameter to
ComponentLoad) and then you specify parent yourself but adding the design to the hierarchy (e.g.
To improve this documentation just edit the source of this page in AsciiDoctor (simple wiki-like syntax) and create a pull request to Castle Game Engine WWW (cge-www) repository.
Copyright Michalis Kamburelis and Castle Game Engine Contributors.