Greetings!
On a few occasions, I ran into the need for LookAt functionality - especially for animating the camera in cutscenes.
Typically, I code that myself because, after a quick look, I didn’t find anything similar. And I’m too lazy to do the proper digging through the units. However, I am wondering if there are any readily available functions in CGE to achieve this. Maybe it’s implemented inside some TCastleTransform or component. Like, making the TCastleTransform.Direction or general Vector3d/4d.Direction to point at the target (world-space coords of the origin point of the target). Or something similar - my problem finding it is it can be named function just-anything depending on how the original purpose was defined. I know the AnimateTo, it’s nice but quite different from LookAt or Target. I hope you understand what I meant.
It’s not a feature request, no worries, and not a bug
- I’m just asking for confirmation that similar functionality is or isn’t there.
Oh well, actually the 3rd person navigation does very similar stuff. Which means I overlooked the possibility of using behaviours. And that is an interesting opportunity because we could put the same behaviour not only for the camera, but also for NPC eyes, head & body - so they turn to, focus, and track objects/players.
I would say that we give you here the building blocks to make it easy:
-
Set the Direction (or Rotation, or use SetView or WorldSetView) on any TCastleTransform as often as you’d like.
-
Do stuff from Update methods (overridden in view, or in particular TCastleTransform or in behavior).
Indeed, behaviors that you mentioned would be my recommendation in many cases. In the simplest case, define a behavior like this:
type
TLookAtBehavior = class(TCastleBehavior)
public
Target: TCastleTransform;
procedure Update(const SecondsPassed: Single; var RemoveMe: TRemoveType); override;
end;
procedure TLookAtBehavior.Update(const SecondsPassed: Single; var RemoveMe: TRemoveType);
begin
inherited;
// Note: No need to normalize direction, it will be done on the engine side.
Parent.WorldDirection := Target.WorldTranslation - Parent.WorldTranslation;
end;
Add a new instance of this class to the TCastleTransform that should act as an “observer” . This can be anything, including a camera, since TCastleCamera is also a descendant from TCastleTransform. Like
procedure TMyView.Start;
var
LookAtBehavior: TLookAtBehavior;
begin
inherited;
LookAtBehavior := TLookAtBehavior.Create(FreeAtStop);
LookAtBehavior.Target := SomeTarget;
Observer.AddBehavior(LookAtBehavior);
end;
This is simplest, and assumes that the Up vector of the observer is already good. If not, you can adjust it, once and/or each frame.
I think above can be extended / modified for a particular use-case, so it’s OK that we don’t explicitly provide such behavior ready in the engine, instead giving you “building blocks” to do it on your side… Hm, but it’s a very good example for behaviors! I have added it to Behaviors | Manual | Castle Game Engine docs 
2 Likes