pull/7/head
Valentin Stark 3 years ago
parent 987cb61c1f
commit 8b7788fe49
  1. 19
      project.godot
  2. 98
      utils/camera/CamBase.gd
  3. 33
      utils/camera/CamBase.tscn
  4. 140
      utils/camera/CameraController.gd
  5. 158
      utils/camera/CameraInput.gd
  6. 17
      utils/camera/SelectionBox.gd
  7. 12
      world/game.tscn

@ -9,6 +9,11 @@
config_version=4
_global_script_classes=[ {
"base": "Camera",
"class": "CameraController",
"language": "GDScript",
"path": "res://utils/camera/CameraController.gd"
}, {
"base": "Reference",
"class": "Delaunator",
"language": "GDScript",
@ -25,6 +30,7 @@ _global_script_classes=[ {
"path": "res://utils/terrain/Terrain.gd"
} ]
_global_script_class_icons={
"CameraController": "",
"Delaunator": "",
"PoissonDiscSampling": "",
"Terrain": ""
@ -40,6 +46,19 @@ config/icon="res://icon.png"
common/drop_mouse_on_gui_input_disabled=true
[input]
main_command={
"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)
]
}
alt_command={
"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)
]
}
[physics]
common/enable_pause_aware_picking=true

@ -0,0 +1,98 @@
extends Spatial
const MOVE_MARGIN = 20
const MOVE_SPEED = 30
const ray_length = 1000
onready var cam = $Camera
var team = 0
var selected_units = []
onready var selection_box = $SelectionBox
var start_sel_pos = Vector2()
func _process(delta):
var m_pos = get_viewport().get_mouse_position()
# calc_move(m_pos, delta)
if Input.is_action_just_pressed("main_command"):
move_selected_units(m_pos)
if Input.is_action_just_pressed("alt_command"):
selection_box.start_sel_pos = m_pos
start_sel_pos = m_pos
if Input.is_action_pressed("alt_command"):
selection_box.m_pos = m_pos
selection_box.is_visible = true
else:
selection_box.is_visible = false
if Input.is_action_just_released("alt_command"):
select_units(m_pos)
func calc_move(m_pos, delta):
var v_size = get_viewport().size
var move_vec = Vector3()
if m_pos.x < MOVE_MARGIN:
move_vec.x -= 1
if m_pos.y < MOVE_MARGIN:
move_vec.z -= 1
if m_pos.x > v_size.x - MOVE_MARGIN:
move_vec.x += 1
if m_pos.y > v_size.y - MOVE_MARGIN:
move_vec.z += 1
move_vec = move_vec.rotated(Vector3(0, 1, 0), rotation_degrees.y)
global_translate(move_vec * delta * MOVE_SPEED)
func move_selected_units(m_pos):
var result = raycast_from_mouse(m_pos, 1)
if result:
var unit_index = 0
for unit in selected_units:
var new_position = result.position
new_position.x = new_position.x + unit_index
unit.move_to(new_position)
unit_index += 1
func select_units(m_pos):
var new_selected_units = []
if m_pos.distance_squared_to(start_sel_pos) < 16:
var u = get_unit_under_mouse(m_pos)
if u != null:
new_selected_units.append(u)
else:
new_selected_units = get_units_in_box(start_sel_pos, m_pos)
for unit in selected_units:
unit.deselect()
for unit in new_selected_units:
unit.select()
selected_units = new_selected_units
func get_unit_under_mouse(m_pos):
var result = raycast_from_mouse(m_pos, 3)
if result and result.collider.is_in_group("units"):
return result.collider
func get_units_in_box(top_left, bot_right):
if top_left.x > bot_right.x:
var tmp = top_left.x
top_left.x = bot_right.x
bot_right.x = tmp
if top_left.y > bot_right.y:
var tmp = top_left.y
top_left.y = bot_right.y
bot_right.y = tmp
var box = Rect2(top_left, bot_right - top_left)
var box_selected_units = []
for unit in get_tree().get_nodes_in_group("units"):
if box.has_point(cam.unproject_position(unit.global_transform.origin)):
box_selected_units.append(unit)
return box_selected_units
func raycast_from_mouse(m_pos, collision_mask):
var ray_start = cam.project_ray_origin(m_pos)
var ray_end = ray_start + cam.project_ray_normal(m_pos) * ray_length
var space_state = get_world().direct_space_state
return space_state.intersect_ray(ray_start, ray_end, [], collision_mask)
func _on_Camera_camera_moved(new_location):
pass # Replace with function body.

@ -0,0 +1,33 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://utils/camera/SelectionBox.gd" type="Script" id=1]
[ext_resource path="res://utils/camera/CamBase.gd" type="Script" id=2]
[ext_resource path="res://utils/camera/CameraController.gd" type="Script" id=3]
[ext_resource path="res://utils/camera/CameraInput.gd" type="Script" id=4]
[node name="CamBase" type="Spatial"]
transform = Transform( 1, 0, 0, 0, 0.34202, 0.939693, 0, -0.939693, 0.34202, 0, 0, 0 )
script = ExtResource( 2 )
[node name="Camera" type="Camera" parent="."]
size = 20.0
near = 0.01
far = 8192.0
script = ExtResource( 3 )
movement_speed = 70.017
min_zoom = 51.0
zoom_sensibility = 2.818
rotation_sensibility = 1.0
[node name="Node" type="Node" parent="Camera"]
script = ExtResource( 4 )
[node name="SelectionBox" type="Control" parent="."]
margin_right = 40.0
margin_bottom = 40.0
script = ExtResource( 1 )
[connection signal="on_change_action" from="Camera/Node" to="Camera" method="change_action"]
[connection signal="on_change_velocity" from="Camera/Node" to="Camera" method="change_velocity"]
[connection signal="on_rotate_view" from="Camera/Node" to="Camera" method="rotate_view"]
[connection signal="on_zoom" from="Camera/Node" to="Camera" method="zoom"]

@ -0,0 +1,140 @@
extends Camera
class_name CameraController
signal camera_moved(new_location)
enum CAMERA_ACTIONS{
MOVING,
ROTATING_VIEW,
}
export(float,1,100) var movement_speed = 30
export(float,0.01,0.99) var movement_damping = 0.74
export(float,0.01, 3.1415) var max_rotation = 1.2
export(float,0.01, 3.1415) var min_rotation = 0.5
#Value in percentage of screen portion
#A value of 0.3 means that when you place the cursor 30% or less away from an edge it will start pushing the camera
export(float, 0.0,1.0) var edge_size = 0.0
#EDIT HERE--->**,***<--- ZOOM MIN AND MAX LIMITS
export(float, 10,100) var min_zoom = 25
export(float, 10,100) var max_zoom = 100
export(float, 1,3) var zoom_sensibility = 2.5
export(float, 1,3) var rotation_sensibility = 2.3
export(float, 1.0, 10.0) var height = 5.0
var pitch : float
var yaw : float
var current_action = CAMERA_ACTIONS.MOVING
var velocity : Vector2
func _ready():
# Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
pitch = rotation.x
yaw = rotation.y
# var new_rotation = (max_zoom - fov) * (max_rotation - min_rotation) / max_zoom + min_rotation
transform.basis = Basis(Vector3(1, 0, 0), (min_rotation + max_rotation) / 2.0)
fov = (min_zoom + max_zoom) / 2.0
func change_action(action):
current_action = action
match(current_action):
# CAMERA_ACTIONS.MOVING:
# Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
CAMERA_ACTIONS.ROTATING_VIEW:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(delta):
match(current_action):
CAMERA_ACTIONS.MOVING:
#CAMERA MOVEMENT
velocity.x = clamp(velocity.x * movement_damping,-1.0,1.0)
velocity.y = clamp(velocity.y * movement_damping,-1.0,1.0)
if velocity != Vector2.ZERO:
move(velocity)
func change_velocity(_velocity : Vector2):
velocity = _velocity
func move(_velocity : Vector2):
#Move along cameras X axis
global_transform.origin += global_transform.basis.x * velocity.x * movement_speed * get_process_delta_time()
#Calculate a forward camera direction that is perpendicular to the XZ plane
var forward = global_transform.basis.x.cross(Vector3.UP)
#Move the camera along that forward direction
global_transform.origin += forward * velocity.y * movement_speed * get_process_delta_time()
var y_offset = 0
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(Vector3(global_transform.origin.x, 100, global_transform.origin.z), Vector3(global_transform.origin.x, 0, global_transform.origin.z))
if result:
y_offset = result.position.y
else:
y_offset = 0
global_transform.origin.y = max(10 + y_offset * 1.3, 30)
emit_signal("camera_moved", global_transform.origin)
func zoom(direction : float):
#Zooming using fov
var new_fov = fov + (sign(direction) * pow(abs(direction),zoom_sensibility)/100 * get_process_delta_time())
fov = clamp(new_fov,min_zoom,max_zoom)
# Linear equation
var slope = (min_rotation - max_rotation) / (max_zoom - min_zoom)
var b = max_rotation - slope * min_zoom
var new_rotation = slope * fov + b
transform.basis = Basis(Vector3(1, 0, 0), new_rotation)
func rotate_view(axis : Vector2):
var pitch_rotation_amount = -axis.y/100 * get_process_delta_time() * rotation_sensibility
var yaw_rotation_amount = -axis.x/100 * get_process_delta_time() * rotation_sensibility
pitch += pitch_rotation_amount
pitch = clamp(pitch,-PI/2,0)
yaw += yaw_rotation_amount
rotation.x = pitch
rotation.y = yaw
func _on_Map_map_clicked(position):
global_transform.origin.x = position.x
global_transform.origin.z = position.y
var y_offset = 0
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(Vector3(global_transform.origin.x, 100, global_transform.origin.z), Vector3(global_transform.origin.x, 0, global_transform.origin.z))
if result:
y_offset = result.position.y
else:
y_offset = 0
global_transform.origin.y = max(height + y_offset * 1.3, 30)
pass # Replace with function body.
func _on_World_character_created(position):
global_transform.origin.x = position.x
global_transform.origin.z = position.y
var y_offset = 0
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(Vector3(global_transform.origin.x, 100, global_transform.origin.z), Vector3(global_transform.origin.x, 0, global_transform.origin.z))
if result:
y_offset = result.position.y
else:
y_offset = 0
global_transform.origin.y = max(height + y_offset * 1.3, 30)
pass # Replace with function body.

@ -0,0 +1,158 @@
extends Node
export(float,0.001,1.0) var screen_edge_size : float = 0.3
export(float) var mouse_wheel_damping = 0.9
#USED TO CALCULATE RAW MOVEMENT WHILE PUSHING AN EDGE
var horizontal : float = 0.0
var vertical : float = 0.0
#USED TO STORE MOUSE WHEEL INERTIA TO ENABLE SMOOTH STOPPING
var mouse_wheel : float = 0.0
signal on_change_velocity(velocity)
signal on_rotate_view(relative)
signal on_change_action(new_state)
signal on_zoom(value)
var current_action
#TOUCH VARIABLE FOR MOBILE
var touch_count : int = 0
var swipe_start : Vector2
func _ready():
connect("on_change_action",self,"change_action")
emit_signal("on_change_action",CameraController.CAMERA_ACTIONS.MOVING)
func change_action(action):
current_action = action
func toggle_action():
current_action = 1 - current_action
func start_swipe(position : Vector2):
swipe_start = position
func move_swipe(position : Vector2):
if blocked_movement:
return
var delta = (position - swipe_start)*-1
var direction_x = sign(delta.x)
var direction_y = sign(delta.y)
var view_size = get_viewport().get_visible_rect().size - Vector2.ONE
horizontal = range_lerp(abs(delta.x),0,view_size.x,0.0,1.0)
vertical = range_lerp(abs(delta.y),0,view_size.y,0.0,1.0)
#Applies direction
horizontal *= direction_x
vertical *= direction_y
var touches = [ Vector2.ZERO, Vector2.ZERO ]
var start_pinch_distance : float
var last_pinch_distance : float
var pinching : float
var blocked_movement : bool = false
func _input(event):
if OS.get_name() == "Android" or OS.get_name() == "iOS":
#MOBILE##############
if event is InputEventScreenTouch:
#SET TOUCH STARTING POSTIION
touches[event.index] = event.position
if event.pressed:
touch_count += 1
start_swipe(event.position)
else:
touch_count -= 1
#RENABLE SWIPE MOVEMENT BECAUSE EVERY TOUCH WAS LIFTED
if blocked_movement and touch_count <= 0:
blocked_movement = false
#RESET PINCHING VALUE WHEN A NEW TOUCH IS DETECTED OR HAS BEEN LIFTED
pinching = 0.0
if touch_count == 2:
#STARTED ZOOMING, BLOCK MOVEMENT UNTIL EVERY TOUCH IS LIFTED
blocked_movement = true
start_pinch_distance = (touches[1] - touches[0]).length()
if event is InputEventScreenDrag:
if touch_count == 2:
#UPDATE TOUCHES POSITIONS
touches[event.index] = event.position
#CALCULATE DISTANCE BETWEEN TOUCHES
var pinch_distance = (touches[1] - touches[0]).length()
var pinch_direction = 1 if pinch_distance > last_pinch_distance else -1
#CALCULATE PINCH DELTA
pinching = abs(start_pinch_distance - pinch_distance) * pinch_direction
#USE MOUSE WHEEL BUFFER TO ENABLE SMOOTHING
mouse_wheel += pinching * get_process_delta_time()
last_pinch_distance = pinch_distance
else:
if current_action == CameraController.CAMERA_ACTIONS.MOVING:
move_swipe(event.position)
elif current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
emit_signal("on_rotate_view",event.relative)
###############MOBILE
else:
#PC##################
#Camera edge pushing
if event is InputEventMouseMotion:
#ROTATE VIEW
if current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
emit_signal("on_rotate_view",event.relative)
#Gets screen size
var view_size = get_viewport().get_visible_rect().size - Vector2.ONE
#Get mouse position in percentage values relative to the screen
var delta = (event.position) / view_size
#Convert it to a range between [-1,1]
delta = (delta * 2) - Vector2.ONE
if current_action == CameraController.CAMERA_ACTIONS.MOVING:
#Store it an buffer to use it on _process
#Calculates delta based on percentage between the edge size and the actual edge
horizontal = max(abs(delta.x) - (1.0 - screen_edge_size),0)
vertical = max(abs(delta.y) - (1.0 - screen_edge_size),0)
#Converts it to an [0.0,1.0] range
horizontal = range_lerp(horizontal,0.0,screen_edge_size,0.0,1.0)
vertical = range_lerp(vertical,0.0,screen_edge_size,0.0,1.0)
#Applies direction
horizontal *= sign(delta.x)
vertical *= sign(delta.y)
elif current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
horizontal = delta.x
vertical = delta.y
pass
if event is InputEventMouseButton:
#WHEEL SCROLL
if event.button_index == BUTTON_WHEEL_UP or event.button_index == BUTTON_WHEEL_DOWN:
if event.pressed and not event.is_echo():
var direction = (-1 if event.button_index == BUTTON_WHEEL_UP else 0) + (1 if event.button_index == BUTTON_WHEEL_DOWN else 0)
mouse_wheel += direction * get_process_delta_time() * 1000
###################PC
func _process(delta):
#PC######
match(current_action):
CameraController.CAMERA_ACTIONS.MOVING:
#RESIDUAL MOVEMENT
if horizontal != 0 or vertical != 0:
emit_signal("on_change_velocity",Vector2(horizontal, vertical))
#MOUSE WHEEL
if mouse_wheel != 0:
mouse_wheel = mouse_wheel * mouse_wheel_damping
emit_signal("on_zoom",mouse_wheel)
#######PC

@ -0,0 +1,17 @@
extends Control
var is_visible = false
var m_pos = Vector2()
var start_sel_pos = Vector2()
const sel_box_col = Color(0, 1, 0)
const sel_box_line_width = 3
func _draw():
if is_visible and start_sel_pos != m_pos:
draw_line(start_sel_pos, Vector2(m_pos.x, start_sel_pos.y), sel_box_col, sel_box_line_width)
draw_line(start_sel_pos, Vector2(start_sel_pos.x, m_pos.y), sel_box_col, sel_box_line_width)
draw_line(m_pos, Vector2(m_pos.x, start_sel_pos.y), sel_box_col, sel_box_line_width)
draw_line(m_pos, Vector2(start_sel_pos.x, m_pos.y), sel_box_col, sel_box_line_width)
func _process(delta):
update()

@ -1,9 +1,10 @@
[gd_scene load_steps=6 format=2]
[gd_scene load_steps=7 format=2]
[ext_resource path="res://ui/ui.tscn" type="PackedScene" id=1]
[ext_resource path="res://world/game.gd" type="Script" id=2]
[ext_resource path="res://world/default_env.tres" type="Environment" id=3]
[ext_resource path="res://world/World.gd" type="Script" id=4]
[ext_resource path="res://utils/camera/CamBase.tscn" type="PackedScene" id=5]
[sub_resource type="PlaneMesh" id=1]
size = Vector2( 2000, 2000 )
@ -13,6 +14,9 @@ script = ExtResource( 2 )
[node name="UI" parent="." instance=ExtResource( 1 )]
[node name="Map" parent="UI" index="0"]
scale = Vector2( 0.25, 0.25 )
[node name="World" type="Spatial" parent="."]
script = ExtResource( 4 )
@ -23,12 +27,10 @@ mesh = SubResource( 1 )
[node name="WorldEnvironment" type="WorldEnvironment" parent="World"]
environment = ExtResource( 3 )
[node name="Camera" type="Camera" parent="World"]
transform = Transform( 1, 0, 0, 0, 0.509837, 0.860271, 0, -0.860271, 0.509837, 0, 5.05008, 66.6125 )
near = 0.01
far = 8192.0
[node name="CamBase" parent="World" instance=ExtResource( 5 )]
[connection signal="world_loaded" from="." to="UI/Map" method="_on_Game_world_loaded"]
[connection signal="world_loaded" from="." to="World" method="_on_Game_world_loaded"]
[editable path="UI"]
[editable path="World/CamBase"]

Loading…
Cancel
Save