- Joined
- Jul 24, 2006
- Messages
- 157
SharpCraft First Person Camera
This tutorial is about a simple first person camera system made with sharpcraft.
Keep in mind:
-You need SharpCraft to play the map
-Wc3 Engine is not made for such a camera
Screenshot how this can look like:
Idea:
We place the cursor in the center of the screen.Now we constantly check whether the cursor position changed and reset the position to the center.
We can use the distance of the cursor to the center to detect the speed of the motion.
With this information we are able to determine the new camera rotation.
SharpCraft
I attached the correct SharpCraft version 1.2.4.0 with an additional script to set and get the mouse cursor position: downloadThere is a newer one, but this is the last stable version. This means you do not need to code any c# and you can directly manipulate the cursor with Jass/Wurst.
Add Sharpcraft to the Editor
If you use WurstScript simply add the SharpCraft folder to your Wurstpack folder and a new menu item will pop up in the editor.
//TODO add description for JNGP
Known Issues: You need multiple tries until SharpCraft successfully injects into wc3 when you start the map via editor.
Code:
The following code segments will be Wurst Code, but it works similar in Jass.You need to add the new native methods with
JASS:
public native CenterMouse()
public native GetCenterScreenX() returns real
public native GetCenterScreenY() returns real
public native GetMouseScreenX() returns real
public native GetMouseScreenY() returns real
Here is an possible initialization of the camera:
JASS:
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_FIELD_OF_VIEW, 115,0 )
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_FARZ, 5000,0 )
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_ANGLE_OF_ATTACK, 0,0 )
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_ZOFFSET,height, 0 )
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_TARGET_DISTANCE, 0, 0 )
Now you can simply use new defined natives to manipluate the camera, here is an example with the y axis:
(It works similar with the camera rotation and the x-axis)
JASS:
//Check if the position of the cursor changed
if GetMouseScreenY() != GetCenterScreenY()
//Calculate the new angle of attack
angleOfAttack+= (GetCenterScreenY()-GetMouseScreenY())/4
// Limit the view so you cannot rotate over your head
if angleOfAttack >90
angleOfAttack = 90
else if angleOfAttack < -90
angleOfAttack = -90
//Adjust the new angle of attack
SetCameraFieldForPlayer( Player(0), CAMERA_FIELD_ANGLE_OF_ATTACK, angleOfAttack, cameraTime )
//Reset the cursor back to the center
CenterMouse()
This means if you only change the angle of attack you get this effect:
To solve this effect you need to adjust the position of the camera.
You can do this with cosinus and sinus:
JASS:
//Turn the rotation angle into a direction vector
angle a = rotation.asAngleDegrees()
vec2 direction = a.direction()
//Use the vector to calculate the correct new cam position
real newX=cameraPosition.x+100*CosBJ(angleOfAttack)*direction.x
real newY=cameraPosition.y+100*CosBJ(angleOfAttack)*direction.y
PanCameraToTimed( newX,newY,cameraTime )
//Do the same with the height of the cam
location loc = Location(GetCameraEyePositionX(),GetCameraEyePositionY())
//Dont forget to get the ground height
real newHeight = GetLocationZ(loc)
setCameraZ(newHeight+height+100*SinBJ(angleOfAttack))
Besides wc3 has the effect to automatically adjust the height of the camera to the ground.
Here is a work around/hack to gain full control over the height of the camera:
JASS:
function setCameraZ(real z)
real zz = GetCameraField(CAMERA_FIELD_ZOFFSET)+z-GetCameraTargetPositionZ()
SetCameraField(CAMERA_FIELD_ZOFFSET,zz,- cameraTime)
SetCameraField(CAMERA_FIELD_ZOFFSET,zz,cameraTime)
Important: Display Bugs and how to fix them
This is the most important part of the tutorial because you will notice very fast that some models will simply disappear in game.In this section I will explain why this is happening and what you can do against it.
Principle:
Warcraft 3 checks the terrain to detect whether a model is displayed or not.As a result models disappear when you look at the sky and no terrain near the model is left on the screen.
This is extremely annoying when you have models larger than the original wc3 trees.
Doodads
1. Best Solution:Fill doodads with terrain. For example when you have a house you can place terrain into the building.
As a result every time you look at the top of the building there will be terrain on the screen -> the building is still visible.
For some Doodads the invisible tile could be useful to place terrain with the invisible tile at the position.
Remember: Most important is that the height of the terrain is nearly as hight as the doodad.
To achieve this you can use the miscdata.txt.
Example:
2. Sometimes this is not possible, for example for large trees. In this case you can edit the model and multiply the MinimumExetent and MaximumExtent with a value like 10.
This means the cuboid that wc3 checks whether the model should be visible or not is much larger. As a result the possibility that the models is displayed correct is increased.
This method fix the issue, but it is bad for the performance. Because now the model is rendered even when it is not on the screen.
Besides it is no longer possible to easily select the model in the editor.
You can use Magos Model Editor: Edit -> Model Properties
Units
For Unit Models you can increase the Bounds Radius.Open Magos -> Edit -> Model Properties
Performance:
The Performance is not good because Warcraft 3 is rendering all models, even those are hidden behind another object:Tips to increase the Performance:
Use less doodads! (and try to keep the polygon count low)A useful technique I created is to merge doodads in an area to a single model.
This means houses build out of single doodads are bad, but a single large house/rock formation is good.
To achive this I created the Doodad2Model Merger.
Attachments
Last edited by a moderator: