mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-11-29 00:27:59 +01:00
1790 lines
69 KiB
C#
1790 lines
69 KiB
C#
|
/*******************************************************************************************
|
||
|
* Author: Lane Gresham, AKA LaneMax
|
||
|
* Websites: http://resurgamstudios.com
|
||
|
* Description: Core logic for Circular Gravity Force.
|
||
|
*******************************************************************************************/
|
||
|
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/Circular Gravity Force", -1)]
|
||
|
public class CGF : MonoBehaviour
|
||
|
{
|
||
|
#region Events
|
||
|
|
||
|
public delegate void ApplyCGFEvent(CGF cgf, Rigidbody rigid, Collider coll);
|
||
|
public static event ApplyCGFEvent OnApplyCGFEvent;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Enums
|
||
|
|
||
|
//Force Types
|
||
|
public enum ForceType
|
||
|
{
|
||
|
ForceAtPosition,
|
||
|
Force,
|
||
|
Torque,
|
||
|
ExplosionForce,
|
||
|
GravitationalAttraction,
|
||
|
}
|
||
|
|
||
|
//Force Types
|
||
|
public enum Shape
|
||
|
{
|
||
|
Sphere,
|
||
|
Capsule,
|
||
|
Raycast,
|
||
|
Box,
|
||
|
}
|
||
|
|
||
|
public enum ForcePosition
|
||
|
{
|
||
|
ThisTransform,
|
||
|
ClosestCollider,
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Classes
|
||
|
|
||
|
//Manages all transform properties
|
||
|
[System.Serializable]
|
||
|
public class TransformProperties
|
||
|
{
|
||
|
[SerializeField, Tooltip("Used for toggling transform properties.")]
|
||
|
private bool toggleTransformProperties;
|
||
|
public bool ToggleTransformProperties
|
||
|
{
|
||
|
get { return toggleTransformProperties; }
|
||
|
set { toggleTransformProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Header("Position"), Tooltip("Toggles to override the transforms position.")]
|
||
|
private bool overridePosition = false;
|
||
|
public bool OverridePosition
|
||
|
{
|
||
|
get { return overridePosition; }
|
||
|
set { overridePosition = value; }
|
||
|
}
|
||
|
[SerializeField, Tooltip("Toggles to use local position.")]
|
||
|
private bool localPosition = false;
|
||
|
public bool LocalPosition
|
||
|
{
|
||
|
get { return localPosition; }
|
||
|
set { localPosition = value; }
|
||
|
}
|
||
|
[SerializeField, Tooltip("Override value for the transforms position.")]
|
||
|
private Vector3 positionValue = Vector3.zero;
|
||
|
public Vector3 PositionValue
|
||
|
{
|
||
|
get { return positionValue; }
|
||
|
set { positionValue = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Header("Rotation"), Tooltip("Toggles to override the transforms rotation.")]
|
||
|
private bool overrideRotation = false;
|
||
|
public bool OverrideRotation
|
||
|
{
|
||
|
get { return overrideRotation; }
|
||
|
set { overrideRotation = value; }
|
||
|
}
|
||
|
[SerializeField, Tooltip("Toggles to use local rotation.")]
|
||
|
private bool localRotation = false;
|
||
|
public bool LocalRotation
|
||
|
{
|
||
|
get { return localRotation; }
|
||
|
set { localRotation = value; }
|
||
|
}
|
||
|
[SerializeField, Tooltip("Override value for the transforms rotation.")]
|
||
|
private Vector3 rotationValue = Vector3.zero;
|
||
|
public Vector3 RotationValue
|
||
|
{
|
||
|
get { return rotationValue; }
|
||
|
set { rotationValue = value; }
|
||
|
}
|
||
|
|
||
|
//Validate the given transform.
|
||
|
public void ValidateTransform(Transform transform)
|
||
|
{
|
||
|
if (OverridePosition)
|
||
|
{
|
||
|
if (LocalPosition)
|
||
|
{
|
||
|
transform.localPosition = PositionValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
transform.position = PositionValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (OverrideRotation)
|
||
|
{
|
||
|
if (LocalRotation)
|
||
|
{
|
||
|
transform.localRotation = Quaternion.Euler(RotationValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
transform.rotation = Quaternion.Euler(RotationValue);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//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 ForcePosition forcePosition = ForcePosition.ThisTransform;
|
||
|
public ForcePosition ForcePosition
|
||
|
{
|
||
|
get { return forcePosition; }
|
||
|
set { forcePosition = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Colliders for when using 'Closest Collider' for 'Force Position'")]
|
||
|
private List<Collider> closestColliders;
|
||
|
public List<Collider> 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<Collider>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Manages all force type properties
|
||
|
[System.Serializable]
|
||
|
public class ForceTypeProperties
|
||
|
{
|
||
|
[SerializeField, Tooltip("Adjustment to the apparent position of the explosion to make it seem to lift objects.")]
|
||
|
private float explosionForceUpwardsModifier = 0f;
|
||
|
public float ExplosionForceUpwardsModifier
|
||
|
{
|
||
|
get { return explosionForceUpwardsModifier; }
|
||
|
set { explosionForceUpwardsModifier = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("The maximimum angular velocity of the rigidbody.")]
|
||
|
private float torqueMaxAngularVelocity = 7f;
|
||
|
public float TorqueMaxAngularVelocity
|
||
|
{
|
||
|
get { return torqueMaxAngularVelocity; }
|
||
|
set { torqueMaxAngularVelocity = value; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//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 Collider collider;
|
||
|
public Collider _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 PhysicMaterial physicMaterial;
|
||
|
public PhysicMaterial _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 colliders, 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(Rigidbody rigid, Collider 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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Manages all event properties
|
||
|
[System.Serializable]
|
||
|
public class EventProperties
|
||
|
{
|
||
|
[SerializeField, Tooltip("Used for toggling event properties.")]
|
||
|
private bool toggleEventProperties;
|
||
|
public bool ToggleEventProperties
|
||
|
{
|
||
|
get { return toggleEventProperties; }
|
||
|
set { toggleEventProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Enables delegate / events.")]
|
||
|
private bool enableEvents = true;
|
||
|
public bool EnableEvents
|
||
|
{
|
||
|
get { return enableEvents; }
|
||
|
set { enableEvents = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Enables SendMessage. Syntax:'void OnApplyCGF(CircularGravityForce.CGF cgf)'")]
|
||
|
private bool enableSendMessage = false;
|
||
|
public bool EnableSendMessage
|
||
|
{
|
||
|
get { return enableSendMessage; }
|
||
|
set { enableSendMessage = value; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Draw gravity properties
|
||
|
[System.Serializable]
|
||
|
public class DrawGravityProperties
|
||
|
{
|
||
|
[SerializeField, Header("Runtime"), Tooltip("Enable/Disables drawing gravity force lines.")]
|
||
|
private bool drawGravityForce = false;
|
||
|
public bool DrawGravityForce
|
||
|
{
|
||
|
get { return drawGravityForce; }
|
||
|
set { drawGravityForce = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Thinkness of the line drawn.")]
|
||
|
private float thickness = 0.05f;
|
||
|
public float Thickness
|
||
|
{
|
||
|
get { return thickness; }
|
||
|
set { thickness = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Material on line.")]
|
||
|
private Material gravityLineMaterial;
|
||
|
public Material GravityLineMaterial
|
||
|
{
|
||
|
get { return gravityLineMaterial; }
|
||
|
set { gravityLineMaterial = value; }
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
[SerializeField, Header("Editor"), Tooltip("Enable/Disables unity editor gizmo for CGF.")]
|
||
|
private bool drawGizmo = true;
|
||
|
public bool DrawGizmo
|
||
|
{
|
||
|
get { return drawGizmo; }
|
||
|
set { drawGizmo = value; }
|
||
|
}
|
||
|
|
||
|
//Used to see gravity area from gizmos
|
||
|
private bool drawGravityForceGizmos = true;
|
||
|
public bool DrawGravityForceGizmos
|
||
|
{
|
||
|
get { return drawGravityForceGizmos; }
|
||
|
set { drawGravityForceGizmos = value; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Draw gravity properties
|
||
|
[System.Serializable]
|
||
|
public class MemoryProperties
|
||
|
{
|
||
|
[SerializeField, Tooltip("Layer mask for all effected colliders.")]
|
||
|
private LayerMask colliderLayerMask = -1;
|
||
|
public LayerMask ColliderLayerMask
|
||
|
{
|
||
|
get { return colliderLayerMask; }
|
||
|
set { colliderLayerMask = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Used for toggling memory properties.")]
|
||
|
private bool toggleMemoryProperties;
|
||
|
public bool ToggleMemoryProperties
|
||
|
{
|
||
|
get { return toggleMemoryProperties; }
|
||
|
set { toggleMemoryProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("See affected colliders in gizmo.")]
|
||
|
private bool seeColliders = false;
|
||
|
public bool SeeColliders
|
||
|
{
|
||
|
get { return seeColliders; }
|
||
|
set { seeColliders = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("See affected raycasthits in gizmo.")]
|
||
|
private bool seeRaycastHits = false;
|
||
|
public bool SeeRaycastHits
|
||
|
{
|
||
|
get { return seeRaycastHits; }
|
||
|
set { seeRaycastHits = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Use Non-Alloc physics.")]
|
||
|
private bool nonAllocPhysics = false;
|
||
|
public bool NonAllocPhysics
|
||
|
{
|
||
|
get { return nonAllocPhysics; }
|
||
|
set { nonAllocPhysics = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Collider buffer size for the Non-Alloc 'Sphere' and 'Box' types.")]
|
||
|
private int colliderBuffer = 100;
|
||
|
public int ColliderBuffer
|
||
|
{
|
||
|
get { return colliderBuffer; }
|
||
|
set { colliderBuffer = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("RaycastHit buffer size for the Non-Alloc 'Capsule' and 'Raycast' shapes.")]
|
||
|
private int raycastHitBuffer = 100;
|
||
|
public int RaycastHitBuffer
|
||
|
{
|
||
|
get { return raycastHitBuffer; }
|
||
|
set { raycastHitBuffer = value; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Properties/Constructor
|
||
|
|
||
|
public CGF()
|
||
|
{
|
||
|
_transformProperties = new TransformProperties();
|
||
|
_forcePositionProperties = new ForcePositionProperties();
|
||
|
_forceTypeProperties = new ForceTypeProperties();
|
||
|
_filterProperties = new FilterProperties();
|
||
|
_eventProperties = new EventProperties();
|
||
|
_drawGravityProperties = new DrawGravityProperties();
|
||
|
_memoryProperties = new 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 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5)
|
||
|
//Warning message for Requiring Unity 5.6
|
||
|
static public string WarningMessageClosestPoint_5_6 = "Force Position Properties Closest Collider Requires Upgrading Project to Unity 5.6 or Higher.";
|
||
|
#endif
|
||
|
|
||
|
#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 public string WarningMessageNonAllocUnity_5_3 = "3D Non-Alloc Physics Requires Upgrading Project to Unity 5.3 or Higher.";
|
||
|
static public string WarningMessageBoxUnity_5_3 = "3D 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 Shape shape = CGF.Shape.Sphere;
|
||
|
public Shape _shape
|
||
|
{
|
||
|
get { return shape; }
|
||
|
set { shape = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("The force type of the Cirular Gravity Force.")]
|
||
|
private ForceType forceType = ForceType.ForceAtPosition;
|
||
|
public ForceType _forceType
|
||
|
{
|
||
|
get { return forceType; }
|
||
|
set { forceType = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Option for how to apply a force.")]
|
||
|
private ForceMode forceMode = ForceMode.Force;
|
||
|
public ForceMode _forceMode
|
||
|
{
|
||
|
get { return forceMode; }
|
||
|
set { forceMode = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Projects the force to the forward.")]
|
||
|
private bool projectForward = false;
|
||
|
public bool _projectForward
|
||
|
{
|
||
|
get { return projectForward; }
|
||
|
set { projectForward = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Radius of the force.")]
|
||
|
private float size = 5f;
|
||
|
public float Size
|
||
|
{
|
||
|
get { return size; }
|
||
|
set { size = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Capsule Radius size of the fore.")]
|
||
|
private float capsuleRadius = 2f;
|
||
|
public float CapsuleRadius
|
||
|
{
|
||
|
get { return capsuleRadius; }
|
||
|
set { capsuleRadius = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Box vector size of the fore.")]
|
||
|
private Vector3 boxSize = new Vector3(5f, 5f, 5f);
|
||
|
public Vector3 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 TransformProperties transformProperties;
|
||
|
public 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("Force type properties.")]
|
||
|
private ForceTypeProperties forceTypeProperties;
|
||
|
public ForceTypeProperties _forceTypeProperties
|
||
|
{
|
||
|
get { return forceTypeProperties; }
|
||
|
set { forceTypeProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Filter properties options.")]
|
||
|
private FilterProperties filterProperties;
|
||
|
public FilterProperties _filterProperties
|
||
|
{
|
||
|
get { return filterProperties; }
|
||
|
set { filterProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Event properties options.")]
|
||
|
private EventProperties eventProperties;
|
||
|
public EventProperties _eventProperties
|
||
|
{
|
||
|
get { return eventProperties; }
|
||
|
set { eventProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Draw gravity properties.")]
|
||
|
private DrawGravityProperties drawGravityProperties;
|
||
|
public DrawGravityProperties _drawGravityProperties
|
||
|
{
|
||
|
get { return drawGravityProperties; }
|
||
|
set { drawGravityProperties = value; }
|
||
|
}
|
||
|
|
||
|
[SerializeField, Tooltip("Memory Properties.")]
|
||
|
private MemoryProperties memoryProperties;
|
||
|
public 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;
|
||
|
|
||
|
//Pre-Allocated Objects
|
||
|
private Collider[] colliderList;
|
||
|
private RaycastHit[] 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 && (_shape != Shape.Box) && (_shape != Shape.Sphere))
|
||
|
{
|
||
|
_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 Collider[_memoryProperties.ColliderBuffer];
|
||
|
raycastHitList = new RaycastHit[_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(Rigidbody rigid, Transform trans, Collider coll)
|
||
|
{
|
||
|
var transPos = trans.position;
|
||
|
|
||
|
switch (_forcePositionProperties.ForcePosition)
|
||
|
{
|
||
|
case ForcePosition.ThisTransform:
|
||
|
break;
|
||
|
case ForcePosition.ClosestCollider:
|
||
|
if (_forcePositionProperties.ClosestColliders != null)
|
||
|
{
|
||
|
if (_forcePositionProperties.ClosestColliders.Count > 0)
|
||
|
{
|
||
|
float heightOffset = _forcePositionProperties.HeightOffset;
|
||
|
|
||
|
if (!_forcePositionProperties.UseEffectedClosestPoint)
|
||
|
{
|
||
|
var point = FindClosestPoints(rigid.position, _forcePositionProperties.ClosestColliders);
|
||
|
|
||
|
transPos = GetVectorHeightOffset(point, rigid.position, heightOffset);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Vector3 pointA = FindClosestPoints(coll.transform.position, _forcePositionProperties.ClosestColliders);
|
||
|
Vector3 pointB = FindClosestPoints(pointA, coll);
|
||
|
|
||
|
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 (_forceType)
|
||
|
{
|
||
|
case ForceType.ForceAtPosition:
|
||
|
ApplyCGFForceAtPosition(rigid, transPos, trans);
|
||
|
break;
|
||
|
case ForceType.Force:
|
||
|
ApplyCGFForce(rigid, transPos, trans);
|
||
|
break;
|
||
|
case ForceType.Torque:
|
||
|
ApplyCGFTorque(rigid, transPos, trans);
|
||
|
break;
|
||
|
case ForceType.ExplosionForce:
|
||
|
ApplyCGFExplosionForce(rigid, transPos, trans);
|
||
|
break;
|
||
|
case ForceType.GravitationalAttraction:
|
||
|
ApplyCGFGravitationalAttraction(rigid, transPos, trans);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void ApplyCGFForceAtPosition(Rigidbody rigid, Vector3 transPos, Transform trans)
|
||
|
{
|
||
|
Vector3 forceAtPoint = transPos;
|
||
|
|
||
|
if (_projectForward || _shape == Shape.Raycast)
|
||
|
{
|
||
|
forceAtPoint = (trans.forward * ForcePower) - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
forceAtPoint = ((rigid.transform.position - transPos) * ForcePower) - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
|
||
|
rigid.AddForceAtPosition(forceAtPoint, transPos, _forceMode);
|
||
|
}
|
||
|
|
||
|
private void ApplyCGFForce(Rigidbody rigid, Vector3 transPos, Transform trans)
|
||
|
{
|
||
|
Vector3 force = transPos;
|
||
|
|
||
|
if (_projectForward || _shape == Shape.Raycast)
|
||
|
{
|
||
|
force = (trans.forward * ForcePower) - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
force = ((rigid.transform.position - transPos) * ForcePower) - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
|
||
|
rigid.AddForce(force, _forceMode);
|
||
|
}
|
||
|
|
||
|
private void ApplyCGFTorque(Rigidbody rigid, Vector3 transPos, Transform trans)
|
||
|
{
|
||
|
Vector3 torque = transPos;
|
||
|
|
||
|
torque = (trans.right * ForcePower) - (AngularVelocityDamping * rigid.angularVelocity);
|
||
|
|
||
|
rigid.maxAngularVelocity = _forceTypeProperties.TorqueMaxAngularVelocity;
|
||
|
rigid.AddTorque(torque, _forceMode);
|
||
|
}
|
||
|
|
||
|
private void ApplyCGFExplosionForce(Rigidbody rigid, Vector3 transPos, Transform trans)
|
||
|
{
|
||
|
rigid.AddExplosionForce(ForcePower, transPos, Size, _forceTypeProperties.ExplosionForceUpwardsModifier, _forceMode);
|
||
|
}
|
||
|
|
||
|
private void ApplyCGFGravitationalAttraction(Rigidbody rigid, Vector3 transPos, Transform trans)
|
||
|
{
|
||
|
Vector3 gravitationalAttraction = transPos;
|
||
|
|
||
|
if (_projectForward || _shape == Shape.Raycast)
|
||
|
{
|
||
|
gravitationalAttraction = trans.forward * rigid.mass * ForcePower / (trans.forward).sqrMagnitude - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gravitationalAttraction = ((rigid.position - transPos).normalized * rigid.mass * ForcePower / (rigid.position - transPos).sqrMagnitude) - (VelocityDamping * rigid.velocity);
|
||
|
}
|
||
|
|
||
|
if (float.IsNaN(gravitationalAttraction.x) && float.IsNaN(gravitationalAttraction.y) && float.IsNaN(gravitationalAttraction.z))
|
||
|
{
|
||
|
gravitationalAttraction = Vector3.zero;
|
||
|
}
|
||
|
|
||
|
rigid.AddForce(gravitationalAttraction, _forceMode);
|
||
|
}
|
||
|
|
||
|
//Calculate and Estimate the force
|
||
|
private void CalculateAndEstimateForce()
|
||
|
{
|
||
|
if (_shape == Shape.Sphere || _shape == Shape.Box)
|
||
|
{
|
||
|
#region Sphere
|
||
|
|
||
|
colliderListCount = 0;
|
||
|
|
||
|
if (_shape == Shape.Sphere)
|
||
|
{
|
||
|
if (_memoryProperties.NonAllocPhysics)
|
||
|
{
|
||
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||
|
colliderListCount = Physics.OverlapSphereNonAlloc(this.transform.position, Size, colliderList, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
#else
|
||
|
Debug.LogWarning(WarningMessageNonAllocUnity_5_3);
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
colliderList = Physics.OverlapSphere(this.transform.position, Size, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
colliderListCount = colliderList.Length;
|
||
|
}
|
||
|
}
|
||
|
if (_shape == Shape.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)
|
||
|
{
|
||
|
colliderListCount = Physics.OverlapBoxNonAlloc(this.transform.position, BoxSize, colliderList, this.transform.rotation, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
colliderList = Physics.OverlapBox(this.transform.position, BoxSize, this.transform.rotation, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
colliderListCount = colliderList.Length;
|
||
|
}
|
||
|
#else
|
||
|
Debug.LogWarning(WarningMessageBoxUnity_5_3);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
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 / Capsule
|
||
|
|
||
|
//Circular Gravity Force Transform
|
||
|
Transform cgfTran = this.transform;
|
||
|
|
||
|
raycastHitListCount = 0;
|
||
|
|
||
|
if (_shape == Shape.Raycast)
|
||
|
{
|
||
|
if (_memoryProperties.NonAllocPhysics)
|
||
|
{
|
||
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||
|
raycastHitListCount = Physics.RaycastNonAlloc(cgfTran.position, cgfTran.rotation * Vector3.forward, raycastHitList, Size, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
#else
|
||
|
Debug.LogWarning(WarningMessageNonAllocUnity_5_3);
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
raycastHitList = Physics.RaycastAll(cgfTran.position, cgfTran.rotation * Vector3.forward, Size, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
raycastHitListCount = raycastHitList.Length;
|
||
|
}
|
||
|
}
|
||
|
else if (_shape == Shape.Capsule)
|
||
|
{
|
||
|
if (_memoryProperties.NonAllocPhysics)
|
||
|
{
|
||
|
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||
|
raycastHitListCount = Physics.CapsuleCastNonAlloc(cgfTran.position, cgfTran.position + ((cgfTran.rotation * Vector3.back)), capsuleRadius, cgfTran.position - ((cgfTran.position + (cgfTran.rotation * (Vector3.back)))), raycastHitList, Size, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
#else
|
||
|
Debug.LogWarning(WarningMessageNonAllocUnity_5_3);
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
raycastHitList = Physics.CapsuleCastAll(cgfTran.position, cgfTran.position + ((cgfTran.rotation * Vector3.back)), capsuleRadius, cgfTran.position - ((cgfTran.position + (cgfTran.rotation * (Vector3.back)))), Size, _memoryProperties.ColliderLayerMask, QueryTriggerInteraction.Ignore);
|
||
|
raycastHitListCount = raycastHitList.Length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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(Vector3 point, List<Collider> closestColliders)
|
||
|
{
|
||
|
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, closestPoint);
|
||
|
|
||
|
var newPoint = FindClosestPoints(point, closestColliders[i]);
|
||
|
|
||
|
if (distance > Vector3.Distance(point, newPoint))
|
||
|
{
|
||
|
closestPoint = newPoint;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return closestPoint;
|
||
|
}
|
||
|
|
||
|
public Vector3 FindClosestPoints(Vector3 point, Collider closestCollider)
|
||
|
{
|
||
|
Vector3 closestPoint = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);
|
||
|
|
||
|
if (closestCollider != null)
|
||
|
{
|
||
|
var distance = Vector3.Distance(point, closestPoint);
|
||
|
|
||
|
var newPoint = point;
|
||
|
|
||
|
#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)
|
||
|
// newPoint = Physics.ClosestPoint(point, closestCollider, closestCollider.transform.position, closestCollider.transform.rotation);
|
||
|
newPoint = closestCollider.ClosestPointOnBounds(point);
|
||
|
#else
|
||
|
Debug.LogWarning(WarningMessageClosestPoint_5_6);
|
||
|
#endif
|
||
|
|
||
|
if (distance > Vector3.Distance(point, newPoint))
|
||
|
{
|
||
|
closestPoint = newPoint;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
closestPoint = point;
|
||
|
}
|
||
|
|
||
|
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";
|
||
|
|
||
|
//Creates Circular Gravity Force component
|
||
|
cgf.AddComponent<CGF>()._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 (_shape)
|
||
|
{
|
||
|
case Shape.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 = 12;
|
||
|
// #elif (UNITY_5_5)
|
||
|
lineRenderer.numPositions = 12;
|
||
|
// #else
|
||
|
// lineRenderer.SetVertexCount(12);
|
||
|
// #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);
|
||
|
lineRenderer.SetPosition(8, cgfTran.position + ((cgfTran.rotation * Vector3.forward) * Size));
|
||
|
lineRenderer.SetPosition(9, cgfTran.position);
|
||
|
lineRenderer.SetPosition(10, cgfTran.position + ((cgfTran.rotation * Vector3.back) * Size));
|
||
|
lineRenderer.SetPosition(11, cgfTran.position);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case Shape.Capsule:
|
||
|
|
||
|
//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 = 17;
|
||
|
// #elif (UNITY_5_5)
|
||
|
lineRenderer.numPositions = 17;
|
||
|
// #else
|
||
|
// lineRenderer.SetVertexCount(17);
|
||
|
// #endif
|
||
|
|
||
|
//Starting Point
|
||
|
lineRenderer.SetPosition(0, cgfTran.position + ((cgfTran.rotation * Vector3.up) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(1, cgfTran.position);
|
||
|
lineRenderer.SetPosition(2, cgfTran.position + ((cgfTran.rotation * Vector3.down) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(3, cgfTran.position);
|
||
|
lineRenderer.SetPosition(4, cgfTran.position + ((cgfTran.rotation * Vector3.left) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(5, cgfTran.position);
|
||
|
lineRenderer.SetPosition(6, cgfTran.position + ((cgfTran.rotation * Vector3.right) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(7, cgfTran.position);
|
||
|
|
||
|
//Middle Line
|
||
|
Vector3 endPointLoc = cgfTran.position + ((cgfTran.rotation * Vector3.forward) * Size);
|
||
|
lineRenderer.SetPosition(8, endPointLoc);
|
||
|
|
||
|
//End Point
|
||
|
lineRenderer.SetPosition(9, endPointLoc + ((cgfTran.rotation * Vector3.up) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(10, endPointLoc);
|
||
|
lineRenderer.SetPosition(11, endPointLoc + ((cgfTran.rotation * Vector3.down) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(12, endPointLoc);
|
||
|
lineRenderer.SetPosition(13, endPointLoc + ((cgfTran.rotation * Vector3.left) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(14, endPointLoc);
|
||
|
lineRenderer.SetPosition(15, endPointLoc + ((cgfTran.rotation * Vector3.right) * capsuleRadius));
|
||
|
lineRenderer.SetPosition(16, endPointLoc);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case Shape.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.forward) * Size));
|
||
|
|
||
|
break;
|
||
|
|
||
|
case Shape.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 = 12;
|
||
|
// #elif (UNITY_5_5)
|
||
|
lineRenderer.numPositions = 12;
|
||
|
// #else
|
||
|
// lineRenderer.SetVertexCount(12);
|
||
|
// #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);
|
||
|
lineRenderer.SetPosition(8, cgfTran.position + ((cgfTran.rotation * Vector3.forward) * BoxSize.z));
|
||
|
lineRenderer.SetPosition(9, cgfTran.position);
|
||
|
lineRenderer.SetPosition(10, cgfTran.position + ((cgfTran.rotation * Vector3.back) * BoxSize.z));
|
||
|
lineRenderer.SetPosition(11, 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 (_shape)
|
||
|
{
|
||
|
case CGF.Shape.Sphere:
|
||
|
|
||
|
Gizmos.color = DebugGravityLineColorB;
|
||
|
Gizmos.DrawSphere(cgfTran.position, Size);
|
||
|
|
||
|
if (!isSelected)
|
||
|
{
|
||
|
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);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.forward) * Size), cgfTran.position);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.back) * Size), cgfTran.position);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Gizmos.color = DebugGravityLineColorB;
|
||
|
Gizmos.DrawSphere(cgfTran.position, Size);
|
||
|
}
|
||
|
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CGF.Shape.Capsule:
|
||
|
|
||
|
Gizmos.color = DebugGravityLineColorA;
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.up) * capsuleRadius), cgfTran.position);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.down) * capsuleRadius), cgfTran.position);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.left) * capsuleRadius), cgfTran.position);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.right) * capsuleRadius), cgfTran.position);
|
||
|
|
||
|
Vector3 endPointLoc = cgfTran.position + ((cgfTran.rotation * Vector3.forward) * Size);
|
||
|
|
||
|
Gizmos.DrawLine(cgfTran.position, endPointLoc);
|
||
|
|
||
|
Gizmos.DrawLine(endPointLoc + ((cgfTran.rotation * Vector3.up) * capsuleRadius), endPointLoc);
|
||
|
Gizmos.DrawLine(endPointLoc + ((cgfTran.rotation * Vector3.down) * capsuleRadius), endPointLoc);
|
||
|
Gizmos.DrawLine(endPointLoc + ((cgfTran.rotation * Vector3.left) * capsuleRadius), endPointLoc);
|
||
|
Gizmos.DrawLine(endPointLoc + ((cgfTran.rotation * Vector3.right) * capsuleRadius), endPointLoc);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CGF.Shape.Raycast:
|
||
|
|
||
|
Gizmos.color = DebugGravityLineColorA;
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.forward) * Size), cgfTran.position);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CGF.Shape.Box:
|
||
|
|
||
|
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);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.forward) * BoxSize.z), cgfTran.position);
|
||
|
Gizmos.DrawLine(cgfTran.position + ((cgfTran.rotation * Vector3.back) * BoxSize.z), cgfTran.position);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (memoryProperties.SeeColliders)
|
||
|
{
|
||
|
if (_shape == Shape.Sphere || _shape == Shape.Box)
|
||
|
{
|
||
|
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 (_shape == Shape.Capsule || _shape == Shape.Raycast)
|
||
|
{
|
||
|
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 == ForcePosition.ClosestCollider)
|
||
|
{
|
||
|
switch (_forceType)
|
||
|
{
|
||
|
case ForceType.ForceAtPosition:
|
||
|
case ForceType.Force:
|
||
|
case ForceType.ExplosionForce:
|
||
|
case ForceType.GravitationalAttraction:
|
||
|
|
||
|
Gizmos.color = DebugGravityLineColorA;
|
||
|
if (_shape == Shape.Sphere || _shape == Shape.Box)
|
||
|
{
|
||
|
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].transform.position, _forcePositionProperties.ClosestColliders);
|
||
|
Vector3 pointB = Vector3.zero;
|
||
|
|
||
|
if (_forcePositionProperties.UseEffectedClosestPoint)
|
||
|
{
|
||
|
pointB = FindClosestPoints(pointA, colliderList[i]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pointB = colliderList[i].transform.position;
|
||
|
}
|
||
|
|
||
|
Gizmos.DrawWireSphere(pointA, .01f);
|
||
|
Gizmos.DrawLine(pointA, pointB);
|
||
|
Gizmos.DrawWireSphere(pointB, .01f);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_shape == Shape.Capsule || _shape == Shape.Raycast)
|
||
|
{
|
||
|
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.transform.position, _forcePositionProperties.ClosestColliders);
|
||
|
Vector3 pointB = Vector3.zero;
|
||
|
|
||
|
if (_forcePositionProperties.UseEffectedClosestPoint)
|
||
|
{
|
||
|
pointB = FindClosestPoints(pointA, raycastHitList[i].collider);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pointB = raycastHitList[i].collider.transform.position;
|
||
|
}
|
||
|
|
||
|
Gizmos.DrawWireSphere(pointA, .01f);
|
||
|
Gizmos.DrawLine(pointA, pointB);
|
||
|
Gizmos.DrawWireSphere(pointB, .01f);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case ForceType.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 meshFilter = _forcePositionProperties.ClosestColliders[i].gameObject.GetComponent<MeshFilter>();
|
||
|
if (meshFilter != null)
|
||
|
{
|
||
|
var mesh = meshFilter.sharedMesh;
|
||
|
|
||
|
if (mesh != null)
|
||
|
{
|
||
|
Gizmos.DrawWireMesh(mesh, meshFilter.gameObject.transform.position, meshFilter.gameObject.transform.rotation, meshFilter.gameObject.transform.lossyScale);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var bound = _forcePositionProperties.ClosestColliders[i].bounds;
|
||
|
Gizmos.DrawWireCube(bound.center, bound.size);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
}
|