├── TrailRenderer ├── TrailRender.tscn ├── Main.tscn └── TrailRender.gd ├── README.md ├── PlaneController ├── PlaneController.gd └── Main.tscn └── TrailRenderScriptClass └── TrailRender.gd /TrailRenderer/TrailRender.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/TrailRenderTutorial/TrailRender.gd" type="Script" id=1] 4 | 5 | [node name="TrailRender" type="Spatial"] 6 | script = ExtResource( 1 ) 7 | 8 | [node name="Node" type="Node" parent="."] 9 | 10 | [node name="Render" type="MeshInstance" parent="Node"] 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GODOG FIGHT 2 | 3 | This is an implementation of a dog fight game in Godot 3.2.2 4 | ## Importent note: 5 | If you want to use the trail renderer in your project simply copy the file `TrailRender.gd` from the `TrailRenderScriptClass` folder. 6 | By simply saving it in your project you will get a new node called `TrailRenderer` which is a standalone version of the trail renderer showed on the tutorial... trail renderer :-) 7 | -------------------------------------------------------------------------------- /TrailRenderer/Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://src/CameraTutorial/PlaneController.gd" type="Script" id=1] 4 | [ext_resource path="res://src/TrailRenderTutorial/TrailRender.tscn" type="PackedScene" id=3] 5 | 6 | [sub_resource type="Curve" id=1] 7 | _data = [ Vector2( 0, 0.4 ), 0.0, 0.0, 0, 0, Vector2( 0.351648, 0.790909 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ] 8 | 9 | [sub_resource type="SpatialMaterial" id=2] 10 | albedo_color = Color( 0.909804, 0.501961, 0.105882, 1 ) 11 | 12 | [node name="Main" type="Node"] 13 | 14 | [node name="World" type="Spatial" parent="."] 15 | 16 | [node name="RtsCameraController" type="Camera" parent="World"] 17 | script = ExtResource( 1 ) 18 | 19 | [node name="Plane" parent="World/RtsCameraController" instance=ExtResource( 3 )] 20 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.966, -5.623 ) 21 | width = 2.0 22 | width_curve = SubResource( 1 ) 23 | max_points = 50 24 | material = SubResource( 2 ) 25 | -------------------------------------------------------------------------------- /PlaneController/PlaneController.gd: -------------------------------------------------------------------------------- 1 | extends Camera 2 | 3 | 4 | ######################### 5 | # EXPORT PARAMS 6 | ######################### 7 | # speed 8 | export (float, 1, 100) var speed = 10 9 | export (float, 1, 3, 0.1) var turbo_modifier = 2 10 | # yaw 11 | export (float, 1, 100) var yaw_speed = 10 12 | export (float, 10, 180, 1) var max_yaw = 70 13 | # roll 14 | export (float, 10, 180, 1) var max_roll = 70 15 | export (float, 1, 100) var pitch_speed = 10 16 | # pitch 17 | export (float, 10, 180, 1) var max_pitch = 30 18 | export (float, 3, 10, 0.5) var turbo_time = 5 19 | 20 | 21 | ######################### 22 | # PARAMS 23 | ######################### 24 | onready var model = $Plane 25 | 26 | 27 | ######################### 28 | # OVERRIDE FUNCTIONS 29 | ######################### 30 | func _process(delta: float) -> void: 31 | _move(delta) 32 | _pitch(delta) 33 | _yaw(delta) 34 | 35 | 36 | ######################### 37 | # MOVEMENT FUNCTIONS 38 | ######################### 39 | func _move(delta: float) -> void: 40 | translation -= transform.basis.z * delta * speed 41 | 42 | 43 | func _pitch(delta: float) -> void: 44 | var mouse_speed = _get_mouse_speed() 45 | rotation_degrees.x += mouse_speed.y * delta * pitch_speed 46 | var amount = abs(mouse_speed.y) 47 | var direction = sign(mouse_speed.y) 48 | model.rotation_degrees.x = lerp(0, max_pitch, amount) * direction 49 | 50 | 51 | func _yaw(delta: float) -> void: 52 | var mouse_speed = _get_mouse_speed() 53 | rotation_degrees.y += mouse_speed.x * delta * pitch_speed 54 | _roll_and_yaw_model(mouse_speed.x, delta) 55 | 56 | 57 | func _roll_and_yaw_model(mouse_speed_x: float, delta: float) -> void: 58 | var amount = abs(mouse_speed_x) 59 | var direction = sign(mouse_speed_x) 60 | model.rotation_degrees.y = lerp(0, max_yaw, amount) * direction 61 | model.rotation_degrees.z = lerp(0, max_roll, amount) * direction 62 | 63 | ######################### 64 | # HELPER FUNCTIONS 65 | ######################### 66 | func _get_mouse_speed() -> Vector2: 67 | var screen_center = get_viewport().size * 0.5 68 | var displacment = screen_center - get_viewport().get_mouse_position() 69 | displacment.x /= screen_center.x 70 | displacment.y /= screen_center.y 71 | return displacment 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /PlaneController/Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/old/Ground.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/old/Plane.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/CameraTutorial/PlaneController.gd" type="Script" id=3] 6 | 7 | [sub_resource type="SpatialMaterial" id=1] 8 | albedo_color = Color( 0.988235, 0.545098, 0.027451, 1 ) 9 | 10 | [sub_resource type="CubeMesh" id=2] 11 | material = SubResource( 1 ) 12 | size = Vector3( 1, 1, 1 ) 13 | 14 | [node name="Main" type="Node"] 15 | 16 | [node name="World" type="Spatial" parent="."] 17 | 18 | [node name="Scene" type="Spatial" parent="World"] 19 | 20 | [node name="Ground" parent="World/Scene" instance=ExtResource( 1 )] 21 | 22 | [node name="Box" type="MeshInstance" parent="World/Scene"] 23 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -4.79738, 0.5, 8.04267 ) 24 | mesh = SubResource( 2 ) 25 | material/0 = null 26 | 27 | [node name="Box2" type="MeshInstance" parent="World/Scene"] 28 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.25432, 0.5, -5.78508 ) 29 | mesh = SubResource( 2 ) 30 | material/0 = null 31 | 32 | [node name="Box3" type="MeshInstance" parent="World/Scene"] 33 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 22.0821, 0.5, 15.5209 ) 34 | mesh = SubResource( 2 ) 35 | material/0 = null 36 | 37 | [node name="Box4" type="MeshInstance" parent="World/Scene"] 38 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 22.0821, 0.5, -18.3429 ) 39 | mesh = SubResource( 2 ) 40 | material/0 = null 41 | 42 | [node name="Box5" type="MeshInstance" parent="World/Scene"] 43 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -26.3151, 0.5, 9.66531 ) 44 | mesh = SubResource( 2 ) 45 | material/0 = null 46 | 47 | [node name="Box6" type="MeshInstance" parent="World/Scene"] 48 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -11.7818, 0.5, -14.251 ) 49 | mesh = SubResource( 2 ) 50 | material/0 = null 51 | 52 | [node name="PlaneController" type="Camera" parent="World"] 53 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 19.946, 51.1794 ) 54 | script = ExtResource( 3 ) 55 | speed = 20.0 56 | yaw_speed = 40.0 57 | max_yaw = 40.0 58 | max_roll = 90.0 59 | pitch_speed = 40.0 60 | 61 | [node name="Plane" parent="World/PlaneController" instance=ExtResource( 2 )] 62 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -3 ) 63 | -------------------------------------------------------------------------------- /TrailRenderer/TrailRender.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | 4 | ############################# 5 | # EXPORT PARAMS 6 | ############################# 7 | # width 8 | export var width: float = 0.5 9 | export var width_curve: Curve 10 | # length 11 | export var max_points := 100 12 | export var material: Material 13 | # show or hide 14 | export var render: bool = true 15 | 16 | 17 | ############################# 18 | # PARAMS 19 | ############################# 20 | onready var half_width = width * 0.5 21 | var points := [] 22 | 23 | 24 | ############################# 25 | # OVERRIDE FUNCTIONS 26 | ############################# 27 | func _process(delta: float) -> void: 28 | if render: 29 | # add new point and render 30 | add_point() 31 | _draw_trail() 32 | else: 33 | # slowly hide the trail 34 | if points.size() > 0: 35 | var last_point = points.pop_back() 36 | last_point.queue_free() 37 | 38 | 39 | ############################# 40 | # API 41 | ############################# 42 | func add_point() -> void: 43 | var new_point = Position3D.new() 44 | new_point.translation = self.global_transform.origin 45 | new_point.rotation = self.global_transform.basis.get_euler() 46 | points.insert(0, new_point) 47 | if points.size() > max_points: 48 | var last_point = points.pop_back() 49 | last_point.queue_free() 50 | 51 | 52 | func _draw_trail() -> void: 53 | if points.size() < 2: 54 | return 55 | # create surface tool 56 | var st = SurfaceTool.new() 57 | st.begin(Mesh.PRIMITIVE_TRIANGLES) 58 | # draw triangles 59 | for i in range(points.size() - 1): 60 | _points_to_rect(st, points[i], points[i + 1], i) 61 | # commit 62 | st.generate_normals() 63 | # st.generate_tangents() 64 | $Node/Render.mesh = st.commit() 65 | $Node/Render.set_surface_material(0, material) 66 | 67 | 68 | func _points_to_rect(st: SurfaceTool, p1: Position3D, p2: Position3D, idx: float) -> void: 69 | var num_points = points.size() - 1 70 | 71 | var offset1 = idx / num_points 72 | var mod1 = half_width * width_curve.interpolate(offset1) 73 | 74 | var v1 = p1.translation + p1.transform.basis.x * mod1 75 | var uv1 = Vector2(0, offset1) 76 | 77 | var v2 = p1.translation - p1.transform.basis.x * mod1 78 | var uv2 = Vector2(1, offset1) 79 | 80 | var offset2 = (idx + 1) / num_points 81 | var mod2 = half_width * width_curve.interpolate(offset2) 82 | 83 | var v3 = p2.translation + p2.transform.basis.x * mod2 84 | var uv3 = Vector2(0, offset2) 85 | 86 | var v4 = p2.translation - p2.transform.basis.x * mod2 87 | var uv4 = Vector2(1, offset2) 88 | 89 | st.add_uv(uv1) 90 | st.add_vertex(v1) 91 | st.add_uv(uv2) 92 | st.add_vertex(v2) 93 | st.add_uv(uv3) 94 | st.add_vertex(v3) 95 | 96 | st.add_uv(uv3) 97 | st.add_vertex(v3) 98 | st.add_uv(uv2) 99 | st.add_vertex(v2) 100 | st.add_uv(uv1) 101 | st.add_vertex(v1) 102 | 103 | st.add_uv(uv3) 104 | st.add_vertex(v3) 105 | st.add_uv(uv4) 106 | st.add_vertex(v4) 107 | st.add_uv(uv2) 108 | st.add_vertex(v2) 109 | 110 | st.add_uv(uv2) 111 | st.add_vertex(v2) 112 | st.add_uv(uv4) 113 | st.add_vertex(v4) 114 | st.add_uv(uv3) 115 | st.add_vertex(v3) 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /TrailRenderScriptClass/TrailRender.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name TrailRenderer 3 | 4 | ############################# 5 | # EXPORT PARAMS 6 | ############################# 7 | # width 8 | export var width: float = 0.5 9 | export var width_curve: Curve 10 | # length 11 | export var max_points := 100 12 | export var material: Material 13 | # show or hide 14 | export var render: bool = true 15 | 16 | 17 | ############################# 18 | # PARAMS 19 | ############################# 20 | onready var half_width = width * 0.5 21 | var points := [] 22 | 23 | 24 | ############################# 25 | # OVERRIDE FUNCTIONS 26 | ############################# 27 | func _ready() -> void: 28 | var node = Node.new() 29 | node.name = "Node" 30 | add_child(node) 31 | 32 | var render = MeshInstance.new() 33 | render.name = "Render" 34 | node.add_child(render) 35 | 36 | 37 | func _process(delta: float) -> void: 38 | if render: 39 | # add new point and render 40 | add_point() 41 | _draw_trail() 42 | else: 43 | # slowly hide the trail 44 | if points.size() > 0: 45 | var last_point = points.pop_back() 46 | last_point.queue_free() 47 | 48 | 49 | ############################# 50 | # API 51 | ############################# 52 | func add_point() -> void: 53 | var new_point = Position3D.new() 54 | new_point.translation = self.global_transform.origin 55 | new_point.rotation = self.global_transform.basis.get_euler() 56 | points.insert(0, new_point) 57 | if points.size() > max_points: 58 | var last_point = points.pop_back() 59 | last_point.queue_free() 60 | 61 | 62 | func _draw_trail() -> void: 63 | if points.size() < 2: 64 | return 65 | # create surface tool 66 | var st = SurfaceTool.new() 67 | st.begin(Mesh.PRIMITIVE_TRIANGLES) 68 | # draw triangles 69 | for i in range(points.size() - 1): 70 | _points_to_rect(st, points[i], points[i + 1], i) 71 | # commit 72 | st.generate_normals() 73 | # st.generate_tangents() 74 | $Node/Render.mesh = st.commit() 75 | $Node/Render.set_surface_material(0, material) 76 | 77 | 78 | func _points_to_rect(st: SurfaceTool, p1: Position3D, p2: Position3D, idx: float) -> void: 79 | var num_points = points.size() - 1 80 | 81 | var offset1 = idx / num_points 82 | var mod1 = half_width * width_curve.interpolate(offset1) 83 | 84 | var v1 = p1.translation + p1.transform.basis.x * mod1 85 | var uv1 = Vector2(0, offset1) 86 | 87 | var v2 = p1.translation - p1.transform.basis.x * mod1 88 | var uv2 = Vector2(1, offset1) 89 | 90 | var offset2 = (idx + 1) / num_points 91 | var mod2 = half_width * width_curve.interpolate(offset2) 92 | 93 | var v3 = p2.translation + p2.transform.basis.x * mod2 94 | var uv3 = Vector2(0, offset2) 95 | 96 | var v4 = p2.translation - p2.transform.basis.x * mod2 97 | var uv4 = Vector2(1, offset2) 98 | 99 | st.add_uv(uv1) 100 | st.add_vertex(v1) 101 | st.add_uv(uv2) 102 | st.add_vertex(v2) 103 | st.add_uv(uv3) 104 | st.add_vertex(v3) 105 | 106 | st.add_uv(uv3) 107 | st.add_vertex(v3) 108 | st.add_uv(uv2) 109 | st.add_vertex(v2) 110 | st.add_uv(uv1) 111 | st.add_vertex(v1) 112 | 113 | st.add_uv(uv3) 114 | st.add_vertex(v3) 115 | st.add_uv(uv4) 116 | st.add_vertex(v4) 117 | st.add_uv(uv2) 118 | st.add_vertex(v2) 119 | 120 | st.add_uv(uv2) 121 | st.add_vertex(v2) 122 | st.add_uv(uv4) 123 | st.add_vertex(v4) 124 | st.add_uv(uv3) 125 | st.add_vertex(v3) 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | --------------------------------------------------------------------------------