mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-11-29 00:27:59 +01:00
1428 lines
54 KiB
C#
1428 lines
54 KiB
C#
/*******************************************************************************************
|
|
* Author: Lane Gresham, AKA LaneMax
|
|
* Websites: http://resurgamstudios.com
|
|
* Description: Core logic for Circular Gravity Force for 2D.
|
|
*******************************************************************************************/
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
|
|
#if (UNITY_EDITOR)
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace CircularGravityForce
|
|
{
|
|
[AddComponentMenu("Physics 2D/Circular Gravity Force 2D", -1)]
|
|
public class CGF2D : MonoBehaviour
|
|
{
|
|
#region Events
|
|
|
|
public delegate void ApplyCGFEvent(CGF2D cgf, Rigidbody2D rigid, Collider2D coll);
|
|
public static event ApplyCGFEvent OnApplyCGFEvent;
|
|
|
|
#endregion
|
|
|
|
#region Enums
|
|
|
|
//Force Types
|
|
public enum ForceType2D
|
|
{
|
|
ForceAtPosition,
|
|
Force,
|
|
Torque,
|
|
GravitationalAttraction
|
|
}
|
|
|
|
//Force Types
|
|
public enum Shape2D
|
|
{
|
|
Sphere,
|
|
Raycast,
|
|
Box
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Classes
|
|
|
|
//Manages all force position properties
|
|
[System.Serializable]
|
|
public class ForcePositionProperties
|
|
{
|
|
[SerializeField, Tooltip("Used for toggling force position properties.")]
|
|
private bool toggleForcePositionProperties;
|
|
public bool ToggleForcePositionProperties
|
|
{
|
|
get { return toggleForcePositionProperties; }
|
|
set { toggleForcePositionProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Force position options.")]
|
|
private CGF.ForcePosition forcePosition = CGF.ForcePosition.ThisTransform;
|
|
public CGF.ForcePosition ForcePosition
|
|
{
|
|
get { return forcePosition; }
|
|
set { forcePosition = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Colliders for when using 'Closest Collider' for 'Force Position'")]
|
|
private List<Collider2D> closestColliders;
|
|
public List<Collider2D> ClosestColliders
|
|
{
|
|
get { return closestColliders; }
|
|
set { closestColliders = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Finds the closest point on effected object and uses that as the force pivot.")]
|
|
private bool useEffectedClosestPoint = false;
|
|
public bool UseEffectedClosestPoint
|
|
{
|
|
get { return useEffectedClosestPoint; }
|
|
set { useEffectedClosestPoint = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Height offset for closest colliders.")]
|
|
private float heightOffset = 0f;
|
|
public float HeightOffset
|
|
{
|
|
get { return heightOffset; }
|
|
set { heightOffset = value; }
|
|
}
|
|
|
|
public ForcePositionProperties()
|
|
{
|
|
ClosestColliders = new List<Collider2D>();
|
|
}
|
|
}
|
|
|
|
//Manages all filter type properties
|
|
[System.Serializable]
|
|
public class FilterProperties
|
|
{
|
|
//Filter effect types
|
|
public enum EffectType
|
|
{
|
|
Effect,
|
|
DontEffect,
|
|
}
|
|
|
|
//Tag filter properties
|
|
[System.Serializable]
|
|
public class TagFilter
|
|
{
|
|
[SerializeField, Tooltip("Effect type for tag filter options.")]
|
|
private EffectType effectType = EffectType.Effect;
|
|
public EffectType _effectType
|
|
{
|
|
get { return effectType; }
|
|
set { effectType = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Tag name used for filter options.")]
|
|
private string tag = string.Empty;
|
|
public string Tag
|
|
{
|
|
get { return tag; }
|
|
set { tag = value; }
|
|
}
|
|
}
|
|
|
|
//GameObject filter properties
|
|
[System.Serializable]
|
|
public class GameObjectFilter
|
|
{
|
|
[SerializeField, Tooltip("Effect type for Gameobject filter options.")]
|
|
private EffectType effectType = EffectType.Effect;
|
|
public EffectType _effectType
|
|
{
|
|
get { return effectType; }
|
|
set { effectType = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Gameobject used for filter options.")]
|
|
private GameObject gameObject;
|
|
public GameObject _gameObject
|
|
{
|
|
get { return gameObject; }
|
|
set { gameObject = value; }
|
|
}
|
|
}
|
|
|
|
//Collider filter properties
|
|
[System.Serializable]
|
|
public class BoundsFilter
|
|
{
|
|
[SerializeField, Tooltip("Effect type for bounds collider filter options.")]
|
|
private EffectType effectType = EffectType.Effect;
|
|
public EffectType _effectType
|
|
{
|
|
get { return effectType; }
|
|
set { effectType = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Bound collider used for filter options.")]
|
|
private Collider2D collider;
|
|
public Collider2D _collider
|
|
{
|
|
get { return collider; }
|
|
set { collider = value; }
|
|
}
|
|
}
|
|
|
|
//Physic material filter properties
|
|
[System.Serializable]
|
|
public class PhysicMaterialFilter
|
|
{
|
|
[SerializeField, Tooltip("Effect type for physic material filter options.")]
|
|
private EffectType effectType = EffectType.Effect;
|
|
public EffectType _effectType
|
|
{
|
|
get { return effectType; }
|
|
set { effectType = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Physic material used for filter options.")]
|
|
private PhysicsMaterial2D physicMaterial;
|
|
public PhysicsMaterial2D _physicMaterial
|
|
{
|
|
get { return physicMaterial; }
|
|
set { physicMaterial = value; }
|
|
}
|
|
}
|
|
|
|
// Filter Properties Constructor
|
|
public FilterProperties()
|
|
{
|
|
gameObjectFilter = new List<GameObjectFilter>();
|
|
tagFilter = new List<TagFilter>();
|
|
boundsFilter = new List<BoundsFilter>();
|
|
physicMaterialFilter = new List<PhysicMaterialFilter>();
|
|
}
|
|
|
|
[SerializeField, Tooltip("Used to filter out gameobjects, has authority over tags, colliders, physicMaterial, and layermasks.")]
|
|
private List<GameObjectFilter> gameObjectFilter;
|
|
public List<GameObjectFilter> _gameObjectFilter
|
|
{
|
|
get { return gameObjectFilter; }
|
|
set { gameObjectFilter = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Used to filter out tags, has authority over colliders, physicMaterial, and layermasks.")]
|
|
private List<TagFilter> tagFilter;
|
|
public List<TagFilter> _tagFilter
|
|
{
|
|
get { return tagFilter; }
|
|
set { tagFilter = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Used to filter out collider bounds, has authority over physicMaterial, and layermasks.")]
|
|
public List<BoundsFilter> boundsFilter;
|
|
public List<BoundsFilter> _boundsFilter
|
|
{
|
|
get { return boundsFilter; }
|
|
set { boundsFilter = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Used to filter out physic material, has authority over layermasks.")]
|
|
public List<PhysicMaterialFilter> physicMaterialFilter;
|
|
public List<PhysicMaterialFilter> _physicMaterialFilter
|
|
{
|
|
get { return physicMaterialFilter; }
|
|
set { physicMaterialFilter = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Used for fildering LayerMasks.")]
|
|
private LayerMask layerMaskFilter = -1;
|
|
public LayerMask _layerMaskFilter
|
|
{
|
|
get { return layerMaskFilter; }
|
|
set { layerMaskFilter = value; }
|
|
}
|
|
|
|
//ValidateFilters all filter options
|
|
public bool ValidateFilters(Rigidbody2D rigid, Collider2D coll)
|
|
{
|
|
bool value = true;
|
|
|
|
if (_gameObjectFilter.Count > 0)
|
|
{
|
|
for (int i = 0; i < _gameObjectFilter.Count; i++)
|
|
{
|
|
switch (_gameObjectFilter[i]._effectType)
|
|
{
|
|
case EffectType.Effect:
|
|
if (_gameObjectFilter[i]._gameObject == rigid.gameObject)
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
case EffectType.DontEffect:
|
|
if (_gameObjectFilter[i]._gameObject == rigid.gameObject)
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_tagFilter.Count > 0)
|
|
{
|
|
for (int i = 0; i < _tagFilter.Count; i++)
|
|
{
|
|
switch (_tagFilter[i]._effectType)
|
|
{
|
|
case EffectType.Effect:
|
|
if (rigid.transform.gameObject.CompareTag(_tagFilter[i].Tag))
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
case EffectType.DontEffect:
|
|
if (rigid.transform.gameObject.CompareTag(_tagFilter[i].Tag))
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_boundsFilter.Count > 0)
|
|
{
|
|
for (int i = 0; i < _boundsFilter.Count; i++)
|
|
{
|
|
switch (_boundsFilter[i]._effectType)
|
|
{
|
|
case EffectType.Effect:
|
|
if (_boundsFilter[i]._collider.bounds.Contains(rigid.position))
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
case EffectType.DontEffect:
|
|
if (_boundsFilter[i]._collider.bounds.Contains(rigid.position))
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_physicMaterialFilter.Count > 0)
|
|
{
|
|
for (int i = 0; i < _physicMaterialFilter.Count; i++)
|
|
{
|
|
switch (_physicMaterialFilter[i]._effectType)
|
|
{
|
|
case EffectType.Effect:
|
|
if (_physicMaterialFilter[i]._physicMaterial == coll.sharedMaterial)
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
case EffectType.DontEffect:
|
|
if (_physicMaterialFilter[i]._physicMaterial == coll.sharedMaterial)
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (((1 << rigid.transform.gameObject.layer) & _layerMaskFilter) != 0)
|
|
{
|
|
value = true;
|
|
}
|
|
else if (((1 << rigid.transform.gameObject.layer) & _layerMaskFilter) == 0)
|
|
{
|
|
value = false;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
//Trigger Area Filter
|
|
[System.Serializable]
|
|
public class TriggerAreaFilter2D
|
|
{
|
|
//Trigger Options
|
|
public enum TriggerAreaFilterOptions
|
|
{
|
|
Disabled,
|
|
OnlyAffectWithinTigger,
|
|
DontAffectWithinTigger,
|
|
}
|
|
|
|
[SerializeField, Tooltip("Trigger area filter options.")]
|
|
private TriggerAreaFilterOptions triggerAreaFilterOptions = TriggerAreaFilterOptions.Disabled;
|
|
public TriggerAreaFilterOptions _triggerAreaFilterOptions
|
|
{
|
|
get { return triggerAreaFilterOptions; }
|
|
set { triggerAreaFilterOptions = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Listed triggers used for the filter.")]
|
|
private List<Collider2D> triggerAreas;
|
|
public List<Collider2D> TriggerAreas
|
|
{
|
|
get { return triggerAreas; }
|
|
set { triggerAreas = value; }
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties/Constructor
|
|
|
|
public CGF2D()
|
|
{
|
|
_transformProperties = new CGF.TransformProperties();
|
|
_forcePositionProperties = new ForcePositionProperties();
|
|
_filterProperties = new FilterProperties();
|
|
_eventProperties = new CGF.EventProperties();
|
|
_drawGravityProperties = new CGF.DrawGravityProperties();
|
|
_memoryProperties = new CGF.MemoryProperties();
|
|
}
|
|
|
|
//Used for when wanting to see the cgf line
|
|
static private string CirularGravityLineName = "CirularGravityForce_LineDisplay";
|
|
|
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
|
//Warning message for Requiring Unity 5.3
|
|
static private string WarningMessageBoxUnity_5_3 = "2D Box Shape Physics Requires Upgrading Project to Unity 5.3 or Higher.";
|
|
#endif
|
|
|
|
[SerializeField, Tooltip("Enable/Disable the Circular Gravity Force.")]
|
|
private bool enable = true;
|
|
public bool Enable
|
|
{
|
|
get { return enable; }
|
|
set { enable = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Shape of the Cirular Gravity Force.")]
|
|
private Shape2D shape2D = Shape2D.Sphere;
|
|
public Shape2D _shape2D
|
|
{
|
|
get { return shape2D; }
|
|
set { shape2D = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("The force type of the Cirular Gravity Force.")]
|
|
private ForceType2D forceType2D = ForceType2D.ForceAtPosition;
|
|
public ForceType2D _forceType2D
|
|
{
|
|
get { return forceType2D; }
|
|
set { forceType2D = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Option for how to apply a force.")]
|
|
private ForceMode2D forceMode2D = ForceMode2D.Force;
|
|
public ForceMode2D _forceMode2D
|
|
{
|
|
get { return forceMode2D; }
|
|
set { forceMode2D = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Projects the force to the right.")]
|
|
private bool projectRight = false;
|
|
public bool _projectRight
|
|
{
|
|
get { return projectRight; }
|
|
set { projectRight = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Radius of the force.")]
|
|
private float size = 5f;
|
|
public float Size
|
|
{
|
|
get { return size; }
|
|
set { size = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Radius of the force.")]
|
|
private Vector2 boxSize = Vector2.one * 5f;
|
|
public Vector2 BoxSize
|
|
{
|
|
get { return boxSize; }
|
|
set { boxSize = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Power for the force, can be negative or positive.")]
|
|
private float forcePower = 10f;
|
|
public float ForcePower
|
|
{
|
|
get { return forcePower; }
|
|
set { forcePower = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Velocity damping on effected rigidbodys.")]
|
|
private float velocityDamping = 0f;
|
|
public float VelocityDamping
|
|
{
|
|
get { return velocityDamping; }
|
|
set { velocityDamping = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Angular velocity damping on effected rigidbodys.")]
|
|
private float angularVelocityDamping = 0f;
|
|
public float AngularVelocityDamping
|
|
{
|
|
get { return angularVelocityDamping; }
|
|
set { angularVelocityDamping = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Manages all transform properties.")]
|
|
private CGF.TransformProperties transformProperties;
|
|
public CGF.TransformProperties _transformProperties
|
|
{
|
|
get { return transformProperties; }
|
|
set { transformProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Options for where you want the force to start. Only available 'Force At Position', 'Explosion Force', and 'Gravitational Attraction' force types.")]
|
|
private ForcePositionProperties forcePositionProperties;
|
|
public ForcePositionProperties _forcePositionProperties
|
|
{
|
|
get { return forcePositionProperties; }
|
|
set { forcePositionProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Filter properties options.")]
|
|
private FilterProperties filterProperties;
|
|
public FilterProperties _filterProperties
|
|
{
|
|
get { return filterProperties; }
|
|
set { filterProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Event properties options.")]
|
|
private CGF.EventProperties eventProperties;
|
|
public CGF.EventProperties _eventProperties
|
|
{
|
|
get { return eventProperties; }
|
|
set { eventProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Draw gravity properties.")]
|
|
private CGF.DrawGravityProperties drawGravityProperties;
|
|
public CGF.DrawGravityProperties _drawGravityProperties
|
|
{
|
|
get { return drawGravityProperties; }
|
|
set { drawGravityProperties = value; }
|
|
}
|
|
|
|
[SerializeField, Tooltip("Memory Properties.")]
|
|
private CGF.MemoryProperties memoryProperties;
|
|
public CGF.MemoryProperties _memoryProperties
|
|
{
|
|
get { return memoryProperties; }
|
|
set { memoryProperties = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
private int colliderListCount;
|
|
public int ColliderListCount
|
|
{
|
|
get { return colliderListCount; }
|
|
}
|
|
[SerializeField]
|
|
private int raycastHitListCount;
|
|
public int RaycastHitListCount
|
|
{
|
|
get { return raycastHitListCount; }
|
|
}
|
|
|
|
//Selected Flag
|
|
bool isSelected = false;
|
|
|
|
//Line Object
|
|
private GameObject cirularGravityLine;
|
|
|
|
//Effected Rigidbodys
|
|
Collider2D[] colliderList;
|
|
RaycastHit2D[] raycastHitList;
|
|
|
|
Color DebugGravityLineColorA;
|
|
Color DebugGravityLineColorB;
|
|
|
|
#endregion
|
|
|
|
#region Gizmos
|
|
|
|
//Used for draying icons
|
|
void OnDrawGizmos()
|
|
{
|
|
if (_drawGravityProperties.DrawGizmo)
|
|
{
|
|
#if (UNITY_EDITOR)
|
|
string icon = "CircularGravityForce Icons/";
|
|
icon = SetupIcons(icon);
|
|
SetupDebugColors();
|
|
|
|
isSelected = CheckGameObjects();
|
|
|
|
if (isSelected)
|
|
{
|
|
if (!EditorApplication.isPlaying && (_shape2D != Shape2D.Box))
|
|
{
|
|
_drawGravityProperties.DrawGravityForceGizmos = false;
|
|
}
|
|
else
|
|
{
|
|
_drawGravityProperties.DrawGravityForceGizmos = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Gizmos.DrawIcon(this.transform.position, icon, true);
|
|
|
|
_drawGravityProperties.DrawGravityForceGizmos = true;
|
|
}
|
|
#endif
|
|
if (_drawGravityProperties.DrawGravityForceGizmos)
|
|
{
|
|
DrawGravityForceGizmos();
|
|
}
|
|
|
|
DrawClosetColliderGizmos();
|
|
}
|
|
}
|
|
|
|
#if (UNITY_EDITOR)
|
|
bool CheckGameObjects()
|
|
{
|
|
if (Selection.activeGameObject == this.gameObject)
|
|
return true;
|
|
|
|
foreach (var item in Selection.gameObjects)
|
|
{
|
|
if (item == this.gameObject)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
string SetupIcons(string icon)
|
|
{
|
|
string cgfDir = string.Format("{0}/ResurgamStudios/CircularGravityForce Package/Gizmos/CircularGravityForce Icons/", Application.dataPath);
|
|
string dir = string.Format("{0}/Gizmos/CircularGravityForce Icons/", Application.dataPath);
|
|
|
|
if (!Directory.Exists(dir))
|
|
{
|
|
if (Directory.Exists(cgfDir))
|
|
{
|
|
CopyIcons(cgfDir, dir);
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
}
|
|
|
|
icon = icon + "cgf_icon";
|
|
|
|
if (forcePower == 0 || enable == false)
|
|
{
|
|
icon = icon + "0.png";
|
|
}
|
|
else if (forcePower >= 0)
|
|
{
|
|
icon = icon + "1.png";
|
|
}
|
|
else if (ForcePower < 0)
|
|
{
|
|
icon = icon + "2.png";
|
|
}
|
|
|
|
return icon;
|
|
}
|
|
|
|
//Copys all cgf icons
|
|
void CopyIcons(string sourceDir, string targetDir)
|
|
{
|
|
Directory.CreateDirectory(targetDir);
|
|
|
|
foreach (var file in Directory.GetFiles(sourceDir).Where(s => s.EndsWith(".png")))
|
|
{
|
|
File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#region Unity Events
|
|
|
|
void Awake()
|
|
{
|
|
if (_memoryProperties.NonAllocPhysics)
|
|
{
|
|
colliderList = new Collider2D[_memoryProperties.ColliderBuffer];
|
|
raycastHitList = new RaycastHit2D[_memoryProperties.RaycastHitBuffer];
|
|
}
|
|
}
|
|
|
|
//Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (Enable)
|
|
{
|
|
//Sets up the line that gets rendered showing the area of forces
|
|
if (_drawGravityProperties.DrawGravityForce)
|
|
{
|
|
if (cirularGravityLine == null)
|
|
{
|
|
//Creates line for showing the force
|
|
cirularGravityLine = new GameObject(CirularGravityLineName);
|
|
cirularGravityLine.transform.SetParent(this.gameObject.transform, false);
|
|
cirularGravityLine.AddComponent<LineRenderer>();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cirularGravityLine != null)
|
|
{
|
|
//Destroys line when not using
|
|
Destroy(cirularGravityLine);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cirularGravityLine != null)
|
|
{
|
|
//Destroys line when not using
|
|
Destroy(cirularGravityLine);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Used for when drawing the cgf line with no lag
|
|
void LateUpdate()
|
|
{
|
|
if (Enable)
|
|
{
|
|
//Validates the this.transform rotation and position
|
|
_transformProperties.ValidateTransform(this.transform);
|
|
|
|
//Sets up the line that gets rendered showing the area of forces
|
|
if (_drawGravityProperties.DrawGravityForce)
|
|
{
|
|
if (cirularGravityLine != null)
|
|
{
|
|
DrawGravityForceLineRenderer();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//This function is called every fixed frame
|
|
void FixedUpdate()
|
|
{
|
|
if (Enable && ForcePower != 0)
|
|
{
|
|
CalculateAndEstimateForce();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Functions
|
|
|
|
//Applys the force function
|
|
private void ApplyForce(Rigidbody2D rigid, Transform trans, Collider2D coll)
|
|
{
|
|
var transPos = trans.position;
|
|
|
|
switch (_forcePositionProperties.ForcePosition)
|
|
{
|
|
case CGF.ForcePosition.ThisTransform:
|
|
break;
|
|
case CGF.ForcePosition.ClosestCollider:
|
|
if (_forcePositionProperties.ClosestColliders != null)
|
|
{
|
|
if (_forcePositionProperties.ClosestColliders.Count > 0)
|
|
{
|
|
float heightOffset = _forcePositionProperties.HeightOffset;
|
|
|
|
if (!_forcePositionProperties.UseEffectedClosestPoint)
|
|
{
|
|
var point = FindClosestPoints(coll, _forcePositionProperties.ClosestColliders, false);
|
|
|
|
transPos = GetVectorHeightOffset(point, coll.transform.position, heightOffset);
|
|
}
|
|
else
|
|
{
|
|
Vector3 pointA = FindClosestPoints(coll, _forcePositionProperties.ClosestColliders, false);
|
|
Vector3 pointB = FindClosestPoints(coll, _forcePositionProperties.ClosestColliders, true);
|
|
|
|
float distanceThisA = Vector3.Distance(coll.transform.position, pointA);
|
|
float distanceAB = Vector3.Distance(pointA, pointB);
|
|
|
|
transPos = GetVectorHeightOffset(pointA, coll.transform.position, Mathf.Abs(distanceThisA - distanceAB) + heightOffset);
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch (_forceType2D)
|
|
{
|
|
//TODO: Add infinity check
|
|
case ForceType2D.ForceAtPosition:
|
|
ApplyCGFForceAtPosition(rigid, transPos, trans);
|
|
break;
|
|
case ForceType2D.Force:
|
|
ApplyCGFForce(rigid, transPos, trans);
|
|
break;
|
|
case ForceType2D.Torque:
|
|
ApplyCGFTorque(rigid, transPos, trans);
|
|
break;
|
|
case ForceType2D.GravitationalAttraction:
|
|
ApplyCGFGravitationalAttraction(rigid, transPos, trans);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ApplyCGFForceAtPosition(Rigidbody2D rigid, Vector3 transPos, Transform trans)
|
|
{
|
|
Vector3 velocity = new Vector3(rigid.velocity.x, rigid.velocity.y, 0f);
|
|
|
|
Vector3 forceAtPoint = transPos;
|
|
|
|
if (_projectRight || _shape2D == Shape2D.Raycast)
|
|
{
|
|
forceAtPoint = ((trans.right) * ForcePower) - (VelocityDamping * velocity);
|
|
}
|
|
else
|
|
{
|
|
forceAtPoint = ((rigid.gameObject.transform.position - transPos) * ForcePower) - (VelocityDamping * velocity);
|
|
}
|
|
|
|
rigid.AddForceAtPosition(forceAtPoint, transPos, _forceMode2D);
|
|
}
|
|
|
|
private void ApplyCGFForce(Rigidbody2D rigid, Vector3 transPos, Transform trans)
|
|
{
|
|
Vector3 velocity = new Vector3(rigid.velocity.x, rigid.velocity.y, 0f);
|
|
|
|
if (_projectRight || _shape2D == Shape2D.Raycast)
|
|
{
|
|
rigid.AddForce(((trans.right) * ForcePower) - (VelocityDamping * velocity), _forceMode2D);
|
|
}
|
|
else
|
|
{
|
|
rigid.AddForce(((rigid.transform.position - transPos) * ForcePower) - (VelocityDamping * velocity), _forceMode2D);
|
|
}
|
|
}
|
|
|
|
private void ApplyCGFTorque(Rigidbody2D rigid, Vector3 transPos, Transform trans)
|
|
{
|
|
rigid.AddTorque(-(ForcePower + ((rigid.angularVelocity * AngularVelocityDamping) * Time.deltaTime)), _forceMode2D);
|
|
}
|
|
|
|
private void ApplyCGFGravitationalAttraction(Rigidbody2D rigid, Vector3 transPos, Transform trans)
|
|
{
|
|
Vector3 velocity = new Vector3(rigid.velocity.x, rigid.velocity.y, 0f);
|
|
|
|
if (_projectRight || _shape2D == Shape2D.Raycast)
|
|
{
|
|
Vector3 gravitationalAttraction = (trans.right).normalized * rigid.mass * ForcePower / (trans.right).sqrMagnitude;
|
|
|
|
if (float.IsNaN(gravitationalAttraction.x) && float.IsNaN(gravitationalAttraction.y) && float.IsNaN(gravitationalAttraction.z))
|
|
{
|
|
gravitationalAttraction = Vector3.zero;
|
|
}
|
|
|
|
rigid.AddForce(gravitationalAttraction - (VelocityDamping * velocity), _forceMode2D);
|
|
}
|
|
else
|
|
{
|
|
Vector3 gravitationalAttraction = (rigid.gameObject.transform.position - transPos).normalized * rigid.mass * ForcePower / (rigid.gameObject.transform.position - transPos).sqrMagnitude;
|
|
|
|
if (float.IsNaN(gravitationalAttraction.x) && float.IsNaN(gravitationalAttraction.y) && float.IsNaN(gravitationalAttraction.z))
|
|
{
|
|
gravitationalAttraction = Vector3.zero;
|
|
}
|
|
|
|
rigid.AddForce(gravitationalAttraction - (VelocityDamping * velocity), _forceMode2D);
|
|
}
|
|
}
|
|
|
|
//Calculate and Estimate the force
|
|
private void CalculateAndEstimateForce()
|
|
{
|
|
if (_shape2D == Shape2D.Sphere)
|
|
{
|
|
#region Sphere
|
|
|
|
colliderListCount = 0;
|
|
|
|
if (_shape2D == Shape2D.Sphere)
|
|
{
|
|
if (_memoryProperties.NonAllocPhysics)
|
|
{
|
|
colliderListCount = Physics2D.OverlapCircleNonAlloc(this.transform.position, Size, colliderList, _memoryProperties.ColliderLayerMask);
|
|
}
|
|
else
|
|
{
|
|
colliderList = Physics2D.OverlapCircleAll(this.transform.position, Size, _memoryProperties.ColliderLayerMask);
|
|
colliderListCount = colliderList.Length;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < colliderListCount; i++)
|
|
{
|
|
if (colliderList[i] != null)
|
|
{
|
|
if (!colliderList[i].isTrigger)
|
|
{
|
|
var rigid = colliderList[i].attachedRigidbody;
|
|
|
|
if (rigid != null)
|
|
{
|
|
if (_filterProperties.ValidateFilters(rigid, colliderList[i]))
|
|
{
|
|
ApplyForce(rigid, this.transform, colliderList[i]);
|
|
|
|
//Enables send message & events
|
|
if (eventProperties.EnableEvents)
|
|
{
|
|
if (OnApplyCGFEvent != null)
|
|
{
|
|
OnApplyCGFEvent.Invoke(this, rigid, colliderList[i]);
|
|
}
|
|
}
|
|
if (eventProperties.EnableSendMessage)
|
|
{
|
|
rigid.SendMessage("OnApplyCGF", this, SendMessageOptions.DontRequireReceiver);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
else
|
|
{
|
|
#region RayCast
|
|
|
|
//Circular Gravity Force Transform
|
|
Transform cgfTran = this.transform;
|
|
|
|
raycastHitListCount = 0;
|
|
|
|
if (_shape2D == Shape2D.Raycast)
|
|
{
|
|
if (_memoryProperties.NonAllocPhysics)
|
|
{
|
|
raycastHitListCount = Physics2D.RaycastNonAlloc(cgfTran.position, cgfTran.rotation * Vector3.right, raycastHitList, Size, _memoryProperties.ColliderLayerMask);
|
|
}
|
|
else
|
|
{
|
|
raycastHitList = Physics2D.RaycastAll(cgfTran.position, cgfTran.rotation * Vector3.right, Size, _memoryProperties.ColliderLayerMask);
|
|
raycastHitListCount = raycastHitList.Length;
|
|
}
|
|
}
|
|
|
|
if (_shape2D == Shape2D.Box)
|
|
{
|
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
|
if (_memoryProperties.NonAllocPhysics)
|
|
{
|
|
raycastHitListCount = Physics2D.BoxCastNonAlloc(this.transform.position, new Vector2(boxSize.x * 2, boxSize.y * 2), this.transform.eulerAngles.z, Vector3.zero, raycastHitList, _memoryProperties.ColliderLayerMask);
|
|
}
|
|
else
|
|
{
|
|
raycastHitList = Physics2D.BoxCastAll(this.transform.position, new Vector2(boxSize.x * 2, boxSize.y * 2), this.transform.eulerAngles.z, Vector3.zero, _memoryProperties.ColliderLayerMask);
|
|
raycastHitListCount = raycastHitList.Length;
|
|
}
|
|
#else
|
|
Debug.LogWarning(WarningMessageBoxUnity_5_3);
|
|
#endif
|
|
}
|
|
|
|
for (int i = 0; i < raycastHitListCount; i++)
|
|
{
|
|
if (raycastHitList[i].collider != null)
|
|
{
|
|
if (!raycastHitList[i].collider.isTrigger)
|
|
{
|
|
var rigid = raycastHitList[i].collider.attachedRigidbody;
|
|
|
|
if (rigid != null)
|
|
{
|
|
if (_filterProperties.ValidateFilters(rigid, raycastHitList[i].collider))
|
|
{
|
|
ApplyForce(rigid, this.transform, raycastHitList[i].collider);
|
|
|
|
//Enables send message & events
|
|
if (eventProperties.EnableEvents)
|
|
{
|
|
if (OnApplyCGFEvent != null)
|
|
{
|
|
OnApplyCGFEvent.Invoke(this, rigid, raycastHitList[i].collider);
|
|
}
|
|
}
|
|
if (eventProperties.EnableSendMessage)
|
|
{
|
|
rigid.SendMessage("OnApplyCGF", this, SendMessageOptions.DontRequireReceiver);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
public Vector3 FindClosestPoints(Collider2D point, List<Collider2D> closestColliders, bool findClosestPoint)
|
|
{
|
|
Vector3 closestPoint = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);
|
|
|
|
if (closestColliders.Count > 0)
|
|
{
|
|
for (int i = 0; i < closestColliders.Count; i++)
|
|
{
|
|
if (closestColliders[i] != null)
|
|
{
|
|
if (closestColliders[i].gameObject.activeSelf && closestColliders[i].enabled)
|
|
{
|
|
var distance = Vector3.Distance(point.transform.position, closestPoint);
|
|
|
|
var newPoint = FindClosestPoints(point, closestColliders[i], findClosestPoint);
|
|
|
|
if (distance > Vector3.Distance(point.transform.position, newPoint))
|
|
{
|
|
closestPoint = newPoint;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return closestPoint;
|
|
}
|
|
|
|
public Vector3 FindClosestPoints(Collider2D point, Collider2D closestCollider, bool findClosestPoint)
|
|
{
|
|
Vector3 closestPoint = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);
|
|
|
|
if (closestCollider != null)
|
|
{
|
|
var distance = Vector3.Distance(point.transform.position, closestPoint);
|
|
|
|
var newPoint = point.transform.position;
|
|
|
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5)
|
|
// if (!findClosestPoint)
|
|
// newPoint = point.Distance(closestCollider).pointB;
|
|
// else
|
|
// newPoint = point.Distance(closestCollider).pointA;
|
|
#else
|
|
Debug.LogWarning(CGF.WarningMessageClosestPoint_5_6);
|
|
#endif
|
|
|
|
if (distance > Vector3.Distance(point.transform.position, newPoint))
|
|
{
|
|
closestPoint = newPoint;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
closestPoint = point.transform.position;
|
|
}
|
|
|
|
return closestPoint;
|
|
}
|
|
|
|
public Vector3 GetVectorHeightOffset(Vector3 A, Vector3 B, float x)
|
|
{
|
|
Vector3 P = x * Vector3.Normalize(B - A) + A;
|
|
return P;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Static Functions
|
|
|
|
//Static function used to create CGFs
|
|
public static GameObject CreateCGF()
|
|
{
|
|
//Creates empty gameobject.
|
|
GameObject cgf = new GameObject();
|
|
|
|
//Sets gameojbect Name
|
|
cgf.name = "CGF 2D";
|
|
|
|
//Creates Circular Gravity Force component
|
|
cgf.AddComponent<CGF2D>()._drawGravityProperties.GravityLineMaterial = new Material(Shader.Find("GUI/Text Shader"));
|
|
|
|
return cgf;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Draw
|
|
|
|
//Draws effected area by forces line renderer
|
|
private void DrawGravityForceLineRenderer()
|
|
{
|
|
//Circular Gravity Force Transform
|
|
Transform cgfTran = this.transform;
|
|
|
|
Color DebugGravityLineColor;
|
|
|
|
if (Enable)
|
|
{
|
|
if (ForcePower == 0)
|
|
DebugGravityLineColor = Color.white;
|
|
else if (ForcePower > 0)
|
|
DebugGravityLineColor = Color.green;
|
|
else
|
|
DebugGravityLineColor = Color.red;
|
|
}
|
|
else
|
|
{
|
|
DebugGravityLineColor = Color.white;
|
|
}
|
|
|
|
//Line setup
|
|
LineRenderer lineRenderer = cirularGravityLine.GetComponent<LineRenderer>();
|
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4)
|
|
lineRenderer.startWidth = _drawGravityProperties.Thickness;
|
|
lineRenderer.endWidth = _drawGravityProperties.Thickness;
|
|
lineRenderer.numCornerVertices = 4;
|
|
#else
|
|
lineRenderer.SetWidth(_drawGravityProperties.Thickness, _drawGravityProperties.Thickness);
|
|
#endif
|
|
lineRenderer.material = _drawGravityProperties.GravityLineMaterial;
|
|
lineRenderer.material.color = DebugGravityLineColor;
|
|
|
|
//Renders type outline
|
|
switch (_shape2D)
|
|
{
|
|
case Shape2D.Sphere:
|
|
|
|
//Models line
|
|
// #if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4)
|
|
// lineRenderer.positionCount = 8;
|
|
// #elif (UNITY_5_5)
|
|
lineRenderer.numPositions = 8;
|
|
// #else
|
|
// lineRenderer.SetVertexCount(8);
|
|
// #endif
|
|
|
|
lineRenderer.SetPosition(0, cgfTran.position + ((cgfTran.rotation * Vector3.up) * Size));
|
|
lineRenderer.SetPosition(1, cgfTran.position);
|
|
lineRenderer.SetPosition(2, cgfTran.position + ((cgfTran.rotation * Vector3.down) * Size));
|
|
lineRenderer.SetPosition(3, cgfTran.position);
|
|
lineRenderer.SetPosition(4, cgfTran.position + ((cgfTran.rotation * Vector3.left) * Size));
|
|
lineRenderer.SetPosition(5, cgfTran.position);
|
|
lineRenderer.SetPosition(6, cgfTran.position + ((cgfTran.rotation * Vector3.right) * Size));
|
|
lineRenderer.SetPosition(7, cgfTran.position);
|
|
|
|
break;
|
|
|
|
case Shape2D.Raycast:
|
|
|
|
//Models line
|
|
// #if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4)
|
|
// lineRenderer.positionCount = 2;
|
|
// #elif (UNITY_5_5)
|
|
lineRenderer.numPositions = 2;
|
|
// #else
|
|
// lineRenderer.SetVertexCount(2);
|
|
// #endif
|
|
|
|
lineRenderer.SetPosition(0, cgfTran.position);
|
|
lineRenderer.SetPosition(1, cgfTran.position + ((cgfTran.rotation * Vector3.right) * Size));
|
|
|
|
break;
|
|
|
|
|
|
case Shape2D.Box:
|
|
|
|
//Models line
|
|
// #if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4)
|
|
// lineRenderer.positionCount = 8;
|
|
// #elif (UNITY_5_5)
|
|
lineRenderer.numPositions = 8;
|
|
// #else
|
|
// lineRenderer.SetVertexCount(8);
|
|
// #endif
|
|
|
|
lineRenderer.SetPosition(0, cgfTran.position + ((cgfTran.rotation * Vector3.up) * BoxSize.y));
|
|
lineRenderer.SetPosition(1, cgfTran.position);
|
|
lineRenderer.SetPosition(2, cgfTran.position + ((cgfTran.rotation * Vector3.down) * BoxSize.y));
|
|
lineRenderer.SetPosition(3, cgfTran.position);
|
|
lineRenderer.SetPosition(4, cgfTran.position + ((cgfTran.rotation * Vector3.left) * BoxSize.x));
|
|
lineRenderer.SetPosition(5, cgfTran.position);
|
|
lineRenderer.SetPosition(6, cgfTran.position + ((cgfTran.rotation * Vector3.right) * BoxSize.x));
|
|
lineRenderer.SetPosition(7, cgfTran.position);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Sets up the gizmo colors for CGF for the editor
|
|
private void SetupDebugColors()
|
|
{
|
|
if (Enable)
|
|
{
|
|
if (forcePower == 0)
|
|
{
|
|
DebugGravityLineColorA = Color.white;
|
|
DebugGravityLineColorB = Color.white;
|
|
}
|
|
else if (forcePower > 0)
|
|
{
|
|
DebugGravityLineColorA = Color.green;
|
|
DebugGravityLineColorB = Color.green;
|
|
}
|
|
else
|
|
{
|
|
DebugGravityLineColorA = Color.red;
|
|
DebugGravityLineColorB = Color.red;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugGravityLineColorA = Color.white;
|
|
DebugGravityLineColorB = Color.white;
|
|
}
|
|
|
|
DebugGravityLineColorA.a = .5f;
|
|
DebugGravityLineColorB.a = .1f;
|
|
}
|
|
|
|
//Draws effected area by forces with debug draw line, so you can see it in Gizmos
|
|
private void DrawGravityForceGizmos()
|
|
{
|
|
//Circular Gravity Force Transform
|
|
Transform cgfTran = this.transform;
|
|
|
|
//Renders type outline
|
|
switch (_shape2D)
|
|
{
|
|
case Shape2D.Sphere:
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.up) * Size), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.down) * Size), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.left) * Size), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.right) * Size), cgfTran.position);
|
|
|
|
break;
|
|
|
|
case Shape2D.Raycast:
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.right) * Size), cgfTran.position);
|
|
|
|
break;
|
|
|
|
case Shape2D.Box:
|
|
|
|
Vector3 BoxSize = new Vector3(boxSize.x, boxSize.y, 0f);
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Matrix4x4 cubeTransform = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one * 2);
|
|
Matrix4x4 oldGizmosMatrix = Gizmos.matrix;
|
|
|
|
Gizmos.matrix *= cubeTransform;
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Gizmos.DrawWireCube(Vector3.zero, BoxSize);
|
|
|
|
if (isSelected)
|
|
DebugGravityLineColorA.a = 1f;
|
|
|
|
if (isSelected)
|
|
{
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Gizmos.DrawWireCube(Vector3.zero, BoxSize);
|
|
}
|
|
|
|
Gizmos.color = DebugGravityLineColorB;
|
|
Gizmos.DrawCube(Vector3.zero, BoxSize);
|
|
|
|
if (isSelected)
|
|
Gizmos.DrawCube(Vector3.zero, BoxSize);
|
|
|
|
Gizmos.matrix = oldGizmosMatrix;
|
|
|
|
if (!isSelected)
|
|
{
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.up) * BoxSize.y), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.down) * BoxSize.y), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.left) * BoxSize.x), cgfTran.position);
|
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.right) * BoxSize.x), cgfTran.position);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (memoryProperties.SeeColliders)
|
|
{
|
|
if (_shape2D == Shape2D.Sphere)
|
|
{
|
|
if (ForcePower != 0)
|
|
{
|
|
for (int i = 0; i < ColliderListCount; i++)
|
|
{
|
|
if (isSelected)
|
|
{
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
DebugGravityLineColorA.a = 1f;
|
|
}
|
|
Gizmos.DrawLine(this.transform.position, colliderList[i].gameObject.transform.position);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (memoryProperties.SeeRaycastHits)
|
|
{
|
|
if (shape2D == Shape2D.Raycast || _shape2D == Shape2D.Box)
|
|
{
|
|
if (ForcePower != 0)
|
|
{
|
|
for (int i = 0; i < RaycastHitListCount; i++)
|
|
{
|
|
if (isSelected)
|
|
{
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
DebugGravityLineColorA.a = 1f;
|
|
}
|
|
Gizmos.DrawLine(this.transform.position, raycastHitList[i].collider.gameObject.transform.position);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_forcePositionProperties.ForcePosition == CGF.ForcePosition.ClosestCollider)
|
|
{
|
|
switch (_forceType2D)
|
|
{
|
|
case ForceType2D.ForceAtPosition:
|
|
case ForceType2D.Force:
|
|
case ForceType2D.GravitationalAttraction:
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
if (_shape2D == Shape2D.Sphere)
|
|
{
|
|
for (int i = 0; i < ColliderListCount; i++)
|
|
{
|
|
if (colliderList != null)
|
|
{
|
|
if (colliderList.Length > 0)
|
|
{
|
|
var rigidCheck = colliderList[i].attachedRigidbody;
|
|
if (rigidCheck != null)
|
|
{
|
|
if (_filterProperties.ValidateFilters(rigidCheck, colliderList[i]))
|
|
{
|
|
Vector3 pointA = FindClosestPoints(colliderList[i], _forcePositionProperties.ClosestColliders, false);
|
|
Vector3 pointB = Vector3.zero;
|
|
|
|
if (_forcePositionProperties.UseEffectedClosestPoint)
|
|
{
|
|
pointB = FindClosestPoints(colliderList[i], _forcePositionProperties.ClosestColliders, true);
|
|
}
|
|
else
|
|
{
|
|
pointB = colliderList[i].transform.position;
|
|
}
|
|
|
|
Gizmos.DrawWireSphere(pointA, .01f);
|
|
Gizmos.DrawLine(pointA, pointB);
|
|
Gizmos.DrawWireSphere(pointB, .01f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_shape2D == Shape2D.Raycast || _shape2D == Shape2D.Box)
|
|
{
|
|
for (int i = 0; i < RaycastHitListCount; i++)
|
|
{
|
|
if (raycastHitList != null)
|
|
{
|
|
if (raycastHitList.Length > 0)
|
|
{
|
|
var rigidCheck = raycastHitList[i].collider.attachedRigidbody;
|
|
if (rigidCheck != null)
|
|
{
|
|
if (_filterProperties.ValidateFilters(rigidCheck, raycastHitList[i].collider))
|
|
{
|
|
Vector3 pointA = FindClosestPoints(raycastHitList[i].collider, _forcePositionProperties.ClosestColliders, false);
|
|
Vector3 pointB = Vector3.zero;
|
|
|
|
if (_forcePositionProperties.UseEffectedClosestPoint)
|
|
{
|
|
pointB = FindClosestPoints(raycastHitList[i].collider, _forcePositionProperties.ClosestColliders, true);
|
|
}
|
|
else
|
|
{
|
|
pointB = raycastHitList[i].collider.transform.position;
|
|
}
|
|
|
|
Gizmos.DrawWireSphere(pointA, .01f);
|
|
Gizmos.DrawLine(pointA, pointB);
|
|
Gizmos.DrawWireSphere(pointB, .01f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case ForceType2D.Torque:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Draws CGF bounds for ClosestCollider
|
|
private void DrawClosetColliderGizmos()
|
|
{
|
|
if (!isSelected)
|
|
return;
|
|
|
|
Gizmos.color = DebugGravityLineColorA;
|
|
|
|
if (_forcePositionProperties.ForcePosition == CGF.ForcePosition.ClosestCollider)
|
|
{
|
|
for (int i = 0; i < _forcePositionProperties.ClosestColliders.Count; i++)
|
|
{
|
|
if (_forcePositionProperties.ClosestColliders[i] != null)
|
|
{
|
|
var bound = _forcePositionProperties.ClosestColliders[i].bounds;
|
|
Gizmos.DrawWireCube(bound.center, bound.size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|