Browse Source

First version of particle trail, supporting rocket trail, smoke trail and blood trail.

readme
Nico de Poel 5 years ago
parent
commit
4c648a1f5a
  1. 22
      Assets/Scripts/Data/QConstants.cs
  2. 13
      Assets/Scripts/Modules/GameModule.Interop.cs
  3. 34
      Assets/Scripts/Modules/GameModule.cs
  4. 106
      Assets/Scripts/Support/ParticleTrailController.cs
  5. 3
      Assets/Scripts/Support/ParticleTrailController.cs.meta
  6. 17
      Assets/Scripts/VisualStyle.cs
  7. 2
      Assets/Styles/Original/GLQuake.asset
  8. 4819
      Assets/Styles/Original/Particles/ParticleTrail.prefab
  9. 7
      Assets/Styles/Original/Particles/ParticleTrail.prefab.meta
  10. 2
      Assets/Styles/Original/Software.asset
  11. 2
      engine/Quake/r_part.c
  12. 1
      engine/Quake/render.h
  13. 6
      engine/UniQuake/game_uniquake.c

22
Assets/Scripts/Data/QConstants.cs

@ -9,3 +9,25 @@
public const int LightmapBlockWidth = 256; // Should correspond to LMBLOCK_WIDTH public const int LightmapBlockWidth = 256; // Should correspond to LMBLOCK_WIDTH
public const int LightmapBlockHeight = 256; // Should correspond to LMBLOCK_HEIGHT public const int LightmapBlockHeight = 256; // Should correspond to LMBLOCK_HEIGHT
} }
// Should correspond to particle_effect_t in game_uniquake.c
public enum ParticleEffect
{
Explosion = 0,
RogueExplosion,
BlobExplosion,
LavaSplash,
TeleportSplash,
}
// Should correspond to `int type` argument in R_RocketTrail
public enum ParticleTrail
{
Rocket = 0,
Smoke = 1,
Blood = 2,
Tracer = 3,
SlightBlood = 4,
Tracer2 = 5,
VoreBall = 6,
}

13
Assets/Scripts/Modules/GameModule.Interop.cs

@ -20,6 +20,7 @@ public partial class GameModule : CallbackHandler<GameModule>
RunParticleEffect = CreateCallback<RunParticleEffectCallback>(Callback_RunParticleEffect), RunParticleEffect = CreateCallback<RunParticleEffectCallback>(Callback_RunParticleEffect),
CreateParticleEffect = CreateCallback<CreateParticleEffectCallback>(Callback_CreateParticleEffect), CreateParticleEffect = CreateCallback<CreateParticleEffectCallback>(Callback_CreateParticleEffect),
CreateParticleTrail = CreateCallback<CreateParticleTrailCallback>(Callback_CreateParticleTrail),
}; };
RegisterCallbacks(callbacks); RegisterCallbacks(callbacks);
@ -39,6 +40,7 @@ public partial class GameModule : CallbackHandler<GameModule>
public IntPtr RunParticleEffect; public IntPtr RunParticleEffect;
public IntPtr CreateParticleEffect; public IntPtr CreateParticleEffect;
public IntPtr CreateParticleTrail;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -122,4 +124,15 @@ public partial class GameModule : CallbackHandler<GameModule>
Profiler.EndSample(); Profiler.EndSample();
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void CreateParticleTrailCallback(IntPtr context, int type, ref QVec3 start, ref QVec3 end);
[MonoPInvokeCallback(typeof(CreateParticleTrailCallback))]
private static void Callback_CreateParticleTrail(IntPtr context, int type, ref QVec3 start, ref QVec3 end)
{
Profiler.BeginSample("CreateParticleTrail");
GetSelf(context).CreateParticleTrail(type, start.ToUnityPosition(), end.ToUnityPosition());
Profiler.EndSample();
}
} }

34
Assets/Scripts/Modules/GameModule.cs

@ -97,25 +97,19 @@ public partial class GameModule
uq.CurrentStyle.Particles.CreateRogueExplosion(position, colorMin, colorMax, uq.GameLayer); uq.CurrentStyle.Particles.CreateRogueExplosion(position, colorMin, colorMax, uq.GameLayer);
} }
// Should correspond to particle_effect_t in game_uniquake.c
private enum ParticleEffect
{
Explosion = 0,
RogueExplosion,
BlobExplosion,
LavaSplash,
TeleportSplash,
}
// Should correspond to `int type` argument in R_RocketTrail
private enum ParticleTrail
{
Rocket = 0,
Smoke = 1,
Blood = 2,
Tracer = 3,
SlightBlood = 4,
Tracer2 = 5,
VoreBall = 6,
private void CreateParticleTrail(int type, Vector3 start, Vector3 end)
{
int dec;
if (type < 128)
{
dec = 3;
}
else
{
dec = 1;
type -= 128;
}
uq.CurrentStyle.Particles.CreateParticleTrail((ParticleTrail)type, start, end, dec, uq.GameLayer);
} }
} }

106
Assets/Scripts/Support/ParticleTrailController.cs

@ -0,0 +1,106 @@
using System.Collections;
using UnityEngine;
public class ParticleTrailController : MonoBehaviour
{
private Vector3 endPosition;
public void Initialize(ParticleSystem effect, ParticleTrail type, Vector3 end, int interval)
{
endPosition = end;
var main = effect.main;
var shape = effect.shape;
var emission = effect.emission;
emission.rateOverDistance = 1.0f / interval;
switch (type)
{
case ParticleTrail.Rocket:
{
main.startLifetime = new ParticleSystem.MinMaxCurve(0.6f, 1.2f);
shape.scale = new Vector3(6f, 6f, 6f);
var colorOverLifetime = effect.colorOverLifetime;
colorOverLifetime.enabled = true;
colorOverLifetime.color = SetupGradients(RocketColorKeys, SmokeColorKeys);
break;
}
case ParticleTrail.Smoke:
{
main.startLifetime = new ParticleSystem.MinMaxCurve(0.2f, 0.8f);
shape.scale = new Vector3(6f, 6f, 6f);
var colorOverLifetime = effect.colorOverLifetime;
colorOverLifetime.enabled = true;
colorOverLifetime.color = SetupGradients(SmokeColorKeys, SmokeColorKeys2);
break;
}
case ParticleTrail.Blood:
{
main.gravityModifierMultiplier = 0.05f;
main.startColor = new ParticleSystem.MinMaxGradient(
new Color32(31, 0, 0, 255),
new Color32(55, 0, 0, 255));
shape.scale = new Vector3(6f, 6f, 6f);
break;
}
case ParticleTrail.Tracer:
case ParticleTrail.Tracer2:
{
break;
}
case ParticleTrail.SlightBlood:
{
break;
}
case ParticleTrail.VoreBall:
{
break;
}
}
}
IEnumerator Start()
{
// Instantly move the particle emitter to its end position, to force it to emit all particles at once
yield return null;
transform.position = endPosition;
}
private static ParticleSystem.MinMaxGradient SetupGradients(GradientColorKey[] minKeys, GradientColorKey[] maxKeys)
{
return new ParticleSystem.MinMaxGradient
{
mode = ParticleSystemGradientMode.TwoGradients,
gradientMin = new Gradient { mode = GradientMode.Fixed, colorKeys = minKeys },
gradientMax = new Gradient { mode = GradientMode.Fixed, colorKeys = maxKeys },
};
}
private static readonly GradientColorKey[] RocketColorKeys =
{
new GradientColorKey(new Color32(223, 171, 39, 255), 0.167f),
new GradientColorKey(new Color32(191, 119, 47, 255), 0.333f),
new GradientColorKey(new Color32(91, 91, 91, 255), 0.5f),
new GradientColorKey(new Color32(75, 75, 75, 255), 0.667f),
new GradientColorKey(new Color32(63, 63, 63, 255), 0.833f),
new GradientColorKey(new Color32(47, 47, 47, 255), 1.0f),
};
private static readonly GradientColorKey[] SmokeColorKeys =
{
new GradientColorKey(new Color32(91, 91, 91, 255), 0.25f),
new GradientColorKey(new Color32(75, 75, 75, 255), 0.5f),
new GradientColorKey(new Color32(63, 63, 63, 255), 0.75f),
new GradientColorKey(new Color32(47, 47, 47, 255), 1.0f),
};
private static readonly GradientColorKey[] SmokeColorKeys2 =
{
new GradientColorKey(new Color32(63, 63, 63, 255), 0.5f),
new GradientColorKey(new Color32(47, 47, 47, 255), 1.0f),
};
}

3
Assets/Scripts/Support/ParticleTrailController.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7220fa57562e4a48b6fc17e6bfc0a945
timeCreated: 1628089994

17
Assets/Scripts/VisualStyle.cs

@ -178,6 +178,9 @@ public class ParticleSystems
[SerializeField] [SerializeField]
protected ParticleSystem lavaSplash; protected ParticleSystem lavaSplash;
[SerializeField]
protected ParticleSystem particleTrail;
public virtual void Init() public virtual void Init()
{ {
InitTemplate(particleEffect); InitTemplate(particleEffect);
@ -186,6 +189,7 @@ public class ParticleSystems
InitTemplate(blobExplosion); InitTemplate(blobExplosion);
InitTemplate(teleportSplash); InitTemplate(teleportSplash);
InitTemplate(lavaSplash); InitTemplate(lavaSplash);
InitTemplate(particleTrail);
} }
protected virtual void InitTemplate(ParticleSystem template) protected virtual void InitTemplate(ParticleSystem template)
@ -255,6 +259,19 @@ public class ParticleSystems
InstantiateEffect(lavaSplash, position, layer); InstantiateEffect(lavaSplash, position, layer);
} }
public virtual void CreateParticleTrail(ParticleTrail type, Vector3 start, Vector3 end, int interval, Layers layer)
{
var effect = InstantiateEffect(particleTrail, start, layer);
if (effect == null)
return;
var controller = effect.gameObject.GetComponent<ParticleTrailController>();
if (controller == null)
return;
controller.Initialize(effect, type, end, interval);
}
protected virtual ParticleSystem InstantiateEffect(ParticleSystem template, Vector3 position, Layers layer) protected virtual ParticleSystem InstantiateEffect(ParticleSystem template, Vector3 position, Layers layer)
{ {
if (template == null) if (template == null)

2
Assets/Styles/Original/GLQuake.asset

@ -37,3 +37,5 @@ MonoBehaviour:
type: 3} type: 3}
lavaSplash: {fileID: 9150008102338277659, guid: 4db0c926dce46fe4c90920ecd8c5df2e, lavaSplash: {fileID: 9150008102338277659, guid: 4db0c926dce46fe4c90920ecd8c5df2e,
type: 3} type: 3}
particleTrail: {fileID: 9150008102338277659, guid: 6f6d855fe9d5e524b9293af4fd7caf21,
type: 3}

4819
Assets/Styles/Original/Particles/ParticleTrail.prefab
File diff suppressed because it is too large
View File

7
Assets/Styles/Original/Particles/ParticleTrail.prefab.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6f6d855fe9d5e524b9293af4fd7caf21
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

2
Assets/Styles/Original/Software.asset

@ -37,3 +37,5 @@ MonoBehaviour:
type: 3} type: 3}
lavaSplash: {fileID: 9150008102338277659, guid: 4db0c926dce46fe4c90920ecd8c5df2e, lavaSplash: {fileID: 9150008102338277659, guid: 4db0c926dce46fe4c90920ecd8c5df2e,
type: 3} type: 3}
particleTrail: {fileID: 9150008102338277659, guid: 6f6d855fe9d5e524b9293af4fd7caf21,
type: 3}

2
engine/Quake/r_part.c

@ -649,6 +649,8 @@ FIXME -- rename function and use #defined types instead of numbers
*/ */
void R_RocketTrail (vec3_t start, vec3_t end, int type) void R_RocketTrail (vec3_t start, vec3_t end, int type)
{ {
UQ_Game_ParticleTrail(type, start, end);
#ifdef USE_OPENGL #ifdef USE_OPENGL
vec3_t vec; vec3_t vec;
float len; float len;

1
engine/Quake/render.h

@ -184,5 +184,6 @@ void UQ_Game_ParticleExplosion2(vec3_t origin, int colorStart, int colorLength);
void UQ_Game_BlobExplosion(vec3_t origin); void UQ_Game_BlobExplosion(vec3_t origin);
void UQ_Game_TeleportSplash(vec3_t origin); void UQ_Game_TeleportSplash(vec3_t origin);
void UQ_Game_LavaSplash(vec3_t origin); void UQ_Game_LavaSplash(vec3_t origin);
void UQ_Game_ParticleTrail(int type, vec3_t start, vec3_t end);
#endif /* _QUAKE_RENDER_H */ #endif /* _QUAKE_RENDER_H */

6
engine/UniQuake/game_uniquake.c

@ -12,6 +12,7 @@ typedef struct unity_gamecalls_s
void(*RunParticleEffect)(void *context, vec3_t origin, vec3_t direction, unsigned int colorMin, unsigned int colorMax, int count); void(*RunParticleEffect)(void *context, vec3_t origin, vec3_t direction, unsigned int colorMin, unsigned int colorMax, int count);
void(*CreateParticleEffect)(void *context, int type, vec3_t origin, unsigned int colorMin, unsigned int colorMax); void(*CreateParticleEffect)(void *context, int type, vec3_t origin, unsigned int colorMin, unsigned int colorMax);
void(*CreateParticleTrail)(void *context, int type, vec3_t start, vec3_t end);
} unity_gamecalls_t; } unity_gamecalls_t;
static void *unity_context; static void *unity_context;
@ -92,3 +93,8 @@ void UQ_Game_LavaSplash(vec3_t origin)
{ {
unity_gamecalls->CreateParticleEffect(unity_context, PARTFX_LAVA_SPLASH, origin, 0, 0); unity_gamecalls->CreateParticleEffect(unity_context, PARTFX_LAVA_SPLASH, origin, 0, 0);
} }
void UQ_Game_ParticleTrail(int type, vec3_t start, vec3_t end)
{
unity_gamecalls->CreateParticleTrail(unity_context, type, start, end);
}
Loading…
Cancel
Save