Add files via upload

master
AiTechEye 2021-06-13 11:06:15 +02:00 committed by GitHub
parent ad4425aac3
commit 5fc5003fdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 658 additions and 1 deletions

View File

@ -1 +1,24 @@
# Godot-Voxel-Prototype
# Voxel Prototype
# Licenses: code: LGPL-2.1, media: CC BY-SA-4.0
## this is a Godot game project: https://godotengine.org
![Screenshot](/screenshot.PNG)
**Notes**
1. i like to do things simple, the result is more performance + a less confused coder.
1. this was a very early step in my game progress.
1. i dont know why the water looks wierd.
1. i dont know why the player is shaking.
1. i have no desire to make a save game system or update this project anymore.
1. just enyoy
|Action|Control|
|----|----|
|Move|A,S,D,W,S|
|Jump|Space|
Fly/Walk mode|F|
Fly up/down|Q,E|
Fly slow|SHIFT|
Choose block|scroll up/down|

140
chunk.gd Normal file
View File

@ -0,0 +1,140 @@
extends Spatial
var timer = 0
var chunks_in_progress = {}
var progress2del = {}
func _init():
core.chunk=self
#creates a new chunk array
#adds air to it so the player not reaching a empty space and things craches
func new_chunk(pos):
var id = pos_to_chunkid(pos)
var chunk_pos = to_chunk_pos(pos)
var air = core.get_node_reg("air").id
for x in range(-core.chunk_size/2,core.chunk_size/2):
for y in range(-core.chunk_size/2,core.chunk_size/2):
for z in range(-core.chunk_size/2,core.chunk_size/2):
core.inset_map_node_id(air,chunk_pos+Vector3(x,y,z))
core.chunks[id] = MeshInstance.new()
var chunk = core.chunks[id]
chunk.transform.origin = chunk_pos
add_child(chunk)
var staticbody = StaticBody.new()
staticbody.name = "body"
chunk.add_child(staticbody)
var collision = CollisionShape.new()
collision.name = "collision"
staticbody.add_child(collision)
func to_chunk_pos(pos):
var c = core.chunk_size
var s = core.chunk_size/2
return ((pos+Vector3(s,s,s))/c).floor()*c
func get_chunk_at_pos(pos):
var c = core.chunk_size
var s = core.chunk_size/2
var c_pos = ((pos+Vector3(s,s,s))/c).floor()
return core.chunks.get(c_pos)
func pos_to_chunkid(pos):
var c = core.chunk_size
var s = core.chunk_size/2
return ((pos+Vector3(s,s,s))/c).floor()
func get_chunk(id):
return core.chunks.get(id)
#sends chunks to update in a list to process
#this keeps performance well, even we can expect somewhat slower loading
func _process(delta):
timer += delta
if timer > 0.0:
timer = 0
for i in progress2del:
chunks_in_progress.erase(i)
progress2del.clear()
var max_nodes = core.settings.max_update_nodes
for di in chunks_in_progress:
var data = chunks_in_progress.get(di)
var chunk_mesh = get_chunk(data.chunkid)
for x in range(data.range_x.a,data.range_x.b):
for y in range(data.range_y.a,data.range_y.b):
for z in range(data.range_z.a,data.range_z.b):
max_nodes -= 1
if max_nodes < 0:
data.range_x.a = x
data.range_y.a = y
data.range_z.a = z
return
var lpos = Vector3(x,y,z)
var id = core.map.get(lpos+data.chunk_pos)
if id:
var n = core.register.id.get(id) if id != null else "default"
var reg = core.register.nodes.get(n)
var tile = core.default_texture if reg.tiles.size() < 1 else reg.tiles[0]
if reg.drawtype != "none":
for f in core.default_node.faces.size():
var neighbour_id = core.map.get(lpos+core.default_node.dir[f]+data.chunk_pos)
var neighbour_name = core.register.id.get(neighbour_id) if neighbour_id != null else "none"
var neighbour_reg = core.register.nodes.get(neighbour_name)
if (data.full_cubes and neighbour_id == null) or (neighbour_id != id and neighbour_reg.get("solid_surface") == false):
data.st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN)
var mat = SpatialMaterial.new()
var transparent = reg.get("transparent") == true
if f < reg.tiles.size():
tile = reg.tiles[f]
mat.albedo_texture = tile
mat.flags_transparent = transparent
data.st.set_material(mat)
data.st.add_color(Color(0,1,1))
var cmf = []
for v in range(0,4):
data.st.add_uv(core.default_node.uv[v])
data.st.add_vertex(core.default_node.faces[f][v]+lpos)
cmf.push_back(core.default_node.faces[f][v]+lpos)
data.st.commit(data.mesh)
# the faces is added, now add to the collision
# the TRIANGLE_FAN allows us to be more flexible models, but the trimesh do not work with it
# so we are using TRIANGLES for that
if reg.get("collidable") != false:
data.cst.begin(Mesh.PRIMITIVE_TRIANGLES)
data.cst.add_triangle_fan(cmf)
data.cst.commit(data.collision_mesh)
data.st.clear()
data.cst.clear()
chunk_mesh.mesh = data.mesh
chunk_mesh.get_node_or_null("body/collision").shape = data.collision_mesh.create_trimesh_shape()
chunks_in_progress.erase(di)
progress2del[di] = di
# the chunk is done, now work on next update
func update(pos):
if get_chunk_at_pos(pos) == null:
new_chunk(pos)
#no chunk here, generate it quickly
core.current_mapgen.call_func(to_chunk_pos(pos))
return
var chunkid = pos_to_chunkid(pos)
var data = {
vertex = {},
full_cubes = core.settings.full_3d_cubes,
mesh = Mesh.new(),
collision_mesh = Mesh.new(),
chunkid = chunkid,
chunk_pos = get_chunk(chunkid).transform.origin,
st = SurfaceTool.new(),
cst = SurfaceTool.new(),
range_x = {a=-core.chunk_size/2,b=core.chunk_size/2},
range_y = {a=-core.chunk_size/2,b=core.chunk_size/2},
range_z = {a=-core.chunk_size/2,b=core.chunk_size/2},
}
chunks_in_progress[chunkid] = data

7
chunk.tscn Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://chunk.gd" type="Script" id=1]
[node name="chunks" type="Spatial"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.5, -0.5 )
script = ExtResource( 1 )

125
core.gd Normal file
View File

@ -0,0 +1,125 @@
extends Node
var chunk #noderef functions
var chunks = {} #contains all chucks, using Vector3() as keys or "id"
var chunk_size=8#16 are more common for this kind of game, but is 4X slower to update
var default_texture = load("res://res/stone.png")#used if we are unable to get the nodes tiles
var player = {name="singleplayer",object=null,inventory=["stone","dirt","grassy","water_source"],inventory_index=0}
var map = {}#contains all nodes, using Vector3() as keys or "id", contains a number/node id, strings would use too much memory
var collision_map = {}
var settings = {
full_3d_cubes=false,
update_chunk_rules=[Vector3(-1,0,0),Vector3(1,0,0),Vector3(0,0,-1),Vector3(0,0,1),Vector3(0,-1,0),Vector3(0,1,0)],
ganerate_chunk_range=4,
max_update_nodes=512,
}
var default_node_id = 7
var mapgen = {}
var current_mapgen # funcref
var register = {
nodes = {
none={id=0,name="none",drawtype="none",tiles=[]},
air={id=1,name="air",drawtype="none",tiles=[],collidable=false,solid_surface=false},
stone={id=2,name="stone",drawtype="default",tiles=[load("res://res/stone.png")]},
grassy={id=3,name="grassy",drawtype="default",tiles=[
load("res://res/grass.png"),
load("res://res/dirt.png"),
load("res://res/grass_dirt.png"),
load("res://res/grass_dirt.png"),
load("res://res/grass_dirt.png"),
load("res://res/grass_dirt.png"),
]},
dirt={id=4,name="dirt",drawtype="default",tiles=[load("res://res/dirt.png")]},
water_source={id=5,name="water_source",replaceable=true,drawtype="liquid",collidable=false,transparent=true,solid_surface=false,tiles=[load("res://res/water.png")]},
},
id = {0:"none",1:"air",2:"stone",3:"grassy",4:"dirt",5:"water_source"},
}
var default_node = {
uv = [Vector2(0,0),Vector2(0,1),Vector2(1,1),Vector2(1,0)],
dir = [Vector3(0,1,0),Vector3(0,-1,0),Vector3(1,0,0),Vector3(-1,0,0),Vector3(0,0,-1),Vector3(0,0,1)],
faces = [
[Vector3(1,0,0),Vector3(1,0,1),Vector3(0,0,1),Vector3(0,0,0)], #up y+
[Vector3(0,-1,0),Vector3(0,-1,1),Vector3(1,-1,1),Vector3(1,-1,0)], #down y-
[Vector3(1,0,0),Vector3(1,-1,0),Vector3(1,-1,1),Vector3(1,0,1)], #north x+
[Vector3(0,0,1),Vector3(0,-1,1),Vector3(0,-1,0),Vector3(0,0,0)], #south x-
[Vector3(0,0,0),Vector3(0,-1,0),Vector3(1,-1,0),Vector3(1,0,0)], #east z+
[Vector3(1,0,1),Vector3(1,-1,1),Vector3(0,-1,1),Vector3(0,0,1)], #west z-
]
}
#returns name of node you are pointing at, pos would be more usefull i think
#use the penultimate pos to get the node next to it
func pointed_at_node():
var pos = player.object.get_translation()
var aim = player.object.get_node("head/Camera").get_global_transform().basis
var hpos = player.object.get_node("head").get_translation()
for i in range(-1,-500,-1):
var p = (pos + hpos+(aim.z*Vector3(i*0.01,i*0.01,i*0.01)))#.round()
var rp = p.round()
var id = map.get(rp)
var reg = get_node_reg(id)
if reg != null and reg.get("drawtype") != "none" and reg.get("collidable") != false:
if (p.x >= rp.x-0.5 and p.x <= rp.x+0.5) and (p.y >= rp.y-0.5 and p.y <= rp.y+0.5) and (p.z >= rp.z-0.5 and p.z <= rp.z+0.5):
return reg.name
return "none"
#problity you finds a better way to use this
#but this is what i used while testing
func pointed_node_action(n):
var pos = player.object.get_translation()
var aim = player.object.get_node("head/Camera").get_global_transform().basis
var hpos = player.object.get_node("head").get_translation()
var lpos = (pos + hpos+aim.z).round()
for i in range(-1,-500,-1):
var p = (pos + hpos+(aim.z*Vector3(i*0.01,i*0.01,i*0.01)))#.round()
var rp = p.round()
var id = map.get(rp)
if id and id != 1:
if core.chunk.get_chunk_at_pos(rp):
if (p.x >= rp.x-0.5 and p.x <= rp.x+0.5) and (p.y >= rp.y-0.5 and p.y <= rp.y+0.5) and (p.z >= rp.z-0.5 and p.z <= rp.z+0.5):
var node = player.inventory[player.inventory_index] if n == 0 else "air"
var pp = rp
if n == 0:
var Name = register.id[id]
var reg = register.nodes[Name]
pp = rp if reg.get("replaceable") == true else lpos
set_node({name=node,pos=pp})
return
lpos = rp
func get_node_reg(v):#a flexible way to get node properties by pos, id or name
if v is Vector3:
v = v.round()
v = map.get(v)
elif v is String:
return register.nodes.get(v)
var n = register.id.get(v)
return register.nodes.get(n)
func get_node(pos):#returns node id
assert(typeof(pos) == TYPE_VECTOR3,"ERROR: set_node: pos required!")
return map.get(pos)
func set_node(def:Dictionary):# set node
assert(typeof(def.get("pos")) == TYPE_VECTOR3 and typeof(def.get("name")) == TYPE_STRING,"ERROR: set_node: def.pos & def.name required!")
var n = register.nodes.get(def.name)
assert(n != null,str('ERROR: set_node: "',def.name,'"', " doesn't exists"))
var rpos = def.pos.round()
map[rpos] = get_node_reg(def.name).id
#check if chunks around the node need to be updated
var cid = chunk.pos_to_chunkid(rpos)
for r in settings.update_chunk_rules.size():
var near_chunk = rpos+settings.update_chunk_rules[r]
if chunk.pos_to_chunkid(near_chunk) != cid:
chunk.update(near_chunk)
#check the chunk
chunk.update(rpos)
func inset_map_node_id(id,pos):# easyer to use
map[pos] = id

7
default_env.tres Normal file
View File

@ -0,0 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

19
main.tscn Normal file
View File

@ -0,0 +1,19 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://player.tscn" type="PackedScene" id=1]
[ext_resource path="res://chunk.tscn" type="PackedScene" id=2]
[sub_resource type="Environment" id=1]
background_mode = 1
background_color = Color( 0.447059, 0.666667, 0.858824, 1 )
ambient_light_color = Color( 1, 1, 1, 1 )
[node name="main" type="Spatial"]
[node name="chunks" parent="." instance=ExtResource( 2 )]
[node name="player" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 )
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource( 1 )

72
mapgen.gd Normal file
View File

@ -0,0 +1,72 @@
extends Node
var timer = 1
func _ready():
core.current_mapgen = funcref(self,"super_flatland")
yield(get_tree().create_timer(2),"timeout")
for x in range(-4,4):
for z in range(-4,4):
core.inset_map_node_id(5,Vector3(x,0,z))
core.chunk.update(Vector3(0,0,0))
var n2gc_timer = -0.01
var n2gc_time = 0
func _process(delta):
timer += delta
if timer > n2gc_time:
if n2gc_timer >= 1:
n2gc_timer = 0
n2gc_time = 1
else:
n2gc_timer += timer
timer = 0
var ppos = core.player.object.global_transform.origin
var pos = core.chunk.to_chunk_pos(ppos)
if core.chunk.get_chunk_at_pos(pos) == null:
core.chunk.new_chunk(pos)
core.current_mapgen.call_func(pos)
n2gc_time = 0
n2gc_timer = 0
#return
for i in range(1,core.settings.ganerate_chunk_range):
var r = core.chunk_size*i
var s = core.chunk_size
for x in range(-r,r,s):
for y in range(-r,r,s):
for z in range(-r,r,s):
pos = Vector3(x,y,z) + core.chunk.to_chunk_pos(ppos)
if core.chunk.get_chunk_at_pos(pos) == null:
core.chunk.new_chunk(pos)
core.current_mapgen.call_func(pos)
n2gc_time = 0
n2gc_timer = 0
#generates a flat map:
#all nodes above 9 will be air
#0 = grassy
#-1 - -3 = dirt
#-4 and lower = stone
func super_flatland(pos):
var id
var grassy = core.get_node_reg("grassy").id
var dirt = core.get_node_reg("dirt").id
var stone = core.get_node_reg("stone").id
var air = core.get_node_reg("air").id
var Y
for x in range(-core.chunk_size/2,core.chunk_size/2):
for y in range(-core.chunk_size/2,core.chunk_size/2):
for z in range(-core.chunk_size/2,core.chunk_size/2):
Y = pos.y+y
if Y == 0:
id = grassy
elif Y < -3:
id = stone
elif Y < 0:
id = dirt
else:
id = air
core.inset_map_node_id(id,Vector3(x,y,z)+pos)
core.chunk.update(pos)

94
player.gd Normal file
View File

@ -0,0 +1,94 @@
extends KinematicBody
var direction = Vector3()
var velocity = Vector3()
var gravity = -27
var jump_height = 10
var walk_speed = 10
var fpv_camera_angle = 0
var fpv_mouse_sensitivity = 0.3
var fly_mode = false
func _ready():
core.player.object = self
#camera
func _input(event):
if Input.is_action_just_pressed("ui_cancel"):
get_tree().quit()
if event is InputEventMouseMotion:
rotate_y(deg2rad(-event.relative.x * fpv_mouse_sensitivity))
var change = -event.relative.y * fpv_mouse_sensitivity
if change + fpv_camera_angle < 90 and change + fpv_camera_angle > -90:
$head/Camera.rotate_x(deg2rad(change))
fpv_camera_angle += change
elif event is InputEventMouseButton:
if Input.is_action_just_pressed("LMB"):
core.pointed_node_action(0)
elif Input.is_action_just_pressed("RMB"):
core.pointed_node_action(1)
elif Input.is_action_just_pressed("WHEEL_UP"):
core.player.inventory_index += 1
if core.player.inventory_index >= core.player.inventory.size():
core.player.inventory_index = 0
elif Input.is_action_just_pressed("WHEEL_DOWN"):
core.player.inventory_index -= 1
if core.player.inventory_index <= 0:
core.player.inventory_index = core.player.inventory.size()-1
# moving
func _process(delta):
direction = Vector3()
var aim = $head/Camera.get_global_transform().basis
var pos = transform.origin
var con = Vector3()
if Input.is_key_pressed(KEY_W):
con -= aim.z
if Input.is_key_pressed(KEY_S):
con += aim.z
if Input.is_key_pressed(KEY_A):
con -= aim.x
if Input.is_key_pressed(KEY_D):
con += aim.x
if Input.is_action_just_pressed("fly_mode"):
fly_mode = fly_mode == false
$Collision.disabled = fly_mode
velocity = Vector3(0,0,0)
#this lines just updates the screen info
#if you are not trying to solve a problem, this 4 lines is kinda useless, and useing unnecessarily performance
ui.screeninfo("player_pos",transform.origin)
ui.screeninfo("chunk_id",core.chunk.pos_to_chunkid(transform.origin))
ui.screeninfo("chunk_pos",core.chunk.to_chunk_pos(transform.origin))
ui.screeninfo("pointing_at",core.pointed_at_node())
if fly_mode:
if Input.is_key_pressed(KEY_E):
con.y += 1
if Input.is_key_pressed(KEY_Q):
con.y -= 1
if Input.is_key_pressed(KEY_SHIFT):
con*=0.1
transform.origin += con*0.2
else:
var on_floor = is_on_floor()
direction = con
direction = direction.normalized()
if on_floor:
velocity.y = 0
else:
#if player is inside a collidable block, freeze the movement to prevent falling through the ground
var id = core.map.get(pos.round())
var n = core.register.id.get(id) if id != null else "default"
var reg = core.register.nodes.get(n)
if reg.get("collidable") != false:
velocity.y = 0
return
velocity.y += gravity * delta
var tv = velocity
tv = velocity.linear_interpolate(direction * walk_speed,15 * delta)
velocity.x = tv.x
velocity.z = tv.z
velocity = move_and_slide(velocity,Vector3(0,1,0))
# == jumping
if on_floor and Input.is_key_pressed(KEY_SPACE):
velocity.y = jump_height

27
player.tscn Normal file
View File

@ -0,0 +1,27 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://player.gd" type="Script" id=1]
[sub_resource type="CubeMesh" id=1]
[sub_resource type="SpatialMaterial" id=2]
albedo_color = Color( 1, 0, 0, 1 )
[sub_resource type="BoxShape" id=3]
[node name="player" type="KinematicBody"]
script = ExtResource( 1 )
[node name="mesh" type="MeshInstance" parent="."]
transform = Transform( 0.4, 0, 0, 0, 1, 0, 0, 0, 0.4, 0, 0, 0 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="Collision" type="CollisionShape" parent="."]
transform = Transform( 0.4, 0, 0, 0, 1, 0, 0, 0, 0.4, 0, 0, 0 )
shape = SubResource( 3 )
[node name="head" type="Spatial" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0 )
[node name="Camera" type="Camera" parent="head"]

84
project.godot Normal file
View File

@ -0,0 +1,84 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="Voxel Prototype"
run/main_scene="res://main.tscn"
config/icon="res://icon.png"
[autoload]
core="*res://core.gd"
mapgen="*res://mapgen.gd"
ui="*res://ui.tscn"
[display]
window/stretch/mode="viewport"
[importer_defaults]
texture={
"compress/bptc_ldr": 0,
"compress/hdr_mode": 0,
"compress/lossy_quality": 0.7,
"compress/mode": 2,
"compress/normal_map": 0,
"detect_3d": false,
"flags/anisotropic": false,
"flags/filter": false,
"flags/mipmaps": true,
"flags/repeat": true,
"flags/srgb": 1,
"process/HDR_as_SRGB": false,
"process/fix_alpha_border": false,
"process/invert_color": false,
"process/premult_alpha": false,
"size_limit": 0,
"stream": false,
"svg/scale": 1.0
}
[input]
fly_mode={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null)
]
}
LMB={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
]
}
RMB={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":2,"pressed":false,"doubleclick":false,"script":null)
]
}
WHEEL_UP={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":4,"pressed":false,"doubleclick":false,"script":null)
]
}
WHEEL_DOWN={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":5,"pressed":false,"doubleclick":false,"script":null)
]
}
[physics]
common/enable_pause_aware_picking=true
[rendering]
environment/default_environment="res://default_env.tres"

BIN
res/crosshair.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

BIN
res/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

BIN
res/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

BIN
res/grass_dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
res/stone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
res/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
screenshot.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

29
ui.gd Normal file
View File

@ -0,0 +1,29 @@
extends Control
var _screeninfo = {
player_pos = Vector3(),
chunk_id = Vector3(),
chunk_pos = Vector3(),
pointing_at = "",
}
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
var ss = get_viewport_rect().size/2
var cs = $crosshair.rect_size / 2
$crosshair.rect_position = ss - cs
var p = OS.get_screen_size()/2
var s = OS.window_size/2
var winpos = p-s
winpos.y = 0 #now we can see the output
OS.set_window_position(winpos)
#if you are not trying to solve a problem, this one is kinda useless
func screeninfo(lab,v):
_screeninfo[lab] = v
var s = _screeninfo.player_pos.round()
var c = _screeninfo.chunk_id
var p = _screeninfo.chunk_pos
$screeninfo.text = str("Pos: ",s.x,",",s.y,",",s.z," Chunk ID: ",c.x,",",c.y,",",c.z," Chunk pos: ",p.x,",",p.y,",",p.z," Pointing at: ",_screeninfo.pointing_at)

30
ui.tscn Normal file
View File

@ -0,0 +1,30 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://ui.gd" type="Script" id=1]
[ext_resource path="res://res/crosshair.png" type="Texture" id=2]
[node name="ui" type="Control"]
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="crosshair" type="TextureRect" parent="."]
margin_left = 60.1041
margin_top = 207.182
margin_right = 80.1041
margin_bottom = 227.182
texture = ExtResource( 2 )
expand = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="screeninfo" type="Label" parent="."]
margin_right = 108.0
margin_bottom = 15.0
rect_scale = Vector2( 2, 2 )
text = "Pos:, Chunk ID:, Pointing at:"
__meta__ = {
"_edit_use_anchors_": false
}