movement refactor, airstepping, landing sound

This commit is contained in:
2022-04-17 20:51:36 +03:00
parent f26f54eae0
commit 84f8452f83
23 changed files with 398 additions and 156 deletions

BIN
Assets/Audio/jumpland4.wav Normal file

Binary file not shown.

BIN
Assets/Audio/jumpland4a.wav Normal file

Binary file not shown.

BIN
Assets/Audio/jumpland5.wav Normal file

Binary file not shown.

BIN
Assets/Audio/jumpland5a.wav Normal file

Binary file not shown.

BIN
Assets/Audio/jumpland5b.wav Normal file

Binary file not shown.

BIN
Assets/Audio/jumpland5c.wav Normal file

Binary file not shown.

BIN
Assets/Audio/step1.wav Normal file

Binary file not shown.

BIN
Assets/Audio/step2.wav Normal file

Binary file not shown.

BIN
Assets/Audio/step3.wav Normal file

Binary file not shown.

BIN
Assets/Audio/step4.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,6 +7,15 @@ using Object = FlaxEngine.Object;
namespace Game
{
[Flags]
public enum AudioFlags
{
None = 0,
/// Avoid replacing the existing playing audio source in this channel.
ContinuePlayingExistingSource = 1,
}
public static class AudioManager
{
private class AudioInfo
@@ -15,21 +24,74 @@ namespace Game
public int lastAudioPlayed;
}
private class ActorAudioChannels
{
public Dictionary<int, AudioSource> channelSources;
public ActorAudioChannels()
{
channelSources = new Dictionary<int, AudioSource>();
}
}
private static Random random = new Random();
private static Dictionary<string, AudioInfo> cachedAudioInfos = new Dictionary<string, AudioInfo>();
private static Dictionary<Actor, ActorAudioChannels> actorAudioChannels =
new Dictionary<Actor, ActorAudioChannels>();
public static void PlaySound(string soundName, Actor actor, Vector3 position, float volume = 1f)
{
PlaySound(soundName, actor, position, volume, Vector2.One);
PlaySound(soundName, actor, 0, AudioFlags.None, position, volume, Vector2.One);
}
public static void PlaySound(string soundName, Actor actor, Vector3 position, float volume, Vector2 pitchRange)
{
PlaySound(soundName, actor, 0, AudioFlags.None, position, volume, pitchRange);
}
public static void PlaySound(string soundName, Actor actor, int channel, Vector3 position, float volume = 1f)
{
PlaySound(soundName, actor, channel, AudioFlags.None, position, volume, Vector2.One);
}
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position, float volume = 1f)
{
PlaySound(soundName, actor, channel, flags, position, volume, Vector2.One);
}
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position, float volume, Vector2 pitchRange)
{
AudioInfo audio = GetSound(soundName);
if (audio.AudioClips.Length == 0)
return;
channel = Math.Max(channel, 0);
ActorAudioChannels actorChannels = null;
if (channel > 0)
{
if (!actorAudioChannels.TryGetValue(actor, out actorChannels))
{
actorChannels = new ActorAudioChannels();
actorAudioChannels.Add(actor, actorChannels);
}
if (!actorChannels.channelSources.TryGetValue(channel, out AudioSource existingAudioSource))
actorChannels.channelSources.Add(channel, null);
if (existingAudioSource && existingAudioSource != null &&
existingAudioSource.State == AudioSource.States.Playing)
{
if (flags.HasFlag(AudioFlags.ContinuePlayingExistingSource))
return;
existingAudioSource.Stop();
Object.Destroy(existingAudioSource);
actorChannels.channelSources[channel] = null;
}
}
AudioClip audioClip;
if (audio.AudioClips.Length > 1)
{
@@ -64,6 +126,51 @@ namespace Game
audioSource.Play();
Object.Destroy(audioSource, audioClip.Length);
if (channel > 0)
{
actorChannels.channelSources[channel] = audioSource;
}
}
public static void StopSound(Actor actor, int channel)
{
if (channel <= 0)
return;
if (!actorAudioChannels.TryGetValue(actor, out ActorAudioChannels actorChannels))
return;
if (!actorChannels.channelSources.TryGetValue(channel, out AudioSource existingAudioSource))
return;
if (existingAudioSource && existingAudioSource != null &&
existingAudioSource.State == AudioSource.States.Playing)
{
existingAudioSource.Stop();
Object.Destroy(existingAudioSource);
actorChannels.channelSources[channel] = null;
}
}
public static bool IsSoundPlaying(Actor actor, int channel)
{
if (channel <= 0)
return false;
if (!actorAudioChannels.TryGetValue(actor, out ActorAudioChannels actorChannels))
return false;
if (!actorChannels.channelSources.TryGetValue(channel, out AudioSource existingAudioSource))
return false;
if (existingAudioSource && existingAudioSource != null &&
existingAudioSource.State == AudioSource.States.Playing)
{
return true;
}
return false;
}
private static AudioInfo GetSound(string soundName)

View File

@@ -92,10 +92,13 @@ namespace Cabrito
public static void PrintError(string text) => instance.PrintError(text);
// Echoes developer/debug text to Console
public static void PrintDebug(string text) => instance.PrintDebug(1, text);
public static void PrintDebug(string text) => instance.PrintDebug(1, false, text);
// Echoes developer/debug text to Console
public static void PrintDebug(int verbosity, string text) => instance.PrintDebug(verbosity, text);
public static void PrintDebug(int verbosity, string text) => instance.PrintDebug(verbosity, false, text);
// Echoes developer/debug text to Console
public static void PrintDebug(int verbosity, bool noRepeat, string text) => instance.PrintDebug(verbosity, noRepeat, text);
// Opens the Console
public static void Open() => instance.Open();
@@ -305,6 +308,8 @@ namespace Cabrito
// Echoes text to Console
public void Print(string text)
{
debugLastLine = text;
foreach (var line in text.Split(new[] { '\n' }))
{
ConsoleLine lineEntry = new ConsoleLine(line);
@@ -341,11 +346,20 @@ namespace Cabrito
}
// Echoes developer/debug text to Console
public void PrintDebug(int verbosity, string text)
private string debugLastLine = "";
public void PrintDebug(int verbosity, bool noRepeat, string text)
{
if (DebugVerbosity < verbosity)
return;
if (noRepeat)
{
if (debugLastLine.Length == text.Length && debugLastLine == text)
return;
}
debugLastLine = text;
foreach (var line in text.Split(new[] { '\n' }))
{
ConsoleLine lineEntry = new ConsoleLine(line);

View File

@@ -30,7 +30,7 @@ namespace Game
{
[Limit(0, 9000), Tooltip("Base Movement speed")]
public float MoveSpeed { get; set; } = 320;
private static Vector3 Gravity { get; set; } = new Vector3(0, -800.0f, 0f);
private float viewPitch;
@@ -41,6 +41,8 @@ namespace Game
private float viewYawLastFrame;
private float viewRollLastFrame;
private bool predicting = false;
private InputEvent onExit = new InputEvent("Exit");
// FIXME, should be much smaller but needed to avoid issues with box collider edges against brush edges diagonally
@@ -56,7 +58,7 @@ namespace Game
base.OnAwake();
bool record = false;
record = true;
//record = true;
if (record)
{
@@ -64,8 +66,8 @@ namespace Game
}
else
{
//input = new PlayerInputLocal();
input = new PlayerInputDemo(@"C:\dev\GoakeFlax\testdemo.gdem"); //playback
input = new PlayerInputLocal();
//input = new PlayerInputDemo(@"C:\dev\GoakeFlax\testdemo.gdem"); //playback
//input = new PlayerInputDemo(@"C:\dev\GoakeFlax\testdemo_desync.gdem"); //playback
}
@@ -213,7 +215,6 @@ namespace Game
}
}
SimulatePlayerMovement(inputState);
if (input is PlayerInputDemo && demoDeltasVerify)
@@ -518,6 +519,8 @@ namespace Game
if (velocity.IsZero)
return SlideMoveHit.Nothing;
Vector3 gravityDirection = Gravity.Normalized;
Vector3 originalPosition = position;
Vector3 originalVelocity = velocity;
@@ -529,76 +532,92 @@ namespace Game
}
// hit something, try to step up
if (onGround)
float effectiveStepHeight = stepHeight;
if (!onGround)
{
Vector3 stepDelta = -Gravity.Normalized * stepSize;
Vector3 slidePosition = position;
Vector3 slideVelocity = velocity;
position = originalPosition;
velocity = originalVelocity;
// step up
Vector3 stepUp = position + stepDelta;
TraceInfo traceUp = TracePlayer(actor, position, stepUp);
if (traceUp.fraction > 0f)
position = traceUp.endPosition;
// try moving from step up position
SlideMoveHit slideMoveStepHit = SlideMove(actor, ref position, ref velocity);
// step down
Vector3 stepDown = position - stepDelta;
TraceInfo traceDown = TracePlayer(actor, position, stepDown);
if (traceDown.fraction < 1f && -Vector3.Dot(Gravity.Normalized, traceDown.hitNormal) < slopeNormal)
// TODO: implement clipping here
/*if (pmove.jump_time > 0 && pmove.jump_time <= movevars.cliptime)
{
// can't step down, slide move like normally
Console.Print("no stepping 1, frac: " + traceDown.fraction + ", dot: " +
(-Vector3.Dot(Gravity.Normalized, traceDown.hitNormal)) +
", norm: " + traceDown.hitNormal);
position = slidePosition;
velocity = slideVelocity;
float zvel = pmove.velocity[2];
VectorCopy(originalvel, pmove.velocity);
pmove.velocity[2] = min(pmove.velocity[2], zvel); // nullifies vertical clipping
}*/
if (!slideMoveHit.HasFlag(SlideMoveHit.Step))
return slideMoveHit;
}
else if (traceDown.fraction > 0f)
position = traceDown.endPosition;
// add some margin from the ground in order to avoid getting stuck after stepping up
if (traceDown.fraction < 1f)
position.Y += collisionMargin;
// ??
var d1 = -Vector3.Dot(Gravity.Normalized, position);
var d2 = -Vector3.Dot(Gravity.Normalized, originalPosition);
if (d1 < d2)
if (airStep < 2)
{
//Console.Print("no stepping 2, " + d1 + " < " + d2);
position = slidePosition;
velocity = slideVelocity;
return slideMoveHit;
//effectiveStepHeight = ?
}
Vector3 slidePosition2 = slidePosition; //down
Vector3 stepPosition2 = position; //up
// FIXME, negate gravity
slidePosition2.Y = 0f;
stepPosition2.Y = 0f;
// take the slide movement results if furthest away from original position
//if ((stepPosition2 - originalPosition).Length < (slidePosition2 - originalPosition).Length)
if ((slidePosition2 - originalPosition).Length >= (stepPosition2 - originalPosition).Length)
{
//Console.Print("no stepping 3");
position = slidePosition;
velocity = slideVelocity;
return slideMoveHit;
}
slideMoveHit = slideMoveStepHit;
}
return slideMoveHit;
Vector3 stepDelta = -gravityDirection * effectiveStepHeight;
Vector3 slidePosition = position;
Vector3 slideVelocity = velocity;
position = originalPosition;
velocity = originalVelocity;
// step up
Vector3 stepUp = position + stepDelta;
TraceInfo traceUp = TracePlayer(actor, position, stepUp);
if (traceUp.fraction > 0f)
position = traceUp.endPosition;
// try moving from step up position
SlideMoveHit slideMoveStepHit = SlideMove(actor, ref position, ref velocity);
// step down
Vector3 stepDown = position - stepDelta;
TraceInfo traceDown = TracePlayer(actor, position, stepDown);
if (traceDown.fraction < 1f && -Vector3.Dot(gravityDirection, traceDown.hitNormal) < slopeNormal)
{
// can't step down, slide move like normally
Console.Print("no stepping 1, frac: " + traceDown.fraction + ", dot: " +
(-Vector3.Dot(gravityDirection, traceDown.hitNormal)) +
", norm: " + traceDown.hitNormal);
position = slidePosition;
velocity = slideVelocity;
return slideMoveHit;
}
else if (traceDown.fraction > 0f)
position = traceDown.endPosition;
// add some margin from the ground in order to avoid getting stuck after stepping up
if (traceDown.fraction < 1f)
position.Y += collisionMargin;
// ??
var d1 = -Vector3.Dot(gravityDirection, position);
var d2 = -Vector3.Dot(gravityDirection, originalPosition);
if (d1 < d2)
{
//Console.Print("no stepping 2, " + d1 + " < " + d2);
position = slidePosition;
velocity = slideVelocity;
return slideMoveHit;
}
Vector3 slidePosition2 = slidePosition; //down
Vector3 stepPosition2 = position; //up
// FIXME, negate gravity
slidePosition2.Y = 0f;
stepPosition2.Y = 0f;
// take the slide movement results if furthest away from original position
//if ((stepPosition2 - originalPosition).Length < (slidePosition2 - originalPosition).Length)
if ((slidePosition2 - originalPosition).Length >= (stepPosition2 - originalPosition).Length)
{
//Console.Print("no stepping 3");
position = slidePosition;
velocity = slideVelocity;
return slideMoveHit;
}
return slideMoveStepHit;
}
[Flags]
@@ -761,6 +780,8 @@ namespace Game
private const float airControl = 0f; //CPM
private const float stepSize = 16f;
private const float autoJumpTime = 0.4f;
private const int airStep = 0;
*/
// GOA
@@ -776,13 +797,16 @@ namespace Game
private const float airStrafeAcceleration = 0f;
private const float strafeAcceleration = 10f;
private const float airControl = 0f;
private const float stepSize = 16f;
private const float stepHeight = 16f;
private const float autoJumpTime = 0.4f;
private const int airStep = 2;
//private bool physicsInteractions = false;
private bool jumped = false;
private float lastJumped = -1f;
private float lastLanded = -1f;
//private Vector3 safePosition;
@@ -823,12 +847,14 @@ namespace Game
wishVelocity = moveDirection.Normalized * MoveSpeed;
// categorize position
bool lastGround = onGround;
Vector3 lastVelocity = velocity;
onGround = true;
Vector3 groundDelta = Gravity.Normalized;//Gravity.Normalized * (collisionMargin * 2);
//if (velocity.Y < 0f)
// groundDelta = Gravity.Normalized * velocity.Y * Time.DeltaTime;
TraceInfo traceGround = TracePlayer(Actor, position, position + groundDelta);
//Console.PrintDebug(1, true, "startSolid: " + traceGround.startSolid);
if (!traceGround.startSolid && traceGround.fraction < 1f &&
-Vector3.Dot(Gravity.Normalized, traceGround.hitNormal) < slopeNormal)
{
@@ -855,14 +881,14 @@ namespace Game
{
// falling or sliding down a slope
onGround = false;
//Console.PrintDebug(1, true, "fall or slide");
}
else
{
//if (onGround != !traceGround.startSolid)
// Console.Print("slidefrac: " + traceGround.fraction);
onGround = !traceGround.startSolid;
//Console.Print("issolid? :" + traceGround.startSolid);
//Console.PrintDebug(1, true, "issolid? :" + traceGround.startSolid);
}
// TODO: snap to ground here
@@ -877,40 +903,19 @@ namespace Game
// jump
if (onGround && jumpAction && !jumped)
{
// reset velocity from gravity
if (-Vector3.Dot(Gravity.Normalized, velocity) < 0 &&
Vector3.Dot(velocity, traceGround.hitNormal) < -0.1)
if (OnJump(traceGround, ref velocity))
{
velocity = Vector3.ProjectOnPlane(velocity, traceGround.hitNormal);
onGround = false;
jumped = true;
lastJumped = Time.GameTime;
}
velocity += Vector3.Up * jumpVelocity;
onGround = false;
jumped = true;
lastJumped = Time.GameTime;
AudioManager.PlaySound("jumpland", Actor, rootActor.Position);
}
//if (/*onGround && */lastGround != onGround)
if (onGround)
{
// ground friction
{
float currentSpeed = velocity.Length;
float control = currentSpeed < stopspeed ? stopspeed : currentSpeed;
var drop = control * friction * Time.DeltaTime;
float newspeed = currentSpeed - drop;
if (newspeed < 0)
newspeed = 0;
if (currentSpeed < 0.0001f)
velocity *= 0;
else
velocity *= newspeed / currentSpeed;
}
ApplyFriction(ref velocity);
// ground acceleration
ApplyAcceleration(ref velocity, wishVelocity.Normalized, wishVelocity.Length, float.MaxValue,
@@ -918,61 +923,125 @@ namespace Game
}
else // air movement
{
float wishspeed = wishVelocity.Length;
if (wishspeed > maxAirSpeed)
wishspeed = maxAirSpeed;
float wishspeedAirControl = wishspeed;
if (airAcceleration != 0)
{
// Q2+ air acceleration
float accel = airAcceleration;
if (Vector3.Dot(velocity, wishVelocity.Normalized) < 0)
accel = airStopAcceleration;
if (airStrafeAcceleration != 0 && Mathf.Abs(moveDirection.X) > 0 && moveDirection.Y == 0)
{
// only strafe movement
if (wishspeed > maxAirStrafeSpeed)
wishspeed = maxAirStrafeSpeed;
accel = airStrafeAcceleration;
}
ApplyAcceleration(ref velocity, wishVelocity.Normalized, wishspeed, float.MaxValue, accel);
}
// QW air acceleration
if (strafeAcceleration != 0f)
{
ApplyAcceleration(ref velocity, wishVelocity.Normalized, wishspeed, maxAirStrafeSpeed,
strafeAcceleration);
}
// air control while holding forward/back buttons
//if (airControl != 0 && moveDirection.X == 0 && Mathf.Abs(moveDirection.Y) > 0)
// PM_Aircontrol(wishdir, wishspeedAirControl);
// apply gravity
velocity += Gravity * Time.DeltaTime;
//Console.Print(Time.DeltaTime.ToString());
ApplyAirAcceleration(ref velocity, wishVelocity);
}
//safePosition = rigidBody.Position;
StepSlideMove(Actor, ref position, ref velocity, onGround);
rigidBody.Position = position;
currentVelocity = velocity;
/*if (!rigidBody.IsKinematic)
rigidBody.LinearVelocity = velocity;
else*/
{
StepSlideMove(Actor, ref position, ref velocity, onGround);
//rigidBody.LinearVelocity = velocity;
rigidBody.Position = position;
currentVelocity = velocity;
//rigidBody.LinearVelocity = velocity;
const float landingVelocityThreshold = 120f;
//if (currentVelocity.Y - lastVelocity.Y > landingVelocityThreshold)
if (currentVelocity.Y - lastVelocity.Y > landingVelocityThreshold)
{
if (Time.GameTime - lastJumped > 0.01)
{
Console.Print("landtime: " + (Time.GameTime - lastJumped) * 1000.0f + "ms, vel: " + currentVelocity.Y);
OnLanded(currentVelocity - lastVelocity);
lastLanded = Time.GameTime;
}
}
}
private bool OnJump(TraceInfo traceGround, ref Vector3 velocity)
{
// reset velocity from gravity
if (-Vector3.Dot(Gravity.Normalized, velocity) < 0 &&
Vector3.Dot(velocity, traceGround.hitNormal) < -0.1)
{
velocity = Vector3.ProjectOnPlane(velocity, traceGround.hitNormal);
}
velocity += Vector3.Up * jumpVelocity;
Console.Print("jump");
if (!predicting)
{
// Avoid overlapping with recent landing sound
if (Time.GameTime - lastLanded > 0.3)
AudioManager.PlaySound("jumpland", Actor, 0, rootActor.Position, 1f /*, new Vector2(0.7f, 1.3f)*/);
}
#if false
AudioManager.PlaySound("jumpland", Actor, 0, rootActor.Position, 1f/*, new Vector2(0.7f, 1.3f)*/);
AudioManager.PlaySound("jumpland", Actor, 0, rootActor.Position, 1f/*, new Vector2(0.7f, 1.3f)*/);
AudioManager.PlaySound("jumpland", Actor, 0, rootActor.Position, 1f/*, new Vector2(0.7f, 1.3f)*/);
#endif
return true;
}
private void OnLanded(Vector3 landingVelocity)
{
const float landingHardVelocityThreshold = 500f;
bool loud = landingVelocity.Y > landingHardVelocityThreshold;
if (!predicting)
AudioManager.PlaySound("jumpland", Actor, 1, rootActor.Position, loud ? 1.0f : 0.7f/*, new Vector2(0.7f, 1.3f)*/);
}
private static void ApplyFriction(ref Vector3 velocity)
{
float currentSpeed = velocity.Length;
float control = currentSpeed < stopspeed ? stopspeed : currentSpeed;
var drop = control * friction * Time.DeltaTime;
float newspeed = currentSpeed - drop;
if (newspeed < 0)
newspeed = 0;
if (currentSpeed < 0.0001f)
velocity *= 0;
else
velocity *= newspeed / currentSpeed;
}
private static void ApplyAirAcceleration(ref Vector3 velocity, Vector3 wishVelocity)
{
float wishspeed = wishVelocity.Length;
if (wishspeed > maxAirSpeed)
wishspeed = maxAirSpeed;
Vector3 wishDir = wishVelocity.Normalized;
float wishspeedAirControl = wishspeed;
if (airAcceleration != 0)
{
// Q2+ air acceleration
float accel = airAcceleration;
if (Vector3.Dot(velocity, wishDir) < 0)
accel = airStopAcceleration;
if (airStrafeAcceleration != 0 && Mathf.Abs(wishVelocity.X) > 0 && wishVelocity.Y == 0)
{
// only strafe movement
if (wishspeed > maxAirStrafeSpeed)
wishspeed = maxAirStrafeSpeed;
accel = airStrafeAcceleration;
}
ApplyAcceleration(ref velocity, wishDir, wishspeed, float.MaxValue, accel);
}
// QW air acceleration
if (strafeAcceleration != 0f)
{
ApplyAcceleration(ref velocity, wishDir, wishspeed, maxAirStrafeSpeed,
strafeAcceleration);
}
// air control while holding forward/back buttons
//if (airControl != 0 && moveDirection.X == 0 && Mathf.Abs(moveDirection.Y) > 0)
// PM_Aircontrol(wishdir, wishspeedAirControl);
// apply gravity
velocity += Gravity * Time.DeltaTime;
//Console.Print(Time.DeltaTime.ToString());
}
private static void ApplyAcceleration(ref Vector3 velocity, Vector3 wishDir, float wishspeed, float maxWishspeed,
float acceleration)
{

View File

@@ -300,7 +300,7 @@ namespace Game
{
worldSpawnActor = Actor.AddChild<Actor>();
worldSpawnActor.Name = "WorldSpawn";
worldSpawnActor.HideFlags |= HideFlags.DontSave;
//worldSpawnActor.HideFlags |= HideFlags.DontSave;
worldSpawnActor.HideFlags |= HideFlags.DontSelect;
}

View File

@@ -181,10 +181,6 @@ namespace Game
}
}
private Quaternion targetRotation;
private Quaternion oldRotation;
private Quaternion accumRotation;
public float swaySpeed = 15f;
private Quaternion GetRotation()

View File

@@ -1,5 +1,61 @@
footsteps: https://freesound.org/people/mypantsfelldown/sounds/465299/
footsteps by mypantsfelldown: https://freesound.org/people/mypantsfelldown/sounds/465299/
first step +10 bass and +7 treble, second step untouched
fadeout reverb on both steps
magic sfx by EminYILDIRIM:
https://freesound.org/people/EminYILDIRIM/sounds/626120/
https://freesound.org/people/EminYILDIRIM/sounds/610382/
https://freesound.org/people/EminYILDIRIM/sounds/610135/
https://freesound.org/people/EminYILDIRIM/sounds/609184/
UNUSED:
Forest Footsteps https://freesound.org/people/EminYILDIRIM/sounds/595874/
Fire Magic Impact https://freesound.org/people/EminYILDIRIM/sounds/594912/
Swooshes (Bass) https://freesound.org/people/EminYILDIRIM/sounds/582083/
Metal Impact https://freesound.org/people/EminYILDIRIM/sounds/582025/
Sword Hit https://freesound.org/people/EminYILDIRIM/sounds/574612/
Combat Whoosh 2021 https://freesound.org/people/EminYILDIRIM/sounds/572682/
Water Whoosh https://freesound.org/people/EminYILDIRIM/sounds/572025/
Player Hit & Impact https://freesound.org/people/EminYILDIRIM/sounds/568795/
Lvl Up Sound https://freesound.org/people/EminYILDIRIM/sounds/566502/
Tension Ambience Background https://freesound.org/people/EminYILDIRIM/sounds/555520/
Footstep Ice & Arctic https://freesound.org/people/EminYILDIRIM/sounds/554793/
Mage Teleport Skill https://freesound.org/people/EminYILDIRIM/sounds/554791/
Footstep Snow Single https://freesound.org/people/EminYILDIRIM/sounds/554710/
Magic Ice Impact Skill Spell https://freesound.org/people/EminYILDIRIM/sounds/550267/
Ice Frost Spell Skill https://freesound.org/people/EminYILDIRIM/sounds/550266/
Frozen Ice Spell Skill https://freesound.org/people/EminYILDIRIM/sounds/550264/
Earth & Ice Impact Spell Skill https://freesound.org/people/EminYILDIRIM/sounds/550262/
Fire Magic Whoosh https://freesound.org/people/EminYILDIRIM/sounds/546824/
Fire Sizzle https://freesound.org/people/EminYILDIRIM/sounds/544634/
Magic Lighting Spell Impact & Punch https://freesound.org/people/EminYILDIRIM/sounds/541480/
Magic Ice Spell Impact & Punch https://freesound.org/people/EminYILDIRIM/sounds/541479/
Magic Fire Spell Impact & Punch https://freesound.org/people/EminYILDIRIM/sounds/541478/
Magic Earth Spell Impact & Punch https://freesound.org/people/EminYILDIRIM/sounds/541477/
Combat Punch https://freesound.org/people/EminYILDIRIM/sounds/541295/
Whoosh https://freesound.org/people/EminYILDIRIM/sounds/541205/
Whoosh https://freesound.org/people/EminYILDIRIM/sounds/541206/
Whoosh 2 https://freesound.org/people/EminYILDIRIM/sounds/541207/
Combat Whoosh 3 https://freesound.org/people/EminYILDIRIM/sounds/541208/
Whoosh https://freesound.org/people/EminYILDIRIM/sounds/541209/
Whoosh Sound https://freesound.org/people/EminYILDIRIM/sounds/541211/
Combat Whoosh 2 https://freesound.org/people/EminYILDIRIM/sounds/541204/
Combat Whoosh https://freesound.org/people/EminYILDIRIM/sounds/541203/
Balloon Deflate Long https://freesound.org/people/EminYILDIRIM/sounds/541195/
Balloon Squeak https://freesound.org/people/EminYILDIRIM/sounds/541196/
Balloon Deflate https://freesound.org/people/EminYILDIRIM/sounds/541194/
Water Single Bubble https://freesound.org/people/EminYILDIRIM/sounds/536118/