Compare commits
No commits in common. "77877b0c35d42a0a606aa7aa7d0bd24312352a45" and "25c7c0771cdc1743c06ac7bbfd202a70226aca03" have entirely different histories.
77877b0c35
...
25c7c0771c
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,2 +1,92 @@
|
|||
extends SharedSlime
|
||||
class_name Villager
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
@onready var target_location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
@onready var location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
@onready var target_direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
@onready var direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
var task = "idle"
|
||||
|
||||
# Percentage chances of the character performing certain actions while idle.
|
||||
@export var walk_chance = 0.1
|
||||
@export var spin_chance = 0.2
|
||||
|
||||
@export var walk_speed = 0.5
|
||||
|
||||
# Rate at which character corrects their direction after going off course (percentage).
|
||||
@export var dir_correction_rate = 0.95
|
||||
|
||||
# Margin of accuracy to which the character will correct their direction when off course (radians).
|
||||
@export var dir_accuracy = deg_to_rad(0.1)
|
||||
|
||||
# Get the gravity from the project settings to be synced with RigidBody nodes.
|
||||
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
|
||||
match task:
|
||||
"idle":
|
||||
idle()
|
||||
task = rng.randf_range(0, 100)
|
||||
|
||||
# 3% chance to walk somewhere.
|
||||
if task <= walk_chance:
|
||||
task = "walk"
|
||||
target_location_xz = transform.origin * Vector3(1, 0, 1) + (direction_xz * 4)
|
||||
# 6% chance to rotate.
|
||||
elif task > walk_chance and task <= (walk_chance + spin_chance):
|
||||
task = "spin"
|
||||
var rotation_angle = rng.randf_range(-2*PI, 2*PI)
|
||||
var rotation_vector = Vector3(cos(rotation_angle), 0, sin(rotation_angle))
|
||||
target_direction_xz = direction_xz + rotation_vector
|
||||
# 90% chance to idle.
|
||||
elif task > (spin_chance + walk_chance):
|
||||
task = "idle"
|
||||
|
||||
"walk":
|
||||
walk()
|
||||
# Get the direction to the target in z-x plane.
|
||||
target_direction_xz = (location_xz.direction_to(target_location_xz) * Vector3(1, 0, 1)).normalized()
|
||||
|
||||
# Continue to correct direction to within a margin of dir_accuracy degrees.
|
||||
if direction_xz.angle_to(target_direction_xz) >= dir_accuracy:
|
||||
# Rotate towards destination at specified percentage rate.
|
||||
rotate_y(direction_xz.angle_to(target_direction_xz) * dir_correction_rate)
|
||||
|
||||
if location_xz.distance_to(target_location_xz) <= (Vector2(direction_xz.x, direction_xz.z) * walk_speed).length():
|
||||
target_direction_xz = direction_xz
|
||||
target_location_xz = location_xz
|
||||
task = "idle"
|
||||
|
||||
"spin":
|
||||
# Continue to correct direction to within a margin of dir_accuracy degrees.
|
||||
if direction_xz.angle_to(target_direction_xz) >= dir_accuracy:
|
||||
# Rotate towards destination at specified percentage rate.
|
||||
rotate_y(direction_xz.angle_to(target_direction_xz) * dir_correction_rate)
|
||||
else:
|
||||
task = "idle"
|
||||
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
# Add the gravity.
|
||||
if not is_on_floor():
|
||||
velocity.y -= gravity * delta
|
||||
|
||||
# Walk to target location.
|
||||
if (location_xz.distance_to(target_location_xz) > walk_speed) and task == "walk":
|
||||
velocity.x = direction_xz.x * walk_speed
|
||||
velocity.z = direction_xz.z * walk_speed
|
||||
else:
|
||||
velocity.x = 0
|
||||
velocity.z = 0
|
||||
|
||||
move_and_slide()
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
extends SharedSlime
|
||||
class_name Cultist
|
||||
|
||||
const SPEED = 5.0
|
||||
const JUMP_VELOCITY = 4.
|
||||
|
||||
func _on_area_3d_body_entered(body):
|
||||
var items_in_range = $Area3D.get_overlapping_bodies()
|
||||
var villagers = []
|
||||
|
||||
for item in items_in_range:
|
||||
if is_class("Villager"):
|
||||
villagers.append(item)
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
var victim_num = rng.randi_range(0, villagers.size())
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://e0s4phx2jiit"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://e0s4phx2jiit"]
|
||||
|
||||
[ext_resource type="Script" path="res://cultist.gd" id="1_k6djk"]
|
||||
[ext_resource type="Texture2D" uid="uid://df0xror4t3gbc" path="res://Default Purple.png" id="1_x8j7f"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_y0hcm"]
|
||||
|
@ -11,21 +10,12 @@ albedo_texture = ExtResource("1_x8j7f")
|
|||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_17ljq"]
|
||||
material = SubResource("StandardMaterial3D_vxnad")
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_rypky"]
|
||||
radius = 20.0
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="Cultist" type="CharacterBody3D"]
|
||||
script = ExtResource("1_k6djk")
|
||||
[node name="RigidBody3D" type="RigidBody3D" parent="."]
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="RigidBody3D"]
|
||||
shape = SubResource("CapsuleShape3D_y0hcm")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="CollisionShape3D"]
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="RigidBody3D/CollisionShape3D"]
|
||||
mesh = SubResource("CapsuleMesh_17ljq")
|
||||
|
||||
[node name="Area3D" type="Area3D" parent="."]
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"]
|
||||
shape = SubResource("SphereShape3D_rypky")
|
||||
|
||||
[connection signal="body_entered" from="Area3D" to="." method="_on_area_3d_body_entered"]
|
||||
|
|
|
@ -3,97 +3,11 @@ class_name SharedSlime
|
|||
|
||||
var is_holdable: bool = true
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
@onready var target_location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
@onready var location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
@onready var target_direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
@onready var direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
var task = "idle"
|
||||
|
||||
# Percentage chances of the character performing certain actions while idle.
|
||||
@export var walk_chance = 0.1
|
||||
@export var spin_chance = 0.2
|
||||
|
||||
@export var walk_speed = 0.5
|
||||
|
||||
# Rate at which character corrects their direction after going off course (percentage).
|
||||
@export var dir_correction_rate = 0.95
|
||||
|
||||
# Margin of accuracy to which the character will correct their direction when off course (radians).
|
||||
@export var dir_accuracy = deg_to_rad(0.1)
|
||||
|
||||
# Get the gravity from the project settings to be synced with RigidBody nodes.
|
||||
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
||||
|
||||
func _ready():
|
||||
$slime.idle()
|
||||
|
||||
func walk():
|
||||
$slime.walk()
|
||||
# Get the direction to the target in z-x plane.
|
||||
target_direction_xz = (location_xz.direction_to(target_location_xz) * Vector3(1, 0, 1)).normalized()
|
||||
|
||||
# Continue to correct direction to within a margin of dir_accuracy degrees.
|
||||
if direction_xz.angle_to(target_direction_xz) >= dir_accuracy:
|
||||
# Rotate towards destination at specified percentage rate.
|
||||
rotate_y(direction_xz.angle_to(target_direction_xz) * dir_correction_rate)
|
||||
|
||||
if location_xz.distance_to(target_location_xz) <= (Vector2(direction_xz.x, direction_xz.z) * walk_speed).length():
|
||||
target_direction_xz = direction_xz
|
||||
target_location_xz = location_xz
|
||||
task = "idle"
|
||||
|
||||
func spin():
|
||||
# Continue to correct direction to within a margin of dir_accuracy degrees.
|
||||
if direction_xz.angle_to(target_direction_xz) >= dir_accuracy:
|
||||
# Rotate towards destination at specified percentage rate.
|
||||
rotate_y(direction_xz.angle_to(target_direction_xz) * dir_correction_rate)
|
||||
else:
|
||||
task = "idle"
|
||||
|
||||
func idle():
|
||||
$slime.idle()
|
||||
task = rng.randf_range(0, 100)
|
||||
|
||||
# 3% chance to walk somewhere.
|
||||
if task <= walk_chance:
|
||||
task = "walk"
|
||||
target_location_xz = transform.origin * Vector3(1, 0, 1) + (direction_xz * 4)
|
||||
# 6% chance to rotate.
|
||||
elif task > walk_chance and task <= (walk_chance + spin_chance):
|
||||
task = "spin"
|
||||
var rotation_angle = rng.randf_range(-2*PI, 2*PI)
|
||||
var rotation_vector = Vector3(cos(rotation_angle), 0, sin(rotation_angle))
|
||||
target_direction_xz = direction_xz + rotation_vector
|
||||
# 90% chance to idle.
|
||||
elif task > (spin_chance + walk_chance):
|
||||
task = "idle"
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
location_xz = transform.origin * Vector3(1, 0, 1)
|
||||
direction_xz = (transform.basis * Vector3(1, 0, 1)).normalized()
|
||||
|
||||
match task:
|
||||
"idle":
|
||||
idle()
|
||||
"walk":
|
||||
walk()
|
||||
"spin":
|
||||
spin()
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
# Add the gravity.
|
||||
if not is_on_floor():
|
||||
velocity.y -= gravity * delta
|
||||
|
||||
# Walk to target location.
|
||||
if (location_xz.distance_to(target_location_xz) > walk_speed) and task == "walk":
|
||||
velocity.x = direction_xz.x * walk_speed
|
||||
velocity.z = direction_xz.z * walk_speed
|
||||
else:
|
||||
velocity.x = 0
|
||||
velocity.z = 0
|
||||
|
||||
move_and_slide()
|
||||
|
|
Loading…
Reference in New Issue