├── README.md ├── LICENSE ├── NewFPSARTut.gd └── NewFPSARTut.tscn /README.md: -------------------------------------------------------------------------------- 1 | # godot-assault-rifle 2 | How to make an assault rifle in the Godot game engine 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Garbaj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NewFPSARTut.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | var damage = 10 4 | const MAX_CAM_SHAKE = 0.3 5 | 6 | var speed = 10 7 | var h_acceleration = 6 8 | var air_acceleration = 1 9 | var normal_acceleration = 6 10 | var gravity = 20 11 | var jump = 10 12 | var full_contact = false 13 | 14 | var mouse_sensitivity = 0.03 15 | 16 | var direction = Vector3() 17 | var h_velocity = Vector3() 18 | var movement = Vector3() 19 | var gravity_vec = Vector3() 20 | 21 | onready var head = $Head 22 | onready var ground_check = $GroundCheck 23 | onready var anim_player = $AnimationPlayer 24 | onready var camera = $Head/Camera 25 | onready var raycast = $Head/Camera/RayCast 26 | 27 | func _ready(): 28 | pass 29 | 30 | func _input(event): 31 | if event is InputEventMouseMotion: 32 | rotate_y(deg2rad(-event.relative.x * mouse_sensitivity)) 33 | head.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity)) 34 | head.rotation.x = clamp(head.rotation.x, deg2rad(-89), deg2rad(89)) 35 | 36 | func fire(): 37 | if Input.is_action_pressed("fire"): 38 | if not anim_player.is_playing(): 39 | camera.translation = lerp(camera.translation, 40 | Vector3(rand_range(MAX_CAM_SHAKE, -MAX_CAM_SHAKE), 41 | rand_range(MAX_CAM_SHAKE, -MAX_CAM_SHAKE), 0), 0.5) 42 | if raycast.is_colliding(): 43 | var target = raycast.get_collider() 44 | if target.is_in_group("Enemy"): 45 | target.health -= damage 46 | anim_player.play("AssaultFire") 47 | else: 48 | camera.translation = Vector3() 49 | anim_player.stop() 50 | 51 | func _physics_process(delta): 52 | 53 | fire() 54 | 55 | direction = Vector3() 56 | 57 | full_contact = ground_check.is_colliding() 58 | 59 | if not is_on_floor(): 60 | gravity_vec += Vector3.DOWN * gravity * delta 61 | h_acceleration = air_acceleration 62 | elif is_on_floor() and full_contact: 63 | gravity_vec = -get_floor_normal() * gravity 64 | h_acceleration = normal_acceleration 65 | else: 66 | gravity_vec = -get_floor_normal() 67 | h_acceleration = normal_acceleration 68 | 69 | if Input.is_action_just_pressed("jump") and (is_on_floor() or ground_check.is_colliding()): 70 | gravity_vec = Vector3.UP * jump 71 | 72 | if Input.is_action_pressed("move_forward"): 73 | direction -= transform.basis.z 74 | elif Input.is_action_pressed("move_backward"): 75 | direction += transform.basis.z 76 | if Input.is_action_pressed("move_left"): 77 | direction -= transform.basis.x 78 | elif Input.is_action_pressed("move_right"): 79 | direction += transform.basis.x 80 | 81 | direction = direction.normalized() 82 | h_velocity = h_velocity.linear_interpolate(direction * speed, h_acceleration * delta) 83 | movement.z = h_velocity.z + gravity_vec.z 84 | movement.x = h_velocity.x + gravity_vec.x 85 | movement.y = gravity_vec.y 86 | 87 | move_and_slide(movement, Vector3.UP) 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /NewFPSARTut.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=2] 2 | 3 | [ext_resource path="res://scripts/NewFPSARTut.gd" type="Script" id=1] 4 | [ext_resource path="res://import/crosshair.png" type="Texture" id=2] 5 | [ext_resource path="res://assets/generic.material" type="Material" id=4] 6 | 7 | [sub_resource type="CapsuleMesh" id=1] 8 | material = ExtResource( 4 ) 9 | mid_height = 3.0 10 | 11 | [sub_resource type="CapsuleShape" id=2] 12 | height = 3.0 13 | 14 | [sub_resource type="CylinderShape" id=3] 15 | 16 | [sub_resource type="CubeMesh" id=4] 17 | size = Vector3( 0.1, 0.2, 1.5 ) 18 | 19 | [sub_resource type="SpatialMaterial" id=5] 20 | albedo_color = Color( 1, 0.0470588, 0.0470588, 1 ) 21 | 22 | [sub_resource type="Animation" id=6] 23 | resource_name = "AssaultFire" 24 | length = 0.08 25 | step = 0.01 26 | tracks/0/type = "value" 27 | tracks/0/path = NodePath("Head/Camera/Hand/MeshInstance:translation") 28 | tracks/0/interp = 2 29 | tracks/0/loop_wrap = true 30 | tracks/0/imported = false 31 | tracks/0/enabled = true 32 | tracks/0/keys = { 33 | "times": PoolRealArray( 0, 0.02, 0.08 ), 34 | "transitions": PoolRealArray( 1, 1, 1 ), 35 | "update": 0, 36 | "values": [ Vector3( 0, 0, 0 ), Vector3( 0, 0, 0.143 ), Vector3( 0, 0, 0 ) ] 37 | } 38 | 39 | [node name="NewFPSARTut" type="KinematicBody"] 40 | script = ExtResource( 1 ) 41 | 42 | [node name="MeshInstance" type="MeshInstance" parent="."] 43 | transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 0, 0 ) 44 | cast_shadow = 0 45 | mesh = SubResource( 1 ) 46 | material/0 = null 47 | 48 | [node name="CollisionShape" type="CollisionShape" parent="."] 49 | transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 0, 0 ) 50 | shape = SubResource( 2 ) 51 | 52 | [node name="Foot" type="CollisionShape" parent="."] 53 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 0 ) 54 | shape = SubResource( 3 ) 55 | 56 | [node name="Head" type="Spatial" parent="."] 57 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0 ) 58 | 59 | [node name="Camera" type="Camera" parent="Head"] 60 | 61 | [node name="RayCast" type="RayCast" parent="Head/Camera"] 62 | enabled = true 63 | cast_to = Vector3( 0, 0, -200 ) 64 | 65 | [node name="Hand" type="Spatial" parent="Head/Camera"] 66 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.271, -0.352, -0.899 ) 67 | 68 | [node name="MeshInstance" type="MeshInstance" parent="Head/Camera/Hand"] 69 | mesh = SubResource( 4 ) 70 | material/0 = SubResource( 5 ) 71 | 72 | [node name="CenterContainer" type="CenterContainer" parent="Head/Camera"] 73 | anchor_right = 1.0 74 | anchor_bottom = 1.0 75 | __meta__ = { 76 | "_edit_use_anchors_": false 77 | } 78 | 79 | [node name="TextureRect" type="TextureRect" parent="Head/Camera/CenterContainer"] 80 | margin_left = 620.0 81 | margin_top = 340.0 82 | margin_right = 660.0 83 | margin_bottom = 380.0 84 | texture = ExtResource( 2 ) 85 | 86 | [node name="GroundCheck" type="RayCast" parent="."] 87 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2, 0 ) 88 | enabled = true 89 | cast_to = Vector3( 0, -1.5, 0 ) 90 | 91 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 92 | playback_speed = 2.0 93 | anims/AssaultFire = SubResource( 6 ) 94 | --------------------------------------------------------------------------------