- 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.
- ASP.NET Core:Cloud-ready,Enterprise Web Application Development
- 青少年軟件編程基礎與實戰(圖形化編程三級)
- Cassandra Design Patterns(Second Edition)
- Python Data Analysis(Second Edition)
- 大模型RAG實戰:RAG原理、應用與系統構建
- H5頁面設計:Mugeda版(微課版)
- 精通MATLAB(第3版)
- Python深度學習:模型、方法與實現
- 小程序,巧應用:微信小程序開發實戰(第2版)
- 大話Java:程序設計從入門到精通
- C++ Fundamentals
- QlikView Unlocked
- Clojure for Finance
- Java 7 Concurrency Cookbook
- Learning ROS for Robotics Programming