- jMonkeyEngine 3.0 Cookbook
- Rickard Edén
- 636字
- 2021-09-03 10:00:49
Making the camera follow units
This recipe will cover some principles on how to make the camera follow something in the game world. While it might seem like an easy task at first, there are some tricky bits too.
Getting ready
The recipe will build upon the Creating an RTS camera AppState object recipe of this chapter. All of the steps described in this recipe will be applied to AppState
.
How to do it...
To make the camera follow units, perform the following steps:
- We start by adding two new variables, which we'll use for the new functionality. A Vector3f variable, called
targetLocation
, will be used to track the target, and a Boolean variable calledfollow
, will be used to declare whether the camera should track the target or not. These are set from external classes. - Out of convenience, we also define a final Vector3f variable, called
UNIT_XZ
, which we set to(1f, 0, 1f)
. We'll use this to convert 3D positions to 2D. - Then, we need to add some functionality in the
update
method just beforecam.setLocation(camLocation);
. - First, we add a check to see whether the camera has been moved by the player. If so, we turn off the tracking as follows:
if(tempVector.length() > 0){ follow = false; }
- Since the camera is up in the air and the target is (most likely) on the ground, we transform the camera's location to a position on the same horizontal plane as the target. The
targetLocation
vector is pretty simple to handle. We just flatten it by zeroing on theY
value as follows:Vector3f targetLocation2D = targetLocation.mult(UNIT_XZ);
- The camera is a bit trickier; since we're interested in the target's position in relation to the point the camera is looking at, we need to first find out where it is looking. First, we get the relative position of the point the camera is looking at by multiplying the height with the direction as follows:
Vector3f camDirOffset = cam.getDirection().mult(camDistance);
- Then, we add it to the camera's location (you can say that we project it on the ground) to get its world position. Finally, we flatten this as well with
UNIT_XZ
as follows:Vector3f camLocation2D = camLocation.add(camDirOffset).multLocal(UNIT_XZ);
- We're using a linear interpolation that moves the camera's focus point 30 percent closer to the target location each cycle. Then, we reverse the addition we did earlier (or unproject) to get a new 3D position for the camera. The distance check is optional, but since we're going to use interpolation, we might save a few calculations by only interpolating if the distance is above a certain threshold as follows:
if(targetLocation2D.distance(camLocation2D) > 0.01f){ camLocation2D.interpolate(targetLocation2D, 0.3f); camLocation.set(camLocation2D); camLocation.subtractLocal(camDirOffset);
- To show that these changes work, we need to change a few things in our test application. We can grab Jaime from our scene and use his translation as the target location. We use
worldTranslation
and notlocalTranslation
in this case:appState.setTargetLocation(jaime.getWorldTranslation()); appState.setFollow(true);
- Then, in the
update
method of the test case, we make him slowly move along the x axis as follows:jaime.move(0.2f * tpf, 0, 0);
- While running the application, we should see the camera follow Jaime until we move it manually.
How it works...
Another way of handling it would be not to move the camera during the input but the actual point it looks at, and have the camera troll along. No matter which way you choose to do it though, practicing and thus getting a better understanding of these trigonometric problems is always a good idea.
Since we're using linear interpolation here, camLocation2D
will never actually reach targetLocation
; it'll just get infinitely closer. This is why an if
statement can be useful in these cases to see whether it's worth actually changing the distance or not. Finding the right threshold to break off is empiric and varies from case to case.
- 極簡算法史:從數學到機器的故事
- 從程序員到架構師:大數據量、緩存、高并發、微服務、多團隊協同等核心場景實戰
- 軟件架構:Python語言實現
- 焊接機器人系統操作、編程與維護
- C++面向對象程序設計習題解答與上機指導(第三版)
- Windows Phone 7.5:Building Location-aware Applications
- 計算機應用基礎案例教程
- Arduino可穿戴設備開發
- 計算機應用基礎項目化教程
- Scala編程實戰
- Django Design Patterns and Best Practices
- TypeScript圖形渲染實戰:2D架構設計與實現
- Python Social Media Analytics
- Java 11 and 12:New Features
- Java面向對象程序設計教程