Initial CSharp Port
parent
350761e8a2
commit
3b2a8c00a3
@ -0,0 +1,7 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.1.1">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<RootNamespace>StarterKit3DPlatformer</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2012
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Starter Kit 3D Platformer", "Starter Kit 3D Platformer.csproj", "{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
ExportDebug|Any CPU = ExportDebug|Any CPU
|
||||||
|
ExportRelease|Any CPU = ExportRelease|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
||||||
|
{B6B2B9A6-A63D-4DA0-B770-B13C8179DFB0}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
Binary file not shown.
@ -0,0 +1,160 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public partial class Player : CharacterBody3D, ICollector
|
||||||
|
{
|
||||||
|
[ExportSubgroup("Components")]
|
||||||
|
[Export] public Node3D View;
|
||||||
|
|
||||||
|
[ExportSubgroup("Properties")]
|
||||||
|
[Export] public float MovementSpeed = 200f;
|
||||||
|
[Export] public float JumpStrength = 6f;
|
||||||
|
|
||||||
|
private Vector3 m_movementVelocity;
|
||||||
|
private float m_rotationDirection;
|
||||||
|
private float m_gravity;
|
||||||
|
|
||||||
|
private bool m_previouslyFloored = false;
|
||||||
|
private bool m_jumpSingle = true;
|
||||||
|
private bool m_jumpDouble = true;
|
||||||
|
private int m_coins = 0;
|
||||||
|
|
||||||
|
private CpuParticles3D m_particlesTrail;
|
||||||
|
private AudioStreamPlayer m_soundFootsteps;
|
||||||
|
private Node3D m_model;
|
||||||
|
private AnimationPlayer m_animation;
|
||||||
|
|
||||||
|
[Signal]
|
||||||
|
public delegate void CoinCollectedEventHandler(int coins);
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
m_particlesTrail = GetNode<CpuParticles3D>("ParticlesTrail");
|
||||||
|
m_soundFootsteps = GetNode<AudioStreamPlayer>("SoundFootsteps");
|
||||||
|
m_model = GetNode<Node3D>("Character");
|
||||||
|
m_animation = GetNode<AnimationPlayer>("Character/AnimationPlayer");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _PhysicsProcess(double delta)
|
||||||
|
{
|
||||||
|
// Handle Functions
|
||||||
|
HandleControls(delta);
|
||||||
|
HandleGravity(delta);
|
||||||
|
|
||||||
|
HandleAnimations();
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
var appliedVelocity = Velocity.Lerp(m_movementVelocity, (float)delta * 10f);
|
||||||
|
appliedVelocity.Y = -m_gravity;
|
||||||
|
Velocity = appliedVelocity;
|
||||||
|
MoveAndSlide();
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
if (Velocity.Length() > 0f)
|
||||||
|
{
|
||||||
|
m_rotationDirection = new Vector2(Velocity.Z, Velocity.X).Angle();
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRotation = Rotation;
|
||||||
|
newRotation.Y = Mathf.LerpAngle(Rotation.Y, m_rotationDirection, (float)delta * 10f);
|
||||||
|
Rotation = newRotation;
|
||||||
|
|
||||||
|
// Scale Animation (Juice)
|
||||||
|
m_model.Scale = m_model.Scale.Lerp(new Vector3(1f, 1f, 1f), (float)delta * 10f);
|
||||||
|
|
||||||
|
// Animation when landing
|
||||||
|
if (IsOnFloor() && m_gravity > 2f && !m_previouslyFloored)
|
||||||
|
{
|
||||||
|
m_model.Scale = new Vector3(1.25f, 0.75f, 1.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_previouslyFloored = IsOnFloor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleControls(double delta)
|
||||||
|
{
|
||||||
|
// Movement
|
||||||
|
var input = Vector3.Zero;
|
||||||
|
input.X = Input.GetAxis("move_left", "move_right");
|
||||||
|
input.Z = Input.GetAxis("move_forward", "move_back");
|
||||||
|
|
||||||
|
m_movementVelocity = View.Basis * input * MovementSpeed * (float)delta;
|
||||||
|
|
||||||
|
// Jumping
|
||||||
|
if (Input.IsActionJustPressed("jump"))
|
||||||
|
{
|
||||||
|
if (m_jumpSingle || m_jumpDouble)
|
||||||
|
{
|
||||||
|
Audio.Instance.Play("res://audio/jump.ogg");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_jumpDouble)
|
||||||
|
{
|
||||||
|
m_gravity = -JumpStrength;
|
||||||
|
|
||||||
|
m_jumpDouble = false;
|
||||||
|
m_model.Scale = new Vector3(0.5f, 1.5f, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_jumpSingle)
|
||||||
|
{
|
||||||
|
Jump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleGravity(double delta)
|
||||||
|
{
|
||||||
|
m_gravity += 25f * (float)delta;
|
||||||
|
|
||||||
|
if (m_gravity > 0f && IsOnFloor())
|
||||||
|
{
|
||||||
|
m_jumpSingle = true;
|
||||||
|
m_gravity = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleAnimations()
|
||||||
|
{
|
||||||
|
m_particlesTrail.Emitting = false;
|
||||||
|
m_soundFootsteps.StreamPaused = true;
|
||||||
|
|
||||||
|
if (IsOnFloor())
|
||||||
|
{
|
||||||
|
if (Mathf.Abs(Velocity.X) > 1f || Mathf.Abs(Velocity.Z) > 1f)
|
||||||
|
{
|
||||||
|
m_animation.Play("walk", 0.5f);
|
||||||
|
m_particlesTrail.Emitting = true;
|
||||||
|
m_soundFootsteps.StreamPaused = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_animation.Play("idle", 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_animation.Play("jump", 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jumping
|
||||||
|
private void Jump()
|
||||||
|
{
|
||||||
|
m_gravity = -JumpStrength;
|
||||||
|
|
||||||
|
m_model.Scale = new Vector3(0.5f, 1.5f, 0.5f);
|
||||||
|
|
||||||
|
m_jumpSingle = false;
|
||||||
|
m_jumpDouble = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collecting Coins
|
||||||
|
public void CollectCoin()
|
||||||
|
{
|
||||||
|
m_coins += 1;
|
||||||
|
EmitSignal(SignalName.CoinCollected, m_coins);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public partial class Audio : Node
|
||||||
|
{
|
||||||
|
public static Audio Instance;
|
||||||
|
|
||||||
|
private int m_players = 12;
|
||||||
|
private string m_bus = "master";
|
||||||
|
private List<AudioStreamPlayer> m_available = new();
|
||||||
|
private List<string> m_queue = new();
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_players; i++)
|
||||||
|
{
|
||||||
|
var audioStreamPlayer = new AudioStreamPlayer();
|
||||||
|
AddChild(audioStreamPlayer);
|
||||||
|
|
||||||
|
m_available.Add(audioStreamPlayer);
|
||||||
|
|
||||||
|
audioStreamPlayer.VolumeDb = -10;
|
||||||
|
audioStreamPlayer.Bus = m_bus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
if (m_queue.Count > 0 && m_available.Any(x => !x.Playing))
|
||||||
|
{
|
||||||
|
var queueItem = m_queue[0];
|
||||||
|
var audioStreamPlayer = m_available.First(x => !x.Playing);
|
||||||
|
|
||||||
|
audioStreamPlayer.Stream = GD.Load<AudioStream>(queueItem);
|
||||||
|
audioStreamPlayer.Play();
|
||||||
|
audioStreamPlayer.PitchScale = (float)GD.RandRange(0.9f, 1.1f);
|
||||||
|
|
||||||
|
m_queue.Remove(queueItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Play(string soundPath)
|
||||||
|
{
|
||||||
|
m_queue.Add(soundPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public partial class Coin : Area3D
|
||||||
|
{
|
||||||
|
private float m_time = 0f;
|
||||||
|
private bool m_grabbed = false;
|
||||||
|
|
||||||
|
public void OnBodyEntered(Node3D body)
|
||||||
|
{
|
||||||
|
if (!m_grabbed && body is ICollector collector)
|
||||||
|
{
|
||||||
|
collector.CollectCoin();
|
||||||
|
|
||||||
|
Audio.Instance.Play("res://audio/coin.ogg");
|
||||||
|
|
||||||
|
GetNode<Node>("Mesh").QueueFree();
|
||||||
|
GetNode<CpuParticles3D>("Particles").Emitting = false;
|
||||||
|
|
||||||
|
m_grabbed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
RotateY(2 * (float)delta);
|
||||||
|
Position += new Vector3(0f, (Mathf.Cos(m_time * 5f) * 1f) * (float)delta, 0f);
|
||||||
|
|
||||||
|
m_time += (float)delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public partial class Hud : Node
|
||||||
|
{
|
||||||
|
private Label m_coins;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
m_coins = GetNode<Label>("Coins");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCoinCollected(int coins)
|
||||||
|
{
|
||||||
|
m_coins.Text = coins.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public interface ICollector
|
||||||
|
{
|
||||||
|
void CollectCoin();
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace StarterKit3DPlatformer;
|
||||||
|
|
||||||
|
public partial class View : Node3D
|
||||||
|
{
|
||||||
|
[ExportGroup("Properties")]
|
||||||
|
[Export] public Node3D Target;
|
||||||
|
|
||||||
|
[ExportGroup("Zoom")]
|
||||||
|
[Export] public float ZoomMinimum = 16f;
|
||||||
|
[Export] public float ZoomMaximum = 4f;
|
||||||
|
[Export] public float ZoomSpeed = 10f;
|
||||||
|
|
||||||
|
[ExportGroup("Rotation")]
|
||||||
|
[Export] public float RotationSpeed = 120f;
|
||||||
|
|
||||||
|
private Vector3 m_cameraRotation;
|
||||||
|
private float m_zoom = 10f;
|
||||||
|
private Camera3D m_camera;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
base._Ready();
|
||||||
|
|
||||||
|
m_camera = GetNode<Camera3D>("Camera");
|
||||||
|
|
||||||
|
m_cameraRotation = RotationDegrees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _PhysicsProcess(double delta)
|
||||||
|
{
|
||||||
|
Position = Position.Lerp(Target.Position, (float)delta * 4f);
|
||||||
|
RotationDegrees = RotationDegrees.Lerp(m_cameraRotation, (float)delta * 6f);
|
||||||
|
|
||||||
|
m_camera.Position = m_camera.Position.Lerp(new Vector3(0f, 0f, m_zoom), 8f * (float)delta);
|
||||||
|
HandleInput(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleInput(double delta)
|
||||||
|
{
|
||||||
|
// Rotation
|
||||||
|
var input = Vector3.Zero;
|
||||||
|
input.Y = Input.GetAxis("camera_left", "camera_right");
|
||||||
|
input.X = Input.GetAxis("camera_up", "camera_down");
|
||||||
|
|
||||||
|
m_cameraRotation += input * RotationSpeed * (float)delta;
|
||||||
|
m_cameraRotation.X = Mathf.Clamp(m_cameraRotation.X, -80, -10);
|
||||||
|
|
||||||
|
// Zooming
|
||||||
|
m_zoom += Input.GetAxis("zoom_in", "zoom_out") * ZoomSpeed * (float)delta;
|
||||||
|
m_zoom = Mathf.Clamp(m_zoom, ZoomMaximum, ZoomMinimum);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,36 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
# Code adapted from KidsCanCode
|
|
||||||
|
|
||||||
var num_players = 12
|
|
||||||
var bus = "master"
|
|
||||||
|
|
||||||
var available = [] # The available players.
|
|
||||||
var queue = [] # The queue of sounds to play.
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
|
|
||||||
for i in num_players:
|
|
||||||
var p = AudioStreamPlayer.new()
|
|
||||||
add_child(p)
|
|
||||||
|
|
||||||
available.append(p)
|
|
||||||
|
|
||||||
p.volume_db = -10
|
|
||||||
p.connect("finished", Callable(self, "_on_stream_finished").bind(p))
|
|
||||||
p.bus = bus
|
|
||||||
|
|
||||||
|
|
||||||
func _on_stream_finished(stream): available.append(stream)
|
|
||||||
|
|
||||||
func play(sound_path): queue.append(sound_path)
|
|
||||||
|
|
||||||
func _process(_delta):
|
|
||||||
|
|
||||||
if not queue.is_empty() and not available.is_empty():
|
|
||||||
|
|
||||||
available[0].stream = load(queue.pop_front())
|
|
||||||
available[0].play()
|
|
||||||
available[0].pitch_scale = randf_range(0.9, 1.1)
|
|
||||||
|
|
||||||
available.pop_front()
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
extends Area3D
|
|
||||||
|
|
||||||
var time = 0
|
|
||||||
var grabbed = false
|
|
||||||
|
|
||||||
# Collecting coins
|
|
||||||
|
|
||||||
func _on_body_entered(body):
|
|
||||||
if body.has_method("collect_coin") and !grabbed:
|
|
||||||
|
|
||||||
body.collect_coin()
|
|
||||||
|
|
||||||
Audio.play("res://audio/coin.ogg") # Play sound
|
|
||||||
|
|
||||||
$Mesh.queue_free()
|
|
||||||
$Particles.emitting = false
|
|
||||||
|
|
||||||
grabbed = true
|
|
||||||
|
|
||||||
# Rotating, animating up and down
|
|
||||||
|
|
||||||
func _process(delta):
|
|
||||||
|
|
||||||
rotate_y(2 * delta) # Rotation
|
|
||||||
position.y += (cos(time * 5) * 1) * delta # Sine movement
|
|
||||||
|
|
||||||
time += delta
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
func _on_coin_collected(coins):
|
|
||||||
|
|
||||||
$Coins.text = str(coins)
|
|
||||||
@ -1,145 +0,0 @@
|
|||||||
extends CharacterBody3D
|
|
||||||
|
|
||||||
signal coin_collected
|
|
||||||
|
|
||||||
@export_subgroup("Components")
|
|
||||||
@export var view: Node3D
|
|
||||||
|
|
||||||
@export_subgroup("Properties")
|
|
||||||
@export var movement_speed = 200
|
|
||||||
@export var jump_strength = 6
|
|
||||||
|
|
||||||
var movement_velocity: Vector3
|
|
||||||
var rotation_direction: float
|
|
||||||
var gravity = 0
|
|
||||||
|
|
||||||
var previously_floored = false
|
|
||||||
|
|
||||||
var jump_single = true
|
|
||||||
var jump_double = true
|
|
||||||
|
|
||||||
var coins = 0
|
|
||||||
|
|
||||||
@onready var particles_trail = $ParticlesTrail
|
|
||||||
@onready var sound_footsteps = $SoundFootsteps
|
|
||||||
@onready var model = $Character
|
|
||||||
@onready var animation = $Character/AnimationPlayer
|
|
||||||
|
|
||||||
# Functions
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
|
||||||
|
|
||||||
# Handle functions
|
|
||||||
|
|
||||||
handle_controls(delta)
|
|
||||||
handle_gravity(delta)
|
|
||||||
|
|
||||||
handle_animations()
|
|
||||||
|
|
||||||
# Movement
|
|
||||||
|
|
||||||
var applied_velocity: Vector3
|
|
||||||
|
|
||||||
applied_velocity = velocity.lerp(movement_velocity, delta * 10)
|
|
||||||
applied_velocity.y = -gravity
|
|
||||||
|
|
||||||
velocity = applied_velocity
|
|
||||||
move_and_slide()
|
|
||||||
|
|
||||||
# Rotation
|
|
||||||
|
|
||||||
if velocity.length() > 0:
|
|
||||||
rotation_direction = Vector2(velocity.z, velocity.x).angle()
|
|
||||||
|
|
||||||
rotation.y = lerp_angle(rotation.y, rotation_direction, delta * 10)
|
|
||||||
|
|
||||||
# Scale animation (juice)
|
|
||||||
|
|
||||||
model.scale = model.scale.lerp(Vector3(1, 1, 1), delta * 10)
|
|
||||||
|
|
||||||
# Animation when landing
|
|
||||||
|
|
||||||
if is_on_floor() and gravity > 2 and !previously_floored:
|
|
||||||
model.scale = Vector3(1.25, 0.75, 1.25)
|
|
||||||
|
|
||||||
previously_floored = is_on_floor()
|
|
||||||
|
|
||||||
# Handle animation(s)
|
|
||||||
|
|
||||||
func handle_animations():
|
|
||||||
|
|
||||||
particles_trail.emitting = false
|
|
||||||
sound_footsteps.stream_paused = true
|
|
||||||
|
|
||||||
if is_on_floor():
|
|
||||||
if abs(velocity.x) > 1 or abs(velocity.z) > 1:
|
|
||||||
animation.play("walk", 0.5)
|
|
||||||
particles_trail.emitting = true
|
|
||||||
sound_footsteps.stream_paused = false
|
|
||||||
else:
|
|
||||||
animation.play("idle", 0.5)
|
|
||||||
else:
|
|
||||||
animation.play("jump", 0.5)
|
|
||||||
|
|
||||||
# Handle movement input
|
|
||||||
|
|
||||||
func handle_controls(delta):
|
|
||||||
|
|
||||||
# Movement
|
|
||||||
|
|
||||||
var input := Vector3.ZERO
|
|
||||||
|
|
||||||
input.x = Input.get_axis("move_left", "move_right")
|
|
||||||
input.z = Input.get_axis("move_forward", "move_back")
|
|
||||||
|
|
||||||
movement_velocity = view.basis * input * movement_speed * delta
|
|
||||||
|
|
||||||
# Jumping
|
|
||||||
|
|
||||||
if Input.is_action_just_pressed("jump"):
|
|
||||||
|
|
||||||
if jump_single or jump_double:
|
|
||||||
Audio.play("res://audio/jump.ogg")
|
|
||||||
|
|
||||||
if jump_double:
|
|
||||||
|
|
||||||
gravity = -jump_strength
|
|
||||||
|
|
||||||
jump_double = false
|
|
||||||
model.scale = Vector3(0.5, 1.5, 0.5)
|
|
||||||
|
|
||||||
if(jump_single): jump()
|
|
||||||
|
|
||||||
# Handle gravity
|
|
||||||
|
|
||||||
func handle_gravity(delta):
|
|
||||||
|
|
||||||
gravity += 25 * delta
|
|
||||||
|
|
||||||
if gravity > 0 and is_on_floor():
|
|
||||||
|
|
||||||
jump_single = true
|
|
||||||
gravity = 0
|
|
||||||
|
|
||||||
# Jumping
|
|
||||||
|
|
||||||
func jump():
|
|
||||||
|
|
||||||
gravity = -jump_strength
|
|
||||||
|
|
||||||
model.scale = Vector3(0.5, 1.5, 0.5)
|
|
||||||
|
|
||||||
jump_single = false;
|
|
||||||
jump_double = true;
|
|
||||||
|
|
||||||
# Collecting coins
|
|
||||||
|
|
||||||
func collect_coin():
|
|
||||||
|
|
||||||
coins += 1
|
|
||||||
|
|
||||||
emit_signal("coin_collected", coins)
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
extends Node3D
|
|
||||||
|
|
||||||
@export_group("Properties")
|
|
||||||
@export var target: Node
|
|
||||||
|
|
||||||
@export_group("Zoom")
|
|
||||||
@export var zoom_minimum = 16
|
|
||||||
@export var zoom_maximum = 4
|
|
||||||
@export var zoom_speed = 10
|
|
||||||
|
|
||||||
@export_group("Rotation")
|
|
||||||
@export var rotation_speed = 120
|
|
||||||
|
|
||||||
var camera_rotation:Vector3
|
|
||||||
var zoom = 10
|
|
||||||
|
|
||||||
@onready var camera = $Camera
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
|
|
||||||
camera_rotation = rotation_degrees # Initial rotation
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
|
||||||
|
|
||||||
# Set position and rotation to targets
|
|
||||||
|
|
||||||
self.position = self.position.lerp(target.position, delta * 4)
|
|
||||||
rotation_degrees = rotation_degrees.lerp(camera_rotation, delta * 6)
|
|
||||||
|
|
||||||
camera.position = camera.position.lerp(Vector3(0, 0, zoom), 8 * delta)
|
|
||||||
|
|
||||||
handle_input(delta)
|
|
||||||
|
|
||||||
# Handle input
|
|
||||||
|
|
||||||
func handle_input(delta):
|
|
||||||
|
|
||||||
# Rotation
|
|
||||||
|
|
||||||
var input := Vector3.ZERO
|
|
||||||
|
|
||||||
input.y = Input.get_axis("camera_left", "camera_right")
|
|
||||||
input.x = Input.get_axis("camera_up", "camera_down")
|
|
||||||
|
|
||||||
camera_rotation += input * rotation_speed * delta
|
|
||||||
camera_rotation.x = clamp(camera_rotation.x, -80, -10)
|
|
||||||
|
|
||||||
# Zooming
|
|
||||||
|
|
||||||
zoom += Input.get_axis("zoom_in", "zoom_out") * zoom_speed * delta
|
|
||||||
zoom = clamp(zoom, zoom_maximum, zoom_minimum)
|
|
||||||
Loading…
Reference in New Issue