Skip to content

Commit

Permalink
feat: add reference system for auto shape emitter
Browse files Browse the repository at this point in the history
  • Loading branch information
IF-ACT committed Jan 31, 2021
1 parent 7617b8f commit 6b75ca3
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public abstract class BulletSystemBase : MonoBehaviour, IBulletSystem, IBulletCo
private AroundAxisModule aroundAxis;

public virtual string Name => name;
public Quaternion Rotation { get => transform.rotation; set => transform.rotation = value; }
public abstract void ChangePosition(Func<Vector3, Vector3, Vector3> operation);
public abstract void ChangeVelocity(Func<Vector3, Vector3, Vector3> operation);
public abstract void ChangeParam(Func<BulletParam, BulletParam> operation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace CANStudio.BulletStorm.BulletSystem
{
public interface IBulletController
{
Quaternion Rotation { get; set; }

/// <summary>
/// Changes all bullets' position in the controller.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using CANStudio.BulletStorm.Util;
using NaughtyAttributes;
using UnityEngine;

#pragma warning disable 0649
Expand All @@ -10,11 +9,12 @@ namespace CANStudio.BulletStorm.BulletSystem.Modules
[Serializable]
public struct AroundAxisModule
{
[InfoBox("This module is experimental, your configure may loss when updating to next version.", EInfoBoxType.Warning)]

[Tooltip("Rotates around this axis."), SerializeField]
private Vector3 axis;

[Tooltip("If select 'self', use reference system set in emitter."), SerializeField]
private Space space;

[Tooltip("Per second rotation angle in degree."), SerializeField]
private float anglePerSecond;

Expand All @@ -25,11 +25,23 @@ public void OnUpdate(IBulletController controller)
BulletStormLogger.LogErrorOnce($"{controller}: In Around axis module, axis can't be zero!");
return;
}
var ax = axis;

Vector3 axisInWorld;
switch (space)
{
case Space.World:
axisInWorld = axis;
break;
case Space.Self:
axisInWorld = controller.Rotation * axis;
break;
default:
throw new ArgumentOutOfRangeException();
}
var angle = anglePerSecond * Time.deltaTime;
controller.ChangeParam(param =>
{
param.rotation = Quaternion.AngleAxis(angle, ax) * param.rotation;
param.rotation = Quaternion.AngleAxis(angle, axisInWorld) * param.rotation;
return param;
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using CANStudio.BulletStorm.Util;
using NaughtyAttributes;
using UnityEngine;

#pragma warning disable 0649
Expand All @@ -13,71 +12,16 @@ public struct DeflectionModule
[Tooltip("Velocity deflection angle per second."), SerializeField]
private Vector2 deflection;

[Tooltip("Specific the space that deflection calculated in."), SerializeField]
private Space space;

[Tooltip("The target transform to be a space."), SerializeField, ShowIf(nameof(ShowTarget)), AllowNesting]
private TargetWrapper target;

[Space, Space] // fix the AllowNesting attribute's default behavior

[Tooltip("The euler to describe rotation of a space."), SerializeField, ShowIf(nameof(ShowEuler)), AllowNesting]
private Vector3 euler;

private bool ShowEuler => space == Space.Fixed;
private bool ShowTarget => space == Space.Dynamic;

public void OnUpdate(IBulletController controller)
{
Quaternion rotation;

var dEuler = new Vector3(-deflection.y * Time.deltaTime, deflection.x * Time.deltaTime);

switch (space)
{
case Space.World:
rotation = Quaternion.Euler(dEuler);
break;
case Space.Fixed:
rotation = Helpers.Euler(dEuler, Quaternion.Euler(euler));
break;
case Space.Dynamic:
if (!target.target.Check())
{
BulletStormLogger.LogWarningOnce($"{controller}: Can't find space {target}, use world space by default.");
rotation = Quaternion.Euler(dEuler);
}
else
{
rotation = Helpers.Euler(dEuler, target.target.AsTransform.rotation);
}
break;
default:
throw new ArgumentOutOfRangeException();
}

var rotation = Quaternion.Euler(dEuler);

controller.ChangeParam(param =>
{
param.rotation = rotation * param.rotation;
return param;
});
}

[Serializable]
private enum Space
{
[Tooltip("Simulates in world space.")]
World,
[Tooltip("Take given euler as simulating space.")]
Fixed,
[Tooltip("Take given target as simulating space.")]
Dynamic
}

[Serializable]
private struct TargetWrapper
{
public Target target;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ protected override IEnumerator StartEmitCoroutine()

var repeatTimes = emission.repeat ? emission.repeatTimes : 1;

if (emission.newReferenceSystem)
SetReferenceSystem(bullet, Emitter.rotation);

for (var i = 0; i < repeatTimes; i++)
{
if (overriden is null)
Expand Down Expand Up @@ -114,6 +117,9 @@ private struct ShapeConfig
[Tooltip("Wait time in second after finish each emission."), MinValue(0), AllowNesting]
public float wait;

[Tooltip("Record emitter's current rotation as reference system when this item begins.")]
public bool newReferenceSystem;

public IReadOnlyList<BulletEmitParam> OverridenShape
{
get
Expand Down
17 changes: 17 additions & 0 deletions Packages/bullet-storm-unity/Scripts/Runtime/Emitters/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ protected virtual void OnDestroy()
{
foreach (var copied in bulletSystems.Values) copied.Destroy();
}

/// <summary>
/// Set reference system for a bullet system. After calling this, emitted bullets will take given rotation
/// their reference system. This function won't change reference system of already emitted bullets.
/// </summary>
/// <param name="bulletSystem"></param>
/// <param name="rotation"></param>
protected void SetReferenceSystem(IBulletSystem bulletSystem, Quaternion rotation)
{
if (bulletSystems.TryGetValue(bulletSystem, out var controller))
{
controller.Destroy();
}
var newController = bulletSystem.GetController();
newController.Rotation = rotation;
bulletSystems[bulletSystem] = newController;
}

private IBulletController GetBulletController(IBulletSystem bullet)
{
Expand Down
19 changes: 0 additions & 19 deletions Packages/bullet-storm-unity/Scripts/Runtime/Util/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,5 @@ public static Vector3 SafeChangeMagnitude(this in Vector3 vector3, float value)

return maxExp < Accuracy ? vector3.Minimized() : calculated;
}

/// <summary>
/// Create quaternion from euler angles relative to given space.
/// </summary>
/// <param name="euler">Euler angles</param>
/// <param name="space"></param>
/// <returns></returns>
public static Quaternion Euler(Vector3 euler, Quaternion space)
{
var q = Quaternion.identity;
var rotationY = Quaternion.AngleAxis(euler.y, space * Vector3.up);
q *= rotationY;
space *= rotationY;
var rotationX = Quaternion.AngleAxis(euler.x, space * Vector3.right);
q *= rotationX;
space *= rotationX;
q *= Quaternion.AngleAxis(euler.z, space * Vector3.forward);
return q;
}
}
}

0 comments on commit 6b75ca3

Please sign in to comment.