I'm making a basic minecraft-style 3d game, and I'm trying to add UI. I set up the game using the built in camera() function, not peasycam, which is what all the answers I've seen are for. I want to have more control over the camera than peasycam allows. How do I create 2d objects like rectangles and text that stay static over the screen and always face the camera?
I have 4 3d vectors: one for position, one for velocity, one for camera angle, and one for camera rotation before I use trigonometry on it. I placed a sphere and a piece of text in the game (under the hud() function in draw()). I used translate() to position them, and it worked, but looking up and down shows that they do not follow camera movement.
import java.awt.Robot;
import java.awt.AWTException;
final float size = 100;
final float speed = 10;
final float look = .02;
final float playerHeight = size;
final float renderDist = 2600;
Robot robot;
PVector pos = new PVector(0, 0, 0); //position
PVector vel = new PVector(0, 0, 0); //velocity
PVector cam = new PVector(0, 0, 0); //camera angle
PVector rot = new PVector(0, 0, 0); //camera rotation
ArrayList<Block> blocks = new ArrayList<Block>();
void setup(){
fullScreen(P3D);
noCursor();
blocks.add(new Block(0, 0, 0, color(255)));
blocks.add(new Block(1, 0, 0, color(255, 0, 0)));
blocks.add(new Block(0, 1, 0, color(0, 255, 0)));
blocks.add(new Block(0, 0, 1, color(0, 0, 255)));
genFloor(500);
try {
robot = new Robot();
} catch (AWTException e){
e.printStackTrace();
}
}
void draw(){
background(115, 189, 245);
look();
movement();
display();
hud();
}
class Block{
PVector pos = new PVector();
color thisColor = color(255);
Block (int x, int y, int z, color thisColor){
pos.x = x;
pos.y = y;
pos.z = z;
this.thisColor = thisColor;
}
Block (int x, int y, int z){
pos.x = x;
pos.y = y;
pos.z = z;
}
}
void display(){
for (Block block : blocks){
float distance = (float)Math.pow(Math.pow(block.pos.x * size - pos.x, 2) + Math.pow(block.pos.z * size - pos.z, 2), .5);
if (distance <= renderDist){
pushMatrix();
translate(size * block.pos.x, size * block.pos.y, size * block.pos.z);
fill(block.thisColor);
box(size);
popMatrix();
}
}
}
void movement(){
pos.x += vel.z * cam.x + vel.x * cam.z;
pos.y += vel.y;
pos.z += -vel.x * cam.x + vel.z * cam.z;
camera(pos.x, pos.y + playerHeight, pos.z, pos.x + cam.x, pos.y + cam.y + playerHeight, pos.z + cam.z, 0, -1, 0);
}
void keyPressed(){
if (key == 'w'){
vel.z = speed;
}
if (key == 's'){
vel.z = -speed;
}
if (key == 'd'){
vel.x = speed;
}
if (key == 'a'){
vel.x = -speed;
}
}
void keyReleased(){
if (key == 'w' && vel.z > 0){
vel.z = 0;
}
if (key == 's' && vel.z < 0){
vel.z = 0;
}
if (key == 'd' && vel.x > 0){
vel.x = 0;
}
if (key == 'a' && vel.x < 0){
vel.x = 0;
}
}
void look(){
rot.x -= (mouseX - width/2) * look;
rot.y += (mouseY - height/2) * look;
if (rot.y < -11){
rot.y = -11;
}
if (rot.y > -8){
rot.y = -8;
}
robot.mouseMove(width/2, height/2);
cam.x = (float)Math.cos(rot.x);
cam.y = (float)Math.sin(rot.y);
cam.z = (float)Math.sin(rot.x);
}
void genFloor(int size){
for (int x = size/-2; x < size/2; x++){
for (int z = size/-2; z < size/2; z++){
blocks.add(new Block(x, -1, z));
}
}
}
void hud(){
pushMatrix();
translate(pos.x + cam.x * 100, pos.y + playerHeight + cam.y * 100, pos.z + cam.z * 100);
fill(0);
sphere(1);
rotateX(radians(180));
text("text", 0,0);
popMatrix();
}