Space soccer polish and editor preview button
This commit is contained in:
parent
a7c1359f97
commit
147e41ca35
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 75bf1bb8530d74e468ff02c71de6a222
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1e3f966a8e1c81a429b6881944ddb88a
|
||||
folderAsset: yes
|
||||
timeCreated: 1620639369
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,71 @@
|
|||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
public class MinMaxRangeAttribute : PropertyAttribute
|
||||
{
|
||||
public float min;
|
||||
public float max;
|
||||
|
||||
public MinMaxRangeAttribute( float min, float max )
|
||||
{
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomPropertyDrawer( typeof( MinMaxRangeAttribute ) )]
|
||||
public class MixMaxRangeAttributeDrawer : PropertyDrawer
|
||||
{
|
||||
private const float MIN_MAX_SLIDER_TEXT_FIELD_WIDTH = 45f;
|
||||
|
||||
// Min-max slider credit: https://github.com/Unity-Technologies/UnityCsReference/blob/61f92bd79ae862c4465d35270f9d1d57befd1761/Editor/Mono/Inspector/LightEditor.cs#L328-L363
|
||||
public override void OnGUI( Rect position, SerializedProperty property, GUIContent label )
|
||||
{
|
||||
MinMaxRangeAttribute minMaxRange = attribute as MinMaxRangeAttribute;
|
||||
|
||||
SerializedProperty minProp = property.FindPropertyRelative( "x" );
|
||||
SerializedProperty maxProp = property.FindPropertyRelative( "y" );
|
||||
|
||||
position = EditorGUI.PrefixLabel( position, label );
|
||||
EditorGUI.BeginProperty( position, GUIContent.none, property );
|
||||
|
||||
Rect minRect = new Rect( position ) { width = MIN_MAX_SLIDER_TEXT_FIELD_WIDTH };
|
||||
Rect maxRect = new Rect( position ) { xMin = position.xMax - MIN_MAX_SLIDER_TEXT_FIELD_WIDTH };
|
||||
Rect sliderRect = new Rect( position ) { xMin = minRect.xMax + 5f, xMax = maxRect.xMin - 5f };
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUI.PropertyField( minRect, minProp, GUIContent.none );
|
||||
|
||||
Vector2 value = property.vector2Value;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUI.MinMaxSlider( sliderRect, ref value.x, ref value.y, minMaxRange.min, minMaxRange.max );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
property.vector2Value = value;
|
||||
|
||||
EditorGUI.PropertyField( maxRect, maxProp, GUIContent.none );
|
||||
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
float x = minProp.floatValue;
|
||||
float y = maxProp.floatValue;
|
||||
|
||||
if( x < minMaxRange.min || x > minMaxRange.max )
|
||||
minProp.floatValue = Mathf.Clamp( x, minMaxRange.min, minMaxRange.max );
|
||||
if( y < minMaxRange.min || y > minMaxRange.max )
|
||||
maxProp.floatValue = Mathf.Clamp( y, minMaxRange.min, minMaxRange.max );
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 277efd8192415fd4fb70032186bd5ed0
|
||||
timeCreated: 1620638811
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,459 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Point" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
public partial class BezierPoint : MonoBehaviour
|
||||
{
|
||||
public Vector3 localPosition
|
||||
{
|
||||
get { return transform.localPosition; }
|
||||
set
|
||||
{
|
||||
if( transform.localPosition == value )
|
||||
return;
|
||||
|
||||
transform.localPosition = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3 m_position;
|
||||
public Vector3 position
|
||||
{
|
||||
get { return m_position; }
|
||||
set
|
||||
{
|
||||
if( transform.position == value )
|
||||
return;
|
||||
|
||||
transform.position = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
public Quaternion localRotation
|
||||
{
|
||||
get { return transform.localRotation; }
|
||||
set
|
||||
{
|
||||
if( transform.localRotation == value )
|
||||
return;
|
||||
|
||||
transform.localRotation = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
public Quaternion rotation
|
||||
{
|
||||
get { return transform.rotation; }
|
||||
set
|
||||
{
|
||||
if( transform.rotation == value )
|
||||
return;
|
||||
|
||||
transform.rotation = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 localEulerAngles
|
||||
{
|
||||
get { return transform.localEulerAngles; }
|
||||
set
|
||||
{
|
||||
if( transform.localEulerAngles == value )
|
||||
return;
|
||||
|
||||
transform.localEulerAngles = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 eulerAngles
|
||||
{
|
||||
get { return transform.eulerAngles; }
|
||||
set
|
||||
{
|
||||
if( transform.eulerAngles == value )
|
||||
return;
|
||||
|
||||
transform.eulerAngles = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 localScale
|
||||
{
|
||||
get { return transform.localScale; }
|
||||
set
|
||||
{
|
||||
if( transform.localScale == value )
|
||||
return;
|
||||
|
||||
transform.localScale = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3 m_precedingControlPointLocalPosition = Vector3.left;
|
||||
public Vector3 precedingControlPointLocalPosition
|
||||
{
|
||||
get { return m_precedingControlPointLocalPosition; }
|
||||
set
|
||||
{
|
||||
if( m_precedingControlPointLocalPosition == value )
|
||||
return;
|
||||
|
||||
m_precedingControlPointLocalPosition = value;
|
||||
m_precedingControlPointPosition = transform.TransformPoint( value );
|
||||
|
||||
if( m_handleMode == HandleMode.Aligned )
|
||||
{
|
||||
m_followingControlPointLocalPosition = -m_precedingControlPointLocalPosition.normalized * m_followingControlPointLocalPosition.magnitude;
|
||||
m_followingControlPointPosition = transform.TransformPoint( m_followingControlPointLocalPosition );
|
||||
}
|
||||
else if( m_handleMode == HandleMode.Mirrored )
|
||||
{
|
||||
m_followingControlPointLocalPosition = -m_precedingControlPointLocalPosition;
|
||||
m_followingControlPointPosition = transform.TransformPoint( m_followingControlPointLocalPosition );
|
||||
}
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3 m_precedingControlPointPosition;
|
||||
public Vector3 precedingControlPointPosition
|
||||
{
|
||||
get { return m_precedingControlPointPosition; }
|
||||
set
|
||||
{
|
||||
if( m_precedingControlPointPosition == value )
|
||||
return;
|
||||
|
||||
m_precedingControlPointPosition = value;
|
||||
m_precedingControlPointLocalPosition = transform.InverseTransformPoint( value );
|
||||
|
||||
if( transform.hasChanged )
|
||||
{
|
||||
m_position = transform.position;
|
||||
m_followingControlPointPosition = transform.TransformPoint( m_followingControlPointLocalPosition );
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange;
|
||||
transform.hasChanged = false;
|
||||
}
|
||||
|
||||
if( m_handleMode == HandleMode.Aligned )
|
||||
{
|
||||
m_followingControlPointPosition = m_position - ( m_precedingControlPointPosition - m_position ).normalized *
|
||||
( m_followingControlPointPosition - m_position ).magnitude;
|
||||
m_followingControlPointLocalPosition = transform.InverseTransformPoint( m_followingControlPointPosition );
|
||||
}
|
||||
else if( m_handleMode == HandleMode.Mirrored )
|
||||
{
|
||||
m_followingControlPointPosition = 2f * m_position - m_precedingControlPointPosition;
|
||||
m_followingControlPointLocalPosition = transform.InverseTransformPoint( m_followingControlPointPosition );
|
||||
}
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3 m_followingControlPointLocalPosition = Vector3.right;
|
||||
public Vector3 followingControlPointLocalPosition
|
||||
{
|
||||
get { return m_followingControlPointLocalPosition; }
|
||||
set
|
||||
{
|
||||
if( m_followingControlPointLocalPosition == value )
|
||||
return;
|
||||
|
||||
m_followingControlPointLocalPosition = value;
|
||||
m_followingControlPointPosition = transform.TransformPoint( value );
|
||||
|
||||
if( m_handleMode == HandleMode.Aligned )
|
||||
{
|
||||
m_precedingControlPointLocalPosition = -m_followingControlPointLocalPosition.normalized * m_precedingControlPointLocalPosition.magnitude;
|
||||
m_precedingControlPointPosition = transform.TransformPoint( m_precedingControlPointLocalPosition );
|
||||
}
|
||||
else if( m_handleMode == HandleMode.Mirrored )
|
||||
{
|
||||
m_precedingControlPointLocalPosition = -m_followingControlPointLocalPosition;
|
||||
m_precedingControlPointPosition = transform.TransformPoint( m_precedingControlPointLocalPosition );
|
||||
}
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3 m_followingControlPointPosition;
|
||||
public Vector3 followingControlPointPosition
|
||||
{
|
||||
get { return m_followingControlPointPosition; }
|
||||
set
|
||||
{
|
||||
if( m_followingControlPointPosition == value )
|
||||
return;
|
||||
|
||||
m_followingControlPointPosition = value;
|
||||
m_followingControlPointLocalPosition = transform.InverseTransformPoint( value );
|
||||
|
||||
if( transform.hasChanged )
|
||||
{
|
||||
m_position = transform.position;
|
||||
m_precedingControlPointPosition = transform.TransformPoint( m_precedingControlPointLocalPosition );
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange;
|
||||
transform.hasChanged = false;
|
||||
}
|
||||
|
||||
if( m_handleMode == HandleMode.Aligned )
|
||||
{
|
||||
m_precedingControlPointPosition = m_position - ( m_followingControlPointPosition - m_position ).normalized *
|
||||
( m_precedingControlPointPosition - m_position ).magnitude;
|
||||
m_precedingControlPointLocalPosition = transform.InverseTransformPoint( m_precedingControlPointPosition );
|
||||
}
|
||||
else if( m_handleMode == HandleMode.Mirrored )
|
||||
{
|
||||
m_precedingControlPointPosition = 2f * m_position - m_followingControlPointPosition;
|
||||
m_precedingControlPointLocalPosition = transform.InverseTransformPoint( m_precedingControlPointPosition );
|
||||
}
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private HandleMode m_handleMode = HandleMode.Mirrored;
|
||||
public HandleMode handleMode
|
||||
{
|
||||
get { return m_handleMode; }
|
||||
set
|
||||
{
|
||||
if( m_handleMode == value )
|
||||
return;
|
||||
|
||||
m_handleMode = value;
|
||||
|
||||
if( value == HandleMode.Aligned || value == HandleMode.Mirrored )
|
||||
{
|
||||
// Temporarily change the value of m_precedingControlPointLocalPosition so that it will be different from precedingControlPointLocalPosition
|
||||
// and precedingControlPointLocalPosition's setter will run
|
||||
Vector3 _precedingControlPointLocalPosition = m_precedingControlPointLocalPosition;
|
||||
m_precedingControlPointLocalPosition -= Vector3.one;
|
||||
|
||||
precedingControlPointLocalPosition = _precedingControlPointLocalPosition;
|
||||
}
|
||||
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs( "normal" )]
|
||||
private Vector3 m_normal = Vector3.up;
|
||||
public Vector3 normal
|
||||
{
|
||||
get { return m_normal; }
|
||||
set
|
||||
{
|
||||
if( m_normal == value )
|
||||
return;
|
||||
|
||||
m_normal = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.NormalChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs( "autoCalculatedNormalAngleOffset" )]
|
||||
private float m_autoCalculatedNormalAngleOffset = 0f;
|
||||
public float autoCalculatedNormalAngleOffset
|
||||
{
|
||||
get { return m_autoCalculatedNormalAngleOffset; }
|
||||
set
|
||||
{
|
||||
if( m_autoCalculatedNormalAngleOffset == value )
|
||||
return;
|
||||
|
||||
m_autoCalculatedNormalAngleOffset = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.NormalOffsetChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Vector3[] m_intermediateNormals;
|
||||
public Vector3[] intermediateNormals
|
||||
{
|
||||
get { return m_intermediateNormals; }
|
||||
set
|
||||
{
|
||||
// In this special case, don't early exit if the assigned array is the same because one of its elements might have changed.
|
||||
// We can safely early exit if the assigned value was null or empty, though
|
||||
if( ( m_intermediateNormals == null || m_intermediateNormals.Length == 0 ) && ( value == null || value.Length == 0 ) )
|
||||
return;
|
||||
|
||||
m_intermediateNormals = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.NormalChange;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs( "extraData" )]
|
||||
private ExtraData m_extraData;
|
||||
public ExtraData extraData
|
||||
{
|
||||
get { return m_extraData; }
|
||||
set
|
||||
{
|
||||
if( m_extraData == value )
|
||||
return;
|
||||
|
||||
m_extraData = value;
|
||||
spline.dirtyFlags |= InternalDirtyFlags.ExtraDataChange;
|
||||
}
|
||||
}
|
||||
#pragma warning restore 0649
|
||||
|
||||
public BezierSpline spline { get; internal set; }
|
||||
public int index { get; internal set; }
|
||||
|
||||
public BezierPoint previousPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if( spline )
|
||||
{
|
||||
if( index > 0 )
|
||||
return spline.endPoints[index - 1];
|
||||
else if( spline.loop )
|
||||
return spline.endPoints[spline.endPoints.Count - 1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public BezierPoint nextPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if( spline )
|
||||
{
|
||||
if( index < spline.endPoints.Count - 1 )
|
||||
return spline.endPoints[index + 1];
|
||||
else if( spline.loop )
|
||||
return spline.endPoints[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
transform.hasChanged = true;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if( spline )
|
||||
spline.dirtyFlags |= InternalDirtyFlags.All;
|
||||
}
|
||||
|
||||
public void CopyTo( BezierPoint other )
|
||||
{
|
||||
other.transform.localPosition = transform.localPosition;
|
||||
other.transform.localRotation = transform.localRotation;
|
||||
other.transform.localScale = transform.localScale;
|
||||
|
||||
other.m_handleMode = m_handleMode;
|
||||
|
||||
other.m_precedingControlPointLocalPosition = m_precedingControlPointLocalPosition;
|
||||
other.m_followingControlPointLocalPosition = m_followingControlPointLocalPosition;
|
||||
|
||||
other.m_normal = m_normal;
|
||||
other.m_autoCalculatedNormalAngleOffset = m_autoCalculatedNormalAngleOffset;
|
||||
|
||||
other.m_extraData = m_extraData;
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
m_position = transform.position;
|
||||
m_precedingControlPointPosition = transform.TransformPoint( m_precedingControlPointLocalPosition );
|
||||
m_followingControlPointPosition = transform.TransformPoint( m_followingControlPointLocalPosition );
|
||||
|
||||
transform.hasChanged = false;
|
||||
}
|
||||
|
||||
internal void RefreshIfChanged()
|
||||
{
|
||||
if( transform.hasChanged )
|
||||
{
|
||||
Refresh();
|
||||
spline.dirtyFlags |= InternalDirtyFlags.EndPointTransformChange | InternalDirtyFlags.ControlPointPositionChange;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetNormalAndResetIntermediateNormals( Vector3 normal, string undo )
|
||||
{
|
||||
if( spline && spline.autoCalculateNormals )
|
||||
return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if( !string.IsNullOrEmpty( undo ) )
|
||||
UnityEditor.Undo.RecordObject( this, undo );
|
||||
#endif
|
||||
|
||||
this.normal = normal;
|
||||
intermediateNormals = null;
|
||||
|
||||
BezierPoint previousPoint = this.previousPoint;
|
||||
if( previousPoint && previousPoint.m_intermediateNormals != null && previousPoint.m_intermediateNormals.Length > 0 )
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if( !string.IsNullOrEmpty( undo ) )
|
||||
UnityEditor.Undo.RecordObject( previousPoint, undo );
|
||||
#endif
|
||||
|
||||
previousPoint.intermediateNormals = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
localPosition = Vector3.zero;
|
||||
localRotation = Quaternion.identity;
|
||||
localScale = Vector3.one;
|
||||
|
||||
precedingControlPointLocalPosition = Vector3.left;
|
||||
followingControlPointLocalPosition = Vector3.right;
|
||||
|
||||
m_normal = Vector3.up;
|
||||
m_autoCalculatedNormalAngleOffset = 0f;
|
||||
|
||||
m_extraData = new ExtraData();
|
||||
|
||||
transform.hasChanged = true;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[ContextMenu( "Invert Spline" )]
|
||||
private void InvertSplineContextMenu()
|
||||
{
|
||||
if( spline )
|
||||
spline.InvertSpline( "Invert spline" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b9cf9c5931a3b3c4ba456c8213d7ebfc
|
||||
timeCreated: 1472737829
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"name": "BezierSolution.Runtime"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 624c061ee4dfdaf4787b9c0bb51b4c1f
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a3dbf94c21a22d74d895b2051a04ba1e
|
||||
timeCreated: 1620216034
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -400
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4b55326d0aea81b42b7f407fffdad047
|
||||
folderAsset: yes
|
||||
timeCreated: 1620724489
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 494545cd2e9cbec47adb2c1adf6066ab
|
||||
timeCreated: 1472738252
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,84 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 44b1882f3e87f214ba0c12a8e3b15d36
|
||||
timeCreated: 1620040793
|
||||
licenseType: Store
|
||||
ModelImporter:
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: tentacle_6_geo
|
||||
100002: //RootNode
|
||||
400000: tentacle_6_geo
|
||||
400002: //RootNode
|
||||
2300000: tentacle_6_geo
|
||||
3300000: tentacle_6_geo
|
||||
4300000: tentacle_6_geo
|
||||
materials:
|
||||
importMaterials: 0
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
serializedVersion: 2
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,79 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: OctopusArm
|
||||
m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _NORMALMAP
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 2800000, guid: 89e1b1c005d29cf4598ea861deb35a80, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: cd20479f79180f440ad81177db5e0b12, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SamplePoint: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SampleRange: {r: 0, g: 1, b: 0, a: 0}
|
||||
- _VertexRange: {r: 0, g: 1, b: 0, a: 0}
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6b88831b1ed3c38439c9be5ac64f87c1
|
||||
timeCreated: 1620040793
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
After Width: | Height: | Size: 259 KiB |
|
@ -0,0 +1,68 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cd20479f79180f440ad81177db5e0b12
|
||||
timeCreated: 1620724293
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 519da3ae01006d64ea40c00e92df6614
|
||||
folderAsset: yes
|
||||
timeCreated: 1472735538
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9d0566a88081c1b46b6236e5b2575a7c
|
||||
timeCreated: 1472737433
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomPropertyDrawer( typeof( BezierPoint.ExtraData ) )]
|
||||
public class BezierPointExtraDataDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI( Rect position, SerializedProperty property, GUIContent label )
|
||||
{
|
||||
EditorGUI.BeginProperty( position, label, property );
|
||||
position = EditorGUI.PrefixLabel( position, GUIUtility.GetControlID( FocusType.Passive ), label );
|
||||
|
||||
float quarterWidth = position.width * 0.25f;
|
||||
Rect c1Rect = new Rect( position.x, position.y, quarterWidth, position.height );
|
||||
Rect c2Rect = new Rect( position.x + quarterWidth, position.y, quarterWidth, position.height );
|
||||
Rect c3Rect = new Rect( position.x + 2f * quarterWidth, position.y, quarterWidth, position.height );
|
||||
Rect c4Rect = new Rect( position.x + 3f * quarterWidth, position.y, quarterWidth, position.height );
|
||||
|
||||
EditorGUI.PropertyField( c1Rect, property.FindPropertyRelative( "c1" ), GUIContent.none );
|
||||
EditorGUI.PropertyField( c2Rect, property.FindPropertyRelative( "c2" ), GUIContent.none );
|
||||
EditorGUI.PropertyField( c3Rect, property.FindPropertyRelative( "c3" ), GUIContent.none );
|
||||
EditorGUI.PropertyField( c4Rect, property.FindPropertyRelative( "c4" ), GUIContent.none );
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d6fe536a44fc10242a73e0114a06befa
|
||||
timeCreated: 1520266844
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,757 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
public static class BezierSettings
|
||||
{
|
||||
#region Colors
|
||||
private static Color? m_splineColor = null;
|
||||
public static Color NormalSplineColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_splineColor == null )
|
||||
m_splineColor = GetColor( "BezierSolution_SplineColor", new Color( 0.8f, 0.6f, 0.8f, 1f ) );
|
||||
|
||||
return m_splineColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_splineColor = value;
|
||||
SetColor( "BezierSolution_SplineColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_selectedSplineColor = null;
|
||||
public static Color SelectedSplineColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_selectedSplineColor == null )
|
||||
m_selectedSplineColor = GetColor( "BezierSolution_SelectedSplineColor", new Color( 0.8f, 0.6f, 0.8f, 1f ) );
|
||||
|
||||
return m_selectedSplineColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_selectedSplineColor = value;
|
||||
SetColor( "BezierSolution_SelectedSplineColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_endPointColor = null;
|
||||
public static Color NormalEndPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_endPointColor == null )
|
||||
m_endPointColor = GetColor( "BezierSolution_EndPointColor", Color.white );
|
||||
|
||||
return m_endPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_endPointColor = value;
|
||||
SetColor( "BezierSolution_EndPointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_selectedEndPointColor = null;
|
||||
public static Color SelectedEndPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_selectedEndPointColor == null )
|
||||
m_selectedEndPointColor = GetColor( "BezierSolution_SelectedEndPointColor", Color.yellow );
|
||||
|
||||
return m_selectedEndPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_selectedEndPointColor = value;
|
||||
SetColor( "BezierSolution_SelectedEndPointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_controlPointColor = null;
|
||||
public static Color NormalControlPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_controlPointColor == null )
|
||||
m_controlPointColor = GetColor( "BezierSolution_ControlPointColor", Color.white );
|
||||
|
||||
return m_controlPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_controlPointColor = value;
|
||||
SetColor( "BezierSolution_ControlPointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_selectedControlPointColor = null;
|
||||
public static Color SelectedControlPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_selectedControlPointColor == null )
|
||||
m_selectedControlPointColor = GetColor( "BezierSolution_SelectedControlPointColor", Color.green );
|
||||
|
||||
return m_selectedControlPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_selectedControlPointColor = value;
|
||||
SetColor( "BezierSolution_SelectedControlPointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_quickEditModeNewEndPointColor = null;
|
||||
public static Color QuickEditModeNewEndPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_quickEditModeNewEndPointColor == null )
|
||||
m_quickEditModeNewEndPointColor = GetColor( "BezierSolution_QuickEditNewPointColor", Color.cyan );
|
||||
|
||||
return m_quickEditModeNewEndPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_quickEditModeNewEndPointColor = value;
|
||||
SetColor( "BezierSolution_QuickEditNewPointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_quickEditModeDeleteEndPointColor = null;
|
||||
public static Color QuickEditModeDeleteEndPointColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_quickEditModeDeleteEndPointColor == null )
|
||||
m_quickEditModeDeleteEndPointColor = GetColor( "BezierSolution_QuickEditDeletePointColor", Color.red );
|
||||
|
||||
return m_quickEditModeDeleteEndPointColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_quickEditModeDeleteEndPointColor = value;
|
||||
SetColor( "BezierSolution_QuickEditDeletePointColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_normalsPreviewColor = null;
|
||||
public static Color NormalsPreviewColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_normalsPreviewColor == null )
|
||||
m_normalsPreviewColor = GetColor( "BezierSolution_NormalsPreviewColor", Color.blue );
|
||||
|
||||
return m_normalsPreviewColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_normalsPreviewColor = value;
|
||||
SetColor( "BezierSolution_NormalsPreviewColor", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static Color? m_evenlySpacedPointsColor = null;
|
||||
public static Color EvenlySpacedPointsColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_evenlySpacedPointsColor == null )
|
||||
m_evenlySpacedPointsColor = GetColor( "BezierSolution_EvenlySpacedPointsColor", Color.white );
|
||||
|
||||
return m_evenlySpacedPointsColor.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_evenlySpacedPointsColor = value;
|
||||
SetColor( "BezierSolution_EvenlySpacedPointsColor", value );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Size Adjustments
|
||||
private static float? m_splineThickness = null;
|
||||
public static float SplineThickness
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_splineThickness == null )
|
||||
m_splineThickness = EditorPrefs.GetFloat( "BezierSolution_SplineThickness", 8f );
|
||||
|
||||
return m_splineThickness.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_splineThickness = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_SplineThickness", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_endPointSize = null;
|
||||
public static float EndPointSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_endPointSize == null )
|
||||
m_endPointSize = EditorPrefs.GetFloat( "BezierSolution_EndPointSize", 0.075f );
|
||||
|
||||
return m_endPointSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_endPointSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_EndPointSize", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_selectedEndPointSize = null;
|
||||
public static float SelectedEndPointSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_selectedEndPointSize == null )
|
||||
m_selectedEndPointSize = EditorPrefs.GetFloat( "BezierSolution_SelectedEndPointSize", 0.075f * 1.5f );
|
||||
|
||||
return m_selectedEndPointSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_selectedEndPointSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_SelectedEndPointSize", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_controlPointSize = null;
|
||||
public static float ControlPointSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_controlPointSize == null )
|
||||
m_controlPointSize = EditorPrefs.GetFloat( "BezierSolution_ControlPointSize", 0.05f );
|
||||
|
||||
return m_controlPointSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_controlPointSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_ControlPointSize", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_quickEditModeNewEndPointSize = null;
|
||||
public static float QuickEditModeNewEndPointSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_quickEditModeNewEndPointSize == null )
|
||||
m_quickEditModeNewEndPointSize = EditorPrefs.GetFloat( "BezierSolution_QuickEditNewEndPointSize", 0.075f );
|
||||
|
||||
return m_quickEditModeNewEndPointSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_quickEditModeNewEndPointSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_QuickEditNewEndPointSize", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_normalsPreviewLength = null;
|
||||
public static float NormalsPreviewLength
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_normalsPreviewLength == null )
|
||||
m_normalsPreviewLength = EditorPrefs.GetFloat( "BezierSolution_NormalsPreviewLength", 0.35f );
|
||||
|
||||
return m_normalsPreviewLength.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
value = Mathf.Max( value, 0f );
|
||||
m_normalsPreviewLength = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_NormalsPreviewLength", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_evenlySpacedPointsSize = null;
|
||||
public static float EvenlySpacedPointsSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_evenlySpacedPointsSize == null )
|
||||
m_evenlySpacedPointsSize = EditorPrefs.GetFloat( "BezierSolution_EvenlySpacedPointsSize", 0.1f );
|
||||
|
||||
return m_evenlySpacedPointsSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_evenlySpacedPointsSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_EvenlySpacedPointsSize", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static float? m_extraDataAsFrustumSize = null;
|
||||
public static float ExtraDataAsFrustumSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_extraDataAsFrustumSize == null )
|
||||
m_extraDataAsFrustumSize = EditorPrefs.GetFloat( "BezierSolution_ExtraDataFrustumSize", 2.2f );
|
||||
|
||||
return m_extraDataAsFrustumSize.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_extraDataAsFrustumSize = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_ExtraDataFrustumSize", value );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other Settings
|
||||
private static float? m_splineSmoothness = null;
|
||||
public static float SplineSmoothness
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_splineSmoothness == null )
|
||||
m_splineSmoothness = EditorPrefs.GetFloat( "BezierSolution_SplineSmoothness", 10f );
|
||||
|
||||
return m_splineSmoothness.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
value = Mathf.Max( value, 1f );
|
||||
m_splineSmoothness = value;
|
||||
EditorPrefs.SetFloat( "BezierSolution_SplineSmoothness", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static int? m_displayedIntermediateNormalsCount = null;
|
||||
public static int DisplayedIntermediateNormalsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_displayedIntermediateNormalsCount == null )
|
||||
m_displayedIntermediateNormalsCount = EditorPrefs.GetInt( "BezierSolution_IntermediateNormals", 8 );
|
||||
|
||||
return m_displayedIntermediateNormalsCount.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp( value, 0, 999 );
|
||||
m_displayedIntermediateNormalsCount = value;
|
||||
EditorPrefs.SetInt( "BezierSolution_IntermediateNormals", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_moveMultiplePointsInOppositeDirections = null;
|
||||
public static bool MoveMultiplePointsInOppositeDirections
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_moveMultiplePointsInOppositeDirections == null )
|
||||
m_moveMultiplePointsInOppositeDirections = EditorPrefs.GetBool( "BezierSolution_OppositeTransformation", false );
|
||||
|
||||
return m_moveMultiplePointsInOppositeDirections.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_moveMultiplePointsInOppositeDirections = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_OppositeTransformation", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_quickEditSplineModifyNormals = null;
|
||||
public static bool QuickEditSplineModifyNormals
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_quickEditSplineModifyNormals == null )
|
||||
m_quickEditSplineModifyNormals = EditorPrefs.GetBool( "BezierSolution_QuickEditModifyNormals", true );
|
||||
|
||||
return m_quickEditSplineModifyNormals.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_quickEditSplineModifyNormals = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_QuickEditModifyNormals", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_quickEditSplinePreserveShape = null;
|
||||
public static bool QuickEditSplinePreserveShape
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_quickEditSplinePreserveShape == null )
|
||||
m_quickEditSplinePreserveShape = EditorPrefs.GetBool( "BezierSolution_QuickEditPreserveShape", false );
|
||||
|
||||
return m_quickEditSplinePreserveShape.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_quickEditSplinePreserveShape = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_QuickEditPreserveShape", value );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Visibility Settings
|
||||
private static bool? m_showControlPoints = null;
|
||||
public static bool ShowControlPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_showControlPoints == null )
|
||||
m_showControlPoints = EditorPrefs.GetBool( "BezierSolution_ShowControlPoints", true );
|
||||
|
||||
return m_showControlPoints.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_showControlPoints = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_ShowControlPoints", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_showControlPointDirections = null;
|
||||
public static bool ShowControlPointDirections
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_showControlPointDirections == null )
|
||||
m_showControlPointDirections = EditorPrefs.GetBool( "BezierSolution_ShowControlPointDirs", true );
|
||||
|
||||
return m_showControlPointDirections.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_showControlPointDirections = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_ShowControlPointDirs", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_showEndPointLabels = null;
|
||||
public static bool ShowEndPointLabels
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_showEndPointLabels == null )
|
||||
m_showEndPointLabels = EditorPrefs.GetBool( "BezierSolution_ShowEndPointLabels", true );
|
||||
|
||||
return m_showEndPointLabels.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_showEndPointLabels = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_ShowEndPointLabels", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_showNormals = null;
|
||||
public static bool ShowNormals
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_showNormals == null )
|
||||
m_showNormals = EditorPrefs.GetBool( "BezierSolution_ShowNormals", true );
|
||||
|
||||
return m_showNormals.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_showNormals = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_ShowNormals", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_showEvenlySpacedPoints = null;
|
||||
public static bool ShowEvenlySpacedPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_showEvenlySpacedPoints == null )
|
||||
m_showEvenlySpacedPoints = EditorPrefs.GetBool( "BezierSolution_ShowEvenlySpacedPoints", false );
|
||||
|
||||
return m_showEvenlySpacedPoints.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_showEvenlySpacedPoints = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_ShowEvenlySpacedPoints", value );
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? m_visualizeExtraDataAsFrustum = null;
|
||||
public static bool VisualizeExtraDataAsFrustum
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_visualizeExtraDataAsFrustum == null )
|
||||
m_visualizeExtraDataAsFrustum = EditorPrefs.GetBool( "BezierSolution_VisualizeFrustum", false );
|
||||
|
||||
return m_visualizeExtraDataAsFrustum.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_visualizeExtraDataAsFrustum = value;
|
||||
EditorPrefs.SetBool( "BezierSolution_VisualizeFrustum", value );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreatePreferencesGUI()
|
||||
{
|
||||
return new SettingsProvider( "Project/yasirkula/Bezier Solution", SettingsScope.Project )
|
||||
{
|
||||
guiHandler = ( searchContext ) => PreferencesGUI(),
|
||||
keywords = new System.Collections.Generic.HashSet<string>() { "Bezier", "Spline", "Point", "Normals", "Color", "Size" }
|
||||
};
|
||||
}
|
||||
|
||||
[MenuItem( "CONTEXT/BezierSpline/Open Settings" )]
|
||||
[MenuItem( "CONTEXT/BezierPoint/Open Settings" )]
|
||||
private static void OpenPreferencesWindow( MenuCommand command )
|
||||
{
|
||||
SettingsService.OpenProjectSettings( "yasirkula/Bezier Solution" );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
[PreferenceItem( "Bezier Solution" )]
|
||||
#endif
|
||||
public static void PreferencesGUI()
|
||||
{
|
||||
Color c;
|
||||
float f;
|
||||
int i;
|
||||
bool b;
|
||||
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth += 50f;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Selected Spline Color", SelectedSplineColor, new Color( 0.8f, 0.6f, 0.8f, 1f ) );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SelectedSplineColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Unselected Spline Color", NormalSplineColor, new Color( 0.8f, 0.6f, 0.8f, 1f ) );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
NormalSplineColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Selected Spline Thickness", SplineThickness, 8f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SplineThickness = f;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Unselected Spline Smoothness", SplineSmoothness, 10f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SplineSmoothness = f;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Selected End Points Color", SelectedEndPointColor, Color.yellow );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SelectedEndPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Unselected End Point Color", NormalEndPointColor, Color.white );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
NormalEndPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Selected End Points Size", SelectedEndPointSize, 0.075f * 1.5f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SelectedEndPointSize = f;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Unselected End Points Size", EndPointSize, 0.075f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
EndPointSize = f;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( "Show End Point Labels", ShowEndPointLabels );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ShowEndPointLabels = b;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( "Show Control Points", ShowControlPoints );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ShowControlPoints = b;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( "Show Control Point Directions", ShowControlPointDirections );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ShowControlPointDirections = b;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Selected Control Point Color", SelectedControlPointColor, Color.green );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SelectedControlPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Unselected Control Point Color", NormalControlPointColor, Color.white );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
NormalControlPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Control Points Size", ControlPointSize, 0.05f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ControlPointSize = f;
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( "Show Normals", ShowNormals );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ShowNormals = b;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
i = IntField( "Displayed Intermediate Normals", DisplayedIntermediateNormalsCount, 8 );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
DisplayedIntermediateNormalsCount = i;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Normals Preview Color", NormalsPreviewColor, Color.blue );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
NormalsPreviewColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Normals Preview Length", NormalsPreviewLength, 0.35f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
NormalsPreviewLength = f;
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( "Visualize Evenly Spaced Points", ShowEvenlySpacedPoints );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ShowEvenlySpacedPoints = b;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Evenly Spaced Points Color", EvenlySpacedPointsColor, Color.white );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
EvenlySpacedPointsColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Evenly Spaced Points Size", EvenlySpacedPointsSize, 0.1f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
EvenlySpacedPointsSize = f;
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Quick Edit New Point Color", QuickEditModeNewEndPointColor, Color.cyan );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
QuickEditModeNewEndPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
c = ColorField( "Quick Edit Delete Point Color", QuickEditModeDeleteEndPointColor, Color.red );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
QuickEditModeDeleteEndPointColor = c;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Quick Edit New Point Size", QuickEditModeNewEndPointSize, 0.075f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
QuickEditModeNewEndPointSize = f;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
b = EditorGUILayout.Toggle( new GUIContent( "Visualize Extra Data As Frustum", "Visualize end points' Extra Data as camera frustum in Scene window" ), VisualizeExtraDataAsFrustum );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
VisualizeExtraDataAsFrustum = b;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
f = FloatField( "Frustum Size", ExtraDataAsFrustumSize, 2.2f );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
ExtraDataAsFrustumSize = f;
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
private static Color ColorField( string label, Color value, Color defaultValue )
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
Color result = EditorGUILayout.ColorField( label, value );
|
||||
if( GUILayout.Button( "Reset", BezierUtils.GL_WIDTH_60 ) )
|
||||
result = defaultValue;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static float FloatField( string label, float value, float defaultValue )
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
float result = EditorGUILayout.FloatField( label, value );
|
||||
if( GUILayout.Button( "Reset", BezierUtils.GL_WIDTH_60 ) )
|
||||
result = defaultValue;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int IntField( string label, int value, int defaultValue )
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
int result = EditorGUILayout.IntField( label, value );
|
||||
if( GUILayout.Button( "Reset", BezierUtils.GL_WIDTH_60 ) )
|
||||
result = defaultValue;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Color GetColor( string pref, Color defaultColor )
|
||||
{
|
||||
if( !EditorPrefs.HasKey( pref ) )
|
||||
return defaultColor;
|
||||
|
||||
string[] parts = EditorPrefs.GetString( pref ).Split( ';' );
|
||||
return new Color32( byte.Parse( parts[0] ), byte.Parse( parts[1] ), byte.Parse( parts[2] ), byte.Parse( parts[3] ) );
|
||||
}
|
||||
|
||||
private static void SetColor( string pref, Color32 value )
|
||||
{
|
||||
EditorPrefs.SetString( pref, string.Concat( value.r.ToString(), ";", value.g.ToString(), ";", value.b.ToString(), ";", value.a.ToString() ) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e751cb465841a4f43b9297b7be55dcd0
|
||||
timeCreated: 1620207781
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "BezierSolution.Editor",
|
||||
"references": [
|
||||
"BezierSolution.Runtime"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b99279c3e8f544f4d83dd26b3a9b5715
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,103 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomEditor( typeof( BezierSpline ) )]
|
||||
[CanEditMultipleObjects]
|
||||
public class BezierSplineEditor : Editor
|
||||
{
|
||||
internal BezierSpline[] allSplines;
|
||||
|
||||
public static BezierSplineEditor ActiveEditor { get; private set; }
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Object[] splines = targets;
|
||||
allSplines = new BezierSpline[splines.Length];
|
||||
for( int i = 0; i < splines.Length; i++ )
|
||||
{
|
||||
BezierSpline spline = (BezierSpline) splines[i];
|
||||
if( spline )
|
||||
spline.Refresh();
|
||||
|
||||
allSplines[i] = spline;
|
||||
}
|
||||
|
||||
ActiveEditor = this;
|
||||
|
||||
if( BezierUtils.QuickEditSplineMode )
|
||||
{
|
||||
Tools.hidden = true;
|
||||
|
||||
EditorApplication.update -= SceneView.RepaintAll;
|
||||
EditorApplication.update += SceneView.RepaintAll;
|
||||
}
|
||||
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
Undo.undoRedoPerformed += OnUndoRedo;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
ActiveEditor = null;
|
||||
Tools.hidden = false;
|
||||
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
EditorApplication.update -= SceneView.RepaintAll;
|
||||
}
|
||||
|
||||
private void OnSceneGUI()
|
||||
{
|
||||
BezierSpline spline = (BezierSpline) target;
|
||||
BezierUtils.DrawSplineDetailed( spline );
|
||||
|
||||
for( int i = 0; i < spline.Count; i++ )
|
||||
BezierUtils.DrawBezierPoint( spline[i], i + 1, false );
|
||||
|
||||
if( BezierSettings.ShowEvenlySpacedPoints )
|
||||
BezierUtils.DrawSplineEvenlySpacedPoints( spline );
|
||||
|
||||
if( BezierUtils.QuickEditSplineMode )
|
||||
{
|
||||
// Execute quick edit mode's scene GUI only once (otherwise things can get ugly when multiple splines are selected)
|
||||
if( spline == allSplines[0] )
|
||||
{
|
||||
BezierUtils.QuickEditModeSceneGUI( allSplines );
|
||||
HandleUtility.AddDefaultControl( 0 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
BezierUtils.DrawSplineInspectorGUI( allSplines );
|
||||
}
|
||||
|
||||
private void OnUndoRedo()
|
||||
{
|
||||
for( int i = 0; i < allSplines.Length; i++ )
|
||||
{
|
||||
if( allSplines[i] )
|
||||
{
|
||||
allSplines[i].dirtyFlags |= InternalDirtyFlags.All;
|
||||
allSplines[i].Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private bool HasFrameBounds()
|
||||
{
|
||||
return !serializedObject.isEditingMultipleObjects;
|
||||
}
|
||||
|
||||
private Bounds OnGetFrameBounds()
|
||||
{
|
||||
return new Bounds( ( (BezierSpline) target ).transform.position, new Vector3( 1f, 1f, 1f ) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0b74ad81d1f30ec479543aea0a27f6ef
|
||||
timeCreated: 1472737433
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f472603c7062a4747bc569c7740ca872
|
||||
timeCreated: 1473158123
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,120 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
public abstract class BezierWalkerEditor : Editor
|
||||
{
|
||||
protected Object[] walkers;
|
||||
|
||||
private bool simulateInEditor;
|
||||
private double lastUpdateTime;
|
||||
|
||||
protected bool hasInitialData;
|
||||
protected List<Vector3> initialPositions = new List<Vector3>( 0 );
|
||||
protected List<Quaternion> initialRotations = new List<Quaternion>( 0 );
|
||||
protected List<float> initialNormalizedTs = new List<float>( 0 );
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
walkers = targets;
|
||||
|
||||
if( simulateInEditor )
|
||||
StartSimulateInEditor();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
StopSimulateInEditor();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
BezierUtils.DrawSeparator();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
simulateInEditor = GUILayout.Toggle( simulateInEditor, "Simulate In Editor", GUI.skin.button );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
if( simulateInEditor )
|
||||
StartSimulateInEditor();
|
||||
else
|
||||
StopSimulateInEditor();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartSimulateInEditor()
|
||||
{
|
||||
SaveInitialData();
|
||||
|
||||
lastUpdateTime = EditorApplication.timeSinceStartup;
|
||||
EditorApplication.update -= SimulateInEditor;
|
||||
EditorApplication.update += SimulateInEditor;
|
||||
}
|
||||
|
||||
private void StopSimulateInEditor()
|
||||
{
|
||||
EditorApplication.update -= SimulateInEditor;
|
||||
|
||||
if( hasInitialData )
|
||||
{
|
||||
hasInitialData = false;
|
||||
RestoreInitialData();
|
||||
}
|
||||
|
||||
simulateInEditor = false;
|
||||
}
|
||||
|
||||
protected virtual void SaveInitialData()
|
||||
{
|
||||
initialPositions.Clear();
|
||||
initialRotations.Clear();
|
||||
initialNormalizedTs.Clear();
|
||||
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
{
|
||||
initialPositions.Add( ( (Component) walkers[i] ).transform.position );
|
||||
initialRotations.Add( ( (Component) walkers[i] ).transform.rotation );
|
||||
initialNormalizedTs.Add( ( (BezierWalker) walkers[i] ).NormalizedT );
|
||||
}
|
||||
|
||||
hasInitialData = true;
|
||||
}
|
||||
|
||||
protected virtual void RestoreInitialData()
|
||||
{
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
{
|
||||
if( walkers[i] )
|
||||
{
|
||||
( (Component) walkers[i] ).transform.position = initialPositions[i];
|
||||
( (Component) walkers[i] ).transform.rotation = initialRotations[i];
|
||||
( (BezierWalker) walkers[i] ).NormalizedT = initialNormalizedTs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SimulateInEditor()
|
||||
{
|
||||
if( EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying )
|
||||
{
|
||||
// Stop the simulation if we are about to enter Play mode
|
||||
StopSimulateInEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
double time = EditorApplication.timeSinceStartup;
|
||||
Simulate( (float) ( time - lastUpdateTime ) );
|
||||
lastUpdateTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Simulate( float deltaTime )
|
||||
{
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
( (BezierWalker) walkers[i] ).Execute( deltaTime );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0c496a7cc8ad6654f891021f652a8e5f
|
||||
timeCreated: 1520346477
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,56 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomEditor( typeof( BezierWalkerLocomotion ) )]
|
||||
[CanEditMultipleObjects]
|
||||
public class BezierWalkerLocomotionEditor : BezierWalkerEditor
|
||||
{
|
||||
private int tailSaveDataStartIndex;
|
||||
|
||||
protected override void SaveInitialData()
|
||||
{
|
||||
base.SaveInitialData();
|
||||
tailSaveDataStartIndex = initialPositions.Count;
|
||||
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
{
|
||||
List<Transform> tail = ( (BezierWalkerLocomotion) walkers[i] ).Tail;
|
||||
for( int j = 0; j < tail.Count; j++ )
|
||||
{
|
||||
initialPositions.Add( tail[j].position );
|
||||
initialRotations.Add( tail[j].rotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RestoreInitialData()
|
||||
{
|
||||
base.RestoreInitialData();
|
||||
|
||||
int index = tailSaveDataStartIndex;
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
{
|
||||
if( walkers[i] )
|
||||
{
|
||||
List<Transform> tail = ( (BezierWalkerLocomotion) walkers[i] ).Tail;
|
||||
for( int j = 0; j < tail.Count; j++, index++ )
|
||||
{
|
||||
tail[j].position = initialPositions[index];
|
||||
tail[j].rotation = initialRotations[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Simulate( float deltaTime )
|
||||
{
|
||||
for( int i = 0; i < walkers.Length; i++ )
|
||||
( (BezierWalkerLocomotion) walkers[i] ).walker.Execute( deltaTime );
|
||||
|
||||
base.Simulate( deltaTime );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: afc4ab3119c2b58498c79718b6945348
|
||||
timeCreated: 1520346477
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEditor;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomEditor( typeof( BezierWalkerWithSpeed ) )]
|
||||
[CanEditMultipleObjects]
|
||||
public class BezierWalkerWithSpeedEditor : BezierWalkerEditor
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: aba64e4e7209c9b44ae73ece7f2c7164
|
||||
timeCreated: 1520346477
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEditor;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
[CustomEditor( typeof( BezierWalkerWithTime ) )]
|
||||
[CanEditMultipleObjects]
|
||||
public class BezierWalkerWithTimeEditor : BezierWalkerEditor
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e24aeb71e708e4043b77585635edfe8d
|
||||
timeCreated: 1520346477
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,46 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution.Extras
|
||||
{
|
||||
// This class is used for resetting the particle system attached to a ParticlesFollowBezier
|
||||
// component when it is selected. Otherwise, particles move in a chaotic way for a while
|
||||
[CustomEditor( typeof( ParticlesFollowBezier ) )]
|
||||
[CanEditMultipleObjects]
|
||||
public class ParticlesFollowBezierEditor : Editor
|
||||
{
|
||||
private int particlesReset;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
particlesReset = 3;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if( Application.isPlaying )
|
||||
return;
|
||||
|
||||
if( particlesReset > 0 && --particlesReset == 0 )
|
||||
{
|
||||
foreach( Object target in targets )
|
||||
{
|
||||
ResetParticles( ( (ParticlesFollowBezier) target ).GetComponentsInParent<ParticlesFollowBezier>() );
|
||||
ResetParticles( ( (ParticlesFollowBezier) target ).GetComponentsInChildren<ParticlesFollowBezier>() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetParticles( ParticlesFollowBezier[] targets )
|
||||
{
|
||||
foreach( ParticlesFollowBezier target in targets )
|
||||
{
|
||||
ParticleSystem particleSystem = target.GetComponent<ParticleSystem>();
|
||||
if( target.spline != null && particleSystem != null && target.enabled )
|
||||
particleSystem.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 652ad8d00b278c04fbf4252c46b7a10f
|
||||
timeCreated: 1520346477
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 34eb947ee3a327b45911b699fb81c1f5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,344 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
public enum SplineAutoConstructMode { None = 0, Linear = 1, Smooth1 = 2, Smooth2 = 3 };
|
||||
|
||||
[System.Flags]
|
||||
internal enum InternalDirtyFlags
|
||||
{
|
||||
None = 0,
|
||||
EndPointTransformChange = 1 << 1,
|
||||
ControlPointPositionChange = 1 << 2,
|
||||
NormalChange = 1 << 3,
|
||||
NormalOffsetChange = 1 << 4,
|
||||
ExtraDataChange = 1 << 5,
|
||||
All = EndPointTransformChange | ControlPointPositionChange | NormalChange | NormalOffsetChange | ExtraDataChange
|
||||
};
|
||||
|
||||
[System.Flags]
|
||||
public enum DirtyFlags
|
||||
{
|
||||
None = 0,
|
||||
SplineShapeChanged = 1 << 1,
|
||||
NormalsChanged = 1 << 2,
|
||||
ExtraDataChanged = 1 << 3,
|
||||
All = SplineShapeChanged | NormalsChanged | ExtraDataChanged
|
||||
};
|
||||
|
||||
[System.Flags]
|
||||
public enum PointCacheFlags
|
||||
{
|
||||
None = 0,
|
||||
Positions = 1 << 1,
|
||||
Normals = 1 << 2,
|
||||
Tangents = 1 << 3,
|
||||
Bitangents = 1 << 4,
|
||||
ExtraDatas = 1 << 5,
|
||||
All = Positions | Normals | Tangents | Bitangents | ExtraDatas
|
||||
};
|
||||
|
||||
public delegate void SplineChangeDelegate( BezierSpline spline, DirtyFlags dirtyFlags );
|
||||
public delegate BezierPoint.ExtraData ExtraDataLerpFunction( BezierPoint.ExtraData data1, BezierPoint.ExtraData data2, float normalizedT );
|
||||
|
||||
public partial class BezierSpline
|
||||
{
|
||||
private static readonly ExtraDataLerpFunction defaultExtraDataLerpFunction = BezierPoint.ExtraData.LerpUnclamped;
|
||||
|
||||
public struct Segment
|
||||
{
|
||||
public readonly BezierPoint point1, point2;
|
||||
public readonly float localT;
|
||||
|
||||
public Segment( BezierPoint point1, BezierPoint point2, float localT )
|
||||
{
|
||||
this.point1 = point1;
|
||||
this.point2 = point2;
|
||||
this.localT = localT;
|
||||
}
|
||||
|
||||
public float GetNormalizedT() { return GetNormalizedT( localT ); }
|
||||
public float GetNormalizedT( float localT )
|
||||
{
|
||||
BezierSpline spline = point1.spline;
|
||||
return ( point1.index + localT ) / ( spline.m_loop ? spline.Count : ( spline.Count - 1 ) );
|
||||
}
|
||||
|
||||
public Vector3 GetPoint() { return GetPoint( localT ); }
|
||||
public Vector3 GetPoint( float localT )
|
||||
{
|
||||
float oneMinusLocalT = 1f - localT;
|
||||
|
||||
return oneMinusLocalT * oneMinusLocalT * oneMinusLocalT * point1.position +
|
||||
3f * oneMinusLocalT * oneMinusLocalT * localT * point1.followingControlPointPosition +
|
||||
3f * oneMinusLocalT * localT * localT * point2.precedingControlPointPosition +
|
||||
localT * localT * localT * point2.position;
|
||||
}
|
||||
|
||||
public Vector3 GetTangent() { return GetTangent( localT ); }
|
||||
public Vector3 GetTangent( float localT )
|
||||
{
|
||||
float oneMinusLocalT = 1f - localT;
|
||||
|
||||
return 3f * oneMinusLocalT * oneMinusLocalT * ( point1.followingControlPointPosition - point1.position ) +
|
||||
6f * oneMinusLocalT * localT * ( point2.precedingControlPointPosition - point1.followingControlPointPosition ) +
|
||||
3f * localT * localT * ( point2.position - point2.precedingControlPointPosition );
|
||||
}
|
||||
|
||||
public Vector3 GetNormal() { return GetNormal( localT ); }
|
||||
public Vector3 GetNormal( float localT )
|
||||
{
|
||||
Vector3[] intermediateNormals = point1.intermediateNormals;
|
||||
if( intermediateNormals != null && intermediateNormals.Length > 0 )
|
||||
{
|
||||
localT = Mathf.Clamp01( localT ) * ( intermediateNormals.Length - 1 );
|
||||
int localStartIndex = (int) localT;
|
||||
|
||||
return ( localStartIndex < intermediateNormals.Length - 1 ) ? Vector3.LerpUnclamped( intermediateNormals[localStartIndex], intermediateNormals[localStartIndex + 1], localT - localStartIndex ) : intermediateNormals[localStartIndex];
|
||||
}
|
||||
|
||||
Vector3 startNormal = point1.normal;
|
||||
Vector3 endNormal = point2.normal;
|
||||
|
||||
Vector3 normal = Vector3.LerpUnclamped( startNormal, endNormal, localT );
|
||||
if( normal.y == 0f && normal.x == 0f && normal.z == 0f )
|
||||
{
|
||||
// Don't return Vector3.zero as normal
|
||||
normal = Vector3.LerpUnclamped( startNormal, endNormal, localT > 0.01f ? ( localT - 0.01f ) : ( localT + 0.01f ) );
|
||||
if( normal.y == 0f && normal.x == 0f && normal.z == 0f )
|
||||
normal = Vector3.up;
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
public BezierPoint.ExtraData GetExtraData() { return defaultExtraDataLerpFunction( point1.extraData, point2.extraData, localT ); }
|
||||
public BezierPoint.ExtraData GetExtraData( float localT ) { return defaultExtraDataLerpFunction( point1.extraData, point2.extraData, localT ); }
|
||||
public BezierPoint.ExtraData GetExtraData( ExtraDataLerpFunction lerpFunction ) { return lerpFunction( point1.extraData, point2.extraData, localT ); }
|
||||
public BezierPoint.ExtraData GetExtraData( float localT, ExtraDataLerpFunction lerpFunction ) { return lerpFunction( point1.extraData, point2.extraData, localT ); }
|
||||
}
|
||||
|
||||
public class EvenlySpacedPointsHolder
|
||||
{
|
||||
public readonly BezierSpline spline;
|
||||
public readonly float splineLength;
|
||||
public readonly float[] uniformNormalizedTs;
|
||||
|
||||
public EvenlySpacedPointsHolder( BezierSpline spline, float splineLength, float[] uniformNormalizedTs )
|
||||
{
|
||||
this.spline = spline;
|
||||
this.splineLength = splineLength;
|
||||
this.uniformNormalizedTs = uniformNormalizedTs;
|
||||
}
|
||||
|
||||
public float GetNormalizedTAtDistance( float distance )
|
||||
{
|
||||
return GetNormalizedTAtPercentage( distance / splineLength );
|
||||
}
|
||||
|
||||
public float GetNormalizedTAtPercentage( float percentage )
|
||||
{
|
||||
if( !spline.loop )
|
||||
{
|
||||
if( percentage <= 0f )
|
||||
return 0f;
|
||||
else if( percentage >= 1f )
|
||||
return 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( percentage < 0f )
|
||||
percentage += 1f;
|
||||
while( percentage >= 1f )
|
||||
percentage -= 1f;
|
||||
}
|
||||
|
||||
float indexRaw = ( uniformNormalizedTs.Length - 1 ) * percentage;
|
||||
int index = (int) indexRaw;
|
||||
return Mathf.LerpUnclamped( uniformNormalizedTs[index], uniformNormalizedTs[index + 1], indexRaw - index );
|
||||
}
|
||||
|
||||
public float GetPercentageAtNormalizedT( float normalizedT )
|
||||
{
|
||||
if( !spline.loop )
|
||||
{
|
||||
if( normalizedT <= 0f )
|
||||
return 0f;
|
||||
else if( normalizedT >= 1f )
|
||||
return 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( normalizedT < 0f )
|
||||
normalizedT += 1f;
|
||||
if( normalizedT >= 1f )
|
||||
normalizedT -= 1f;
|
||||
}
|
||||
|
||||
// Perform binary search
|
||||
int lowerBound = 0;
|
||||
int upperBound = uniformNormalizedTs.Length - 1;
|
||||
while( lowerBound <= upperBound )
|
||||
{
|
||||
int index = lowerBound + ( ( upperBound - lowerBound ) >> 1 );
|
||||
float arrElement = uniformNormalizedTs[index];
|
||||
if( arrElement < normalizedT )
|
||||
lowerBound = index + 1;
|
||||
else if( arrElement > normalizedT )
|
||||
upperBound = index - 1;
|
||||
else
|
||||
return index / (float) ( uniformNormalizedTs.Length - 1 );
|
||||
}
|
||||
|
||||
float inverseLerp = ( normalizedT - uniformNormalizedTs[lowerBound] ) / ( uniformNormalizedTs[lowerBound - 1] - uniformNormalizedTs[lowerBound] );
|
||||
return ( lowerBound - inverseLerp ) / ( uniformNormalizedTs.Length - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
public class PointCache
|
||||
{
|
||||
public readonly Vector3[] positions, normals, tangents, bitangents;
|
||||
public readonly BezierPoint.ExtraData[] extraDatas;
|
||||
public readonly bool loop;
|
||||
|
||||
public PointCache( Vector3[] positions, Vector3[] normals, Vector3[] tangents, Vector3[] bitangents, BezierPoint.ExtraData[] extraDatas, bool loop )
|
||||
{
|
||||
this.positions = positions;
|
||||
this.normals = normals;
|
||||
this.tangents = tangents;
|
||||
this.bitangents = bitangents;
|
||||
this.extraDatas = extraDatas;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
public Vector3 GetPoint( float percentage ) { return LerpArray( positions, percentage ); }
|
||||
public Vector3 GetNormal( float percentage ) { return LerpArray( normals, percentage ); }
|
||||
public Vector3 GetTangent( float percentage ) { return LerpArray( tangents, percentage ); }
|
||||
public Vector3 GetBitangent( float percentage ) { return LerpArray( bitangents, percentage ); }
|
||||
|
||||
public BezierPoint.ExtraData GetExtraData( float percentage ) { return GetExtraData( percentage, defaultExtraDataLerpFunction ); }
|
||||
public BezierPoint.ExtraData GetExtraData( float percentage, ExtraDataLerpFunction lerpFunction )
|
||||
{
|
||||
if( !loop )
|
||||
{
|
||||
if( percentage <= 0f )
|
||||
return extraDatas[0];
|
||||
else if( percentage >= 1f )
|
||||
return extraDatas[extraDatas.Length - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( percentage < 0f )
|
||||
percentage += 1f;
|
||||
if( percentage >= 1f )
|
||||
percentage -= 1f;
|
||||
}
|
||||
|
||||
float t = percentage * ( loop ? extraDatas.Length : ( extraDatas.Length - 1 ) );
|
||||
|
||||
int startIndex = (int) t;
|
||||
int endIndex = startIndex + 1;
|
||||
|
||||
if( endIndex == extraDatas.Length )
|
||||
endIndex = 0;
|
||||
|
||||
return lerpFunction( extraDatas[startIndex], extraDatas[endIndex], t - startIndex );
|
||||
}
|
||||
|
||||
private Vector3 LerpArray( Vector3[] array, float percentage )
|
||||
{
|
||||
if( !loop )
|
||||
{
|
||||
if( percentage <= 0f )
|
||||
return array[0];
|
||||
else if( percentage >= 1f )
|
||||
return array[array.Length - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( percentage < 0f )
|
||||
percentage += 1f;
|
||||
if( percentage >= 1f )
|
||||
percentage -= 1f;
|
||||
}
|
||||
|
||||
float t = percentage * ( loop ? array.Length : ( array.Length - 1 ) );
|
||||
|
||||
int startIndex = (int) t;
|
||||
int endIndex = startIndex + 1;
|
||||
|
||||
if( endIndex == array.Length )
|
||||
endIndex = 0;
|
||||
|
||||
return Vector3.LerpUnclamped( array[startIndex], array[endIndex], t - startIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class BezierPoint
|
||||
{
|
||||
public enum HandleMode { Free, Aligned, Mirrored };
|
||||
|
||||
[System.Serializable]
|
||||
public struct ExtraData
|
||||
{
|
||||
public float c1, c2, c3, c4;
|
||||
|
||||
public ExtraData( float c1 = 0f, float c2 = 0f, float c3 = 0f, float c4 = 0f )
|
||||
{
|
||||
this.c1 = c1;
|
||||
this.c2 = c2;
|
||||
this.c3 = c3;
|
||||
this.c4 = c4;
|
||||
}
|
||||
|
||||
public static ExtraData Lerp( ExtraData a, ExtraData b, float t )
|
||||
{
|
||||
t = Mathf.Clamp01( t );
|
||||
return new ExtraData(
|
||||
a.c1 + ( b.c1 - a.c1 ) * t,
|
||||
a.c2 + ( b.c2 - a.c2 ) * t,
|
||||
a.c3 + ( b.c3 - a.c3 ) * t,
|
||||
a.c4 + ( b.c4 - a.c4 ) * t );
|
||||
}
|
||||
|
||||
public static ExtraData LerpUnclamped( ExtraData a, ExtraData b, float t )
|
||||
{
|
||||
return new ExtraData(
|
||||
a.c1 + ( b.c1 - a.c1 ) * t,
|
||||
a.c2 + ( b.c2 - a.c2 ) * t,
|
||||
a.c3 + ( b.c3 - a.c3 ) * t,
|
||||
a.c4 + ( b.c4 - a.c4 ) * t );
|
||||
}
|
||||
|
||||
public static implicit operator ExtraData( Vector2 v ) { return new ExtraData( v.x, v.y ); }
|
||||
public static implicit operator ExtraData( Vector3 v ) { return new ExtraData( v.x, v.y, v.z ); }
|
||||
public static implicit operator ExtraData( Vector4 v ) { return new ExtraData( v.x, v.y, v.z, v.w ); }
|
||||
public static implicit operator ExtraData( Quaternion q ) { return new ExtraData( q.x, q.y, q.z, q.w ); }
|
||||
public static implicit operator ExtraData( Rect r ) { return new ExtraData( r.xMin, r.yMin, r.width, r.height ); }
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
public static implicit operator ExtraData( Vector2Int v ) { return new ExtraData( v.x, v.y ); }
|
||||
public static implicit operator ExtraData( Vector3Int v ) { return new ExtraData( v.x, v.y, v.z ); }
|
||||
public static implicit operator ExtraData( RectInt r ) { return new ExtraData( r.xMin, r.yMin, r.width, r.height ); }
|
||||
#endif
|
||||
|
||||
public static implicit operator Vector2( ExtraData v ) { return new Vector2( v.c1, v.c2 ); }
|
||||
public static implicit operator Vector3( ExtraData v ) { return new Vector3( v.c1, v.c2, v.c3 ); }
|
||||
public static implicit operator Vector4( ExtraData v ) { return new Vector4( v.c1, v.c2, v.c3, v.c4 ); }
|
||||
public static implicit operator Quaternion( ExtraData v ) { return new Quaternion( v.c1, v.c2, v.c3, v.c4 ); }
|
||||
public static implicit operator Rect( ExtraData v ) { return new Rect( v.c1, v.c2, v.c3, v.c4 ); }
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
public static implicit operator Vector2Int( ExtraData v ) { return new Vector2Int( Mathf.RoundToInt( v.c1 ), Mathf.RoundToInt( v.c2 ) ); }
|
||||
public static implicit operator Vector3Int( ExtraData v ) { return new Vector3Int( Mathf.RoundToInt( v.c1 ), Mathf.RoundToInt( v.c2 ), Mathf.RoundToInt( v.c3 ) ); }
|
||||
public static implicit operator RectInt( ExtraData v ) { return new RectInt( Mathf.RoundToInt( v.c1 ), Mathf.RoundToInt( v.c2 ), Mathf.RoundToInt( v.c3 ), Mathf.RoundToInt( v.c4 ) ); }
|
||||
#endif
|
||||
|
||||
public static bool operator ==( ExtraData d1, ExtraData d2 ) { return d1.c1 == d2.c1 && d1.c2 == d2.c2 && d1.c3 == d2.c3 && d1.c4 == d2.c4; }
|
||||
public static bool operator !=( ExtraData d1, ExtraData d2 ) { return d1.c1 != d2.c1 || d1.c2 != d2.c2 || d1.c3 != d2.c3 || d1.c4 != d2.c4; }
|
||||
|
||||
public override bool Equals( object obj ) { return obj is ExtraData && this == (ExtraData) obj; }
|
||||
public override int GetHashCode() { return unchecked((int) ( ( ( ( 17 * 23 + c1 ) * 23 + c2 ) * 23 + c3 ) * 23 + c4 )); }
|
||||
public override string ToString() { return ( (Vector4) this ).ToString(); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4cf39235e4779904896b58210ade2e37
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,36 @@
|
|||
= Bezier Solution =
|
||||
|
||||
Online documentation & example code available at: https://github.com/yasirkula/UnityBezierSolution
|
||||
E-mail: yasirkula@gmail.com
|
||||
|
||||
### ABOUT
|
||||
This plugin helps you create bezier splines either visually in editor or by code during gameplay. Includes some utility functions like finding the closest point on the spline or travelling the spline with constant speed. It is built upon Catlike Coding's spline tutorial: https://catlikecoding.com/unity/tutorials/curves-and-splines/
|
||||
|
||||
|
||||
### HOW TO
|
||||
To create a new spline in the editor, click "GameObject - Bezier Spline". Now you can select the end points of the spline in the Scene view and move/rotate/scale or delete/duplicate them as you wish (each end point also has 2 control points that can be moved around). Most variables have explanatory tooltips.
|
||||
|
||||
You can tweak the Scene view gizmos via "Project Settings/yasirkula/Bezier Solution" page (on older versions, this menu is located at "Preferences" window).
|
||||
|
||||
The plugin comes with some additional components that may help you move objects or particles along splines. These components are located in the Utilities folder:
|
||||
|
||||
- BezierWalkerWithSpeed: Moves an object along a spline with constant speed. There are 3 travel modes: Once, Ping Pong and Loop. If Look At is Forward, the object will always face forwards. If it is SplineExtraData, the extra data stored in the spline's end points is used to determine the rotation. You can modify this extra data from the points' Inspector. The smoothness of the rotation can be adjusted via Rotation Lerp Modifier. Normalized T determines the starting point. Each time the object completes a lap, its On Path Completed () event is invoked. To see this component in action without entering Play mode, click the "Simulate In Editor" button.
|
||||
|
||||
- BezierWalkerWithTime: Travels a spline in Travel Time seconds. Movement Lerp Modifier parameter defines the smoothness applied to the position of the object. If High Quality is enabled, the spline will be traversed with constant speed but the calculations can be more expensive.
|
||||
|
||||
- BezierWalkerLocomotion: Allows you to move a number of objects together with this object on a spline. This component must be attached to an object with a BezierWalker component (tail objects don't need a BezierWalker, though). Look At, Movement Lerp Modifier and Rotation Lerp Modifier parameters affect the tail objects. If tail objects jitter too much, enabling High Quality may help greatly but the calculations can be more expensive.
|
||||
|
||||
- ParticlesFollowBezier: Moves particles of a Particle System in the direction of a spline. It is recommended to set the Simulation Space of the Particle System to Local for increased performance. This component affects particles in one of two ways:
|
||||
-- Strict: particles will strictly follow the spline. They will always be aligned to the spline and will reach the end of the spline at the end of their lifetime. This mode performs slightly better than Relaxed mode
|
||||
-- Relaxed: properties of the particle system like speed, Noise and Shape will affect the movement of the particles. Particles in this mode will usually look more interesting. If you want the particles to stick with the spline, though, set their speed to 0
|
||||
|
||||
- BezierAttachment: Snaps an object to the specified point of the spline. You can snap the object's position and/or rotation values, optionally with some offsets. Rotation can be snapped in one of two ways:
|
||||
-- Use Spline Normals: spline's normal vectors will be used to determine the object's rotation
|
||||
-- Use End Point Rotations: the Transform rotation values of the spline's end points will be used to determine the object's rotation
|
||||
|
||||
- BezierLineRenderer: Automatically positions a Line Renderer's points so that its shape matches the target spline's shape. It is possible to match the shape of only a portion of the spline by tweaking the Spline Sample Range property. If Line Renderer's "Use World Space" property is enabled, then its points will be placed at the spline's current position. Otherwise, the points will be placed relative to the Line Renderer's position and they will rotate/scale with the Line Renderer.
|
||||
|
||||
- BendMeshAlongBezier: Modifies a MeshFilter's mesh to bend it in the direction of a spline (make sure that the spline's normals are perpendicular to the spline; Auto Calculate Normals may help). If High Quality is enabled, evenly spaced bezier points will be used so that the mesh bends uniformly but the calculations will be more expensive. If Auto Refresh is enabled, the mesh will be refreshed automatically when the spline is modified (at runtime, this has the same effect with disabling the component but in edit mode, disabling the component will restore the original mesh instead). Mesh's normal and tangent vectors can optionally be recalculated in one of two ways:
|
||||
-- Modify Originals: the original mesh's normal and tangent vectors will be rotated with the spline
|
||||
-- Recalculate From Scratch: Unity's RecalculateNormals and/or RecalculateTangents functions will be invoked to recalculate these vectors from scratch
|
||||
Note that this component doesn't add new vertices to the original mesh, so if the original mesh doesn't have enough vertices in its bend axis, then the bent mesh will have jagged edges on complex splines.
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 90c5928df0356a746a1423cce53181b9
|
||||
timeCreated: 1562520040
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 86440575d46397c488152ba57ee62ed4
|
||||
folderAsset: yes
|
||||
timeCreated: 1473251123
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,607 @@
|
|||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
using PrefabStage = UnityEditor.Experimental.SceneManagement.PrefabStage;
|
||||
using PrefabStageUtility = UnityEditor.Experimental.SceneManagement.PrefabStageUtility;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bend Mesh Along Bezier" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
[RequireComponent( typeof( MeshFilter ) )]
|
||||
[ExecuteInEditMode]
|
||||
public class BendMeshAlongBezier : MonoBehaviour
|
||||
{
|
||||
public enum VectorMode { DontModify = 0, ModifyOriginals = 1, RecalculateFromScratch = 2 };
|
||||
public enum Axis { X = 0, Y = 1, Z = 2 };
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private BezierSpline m_spline;
|
||||
public BezierSpline spline
|
||||
{
|
||||
get { return m_spline; }
|
||||
set
|
||||
{
|
||||
if( m_spline != value )
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
|
||||
m_spline = value;
|
||||
|
||||
if( m_spline && isActiveAndEnabled )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[MinMaxRange( 0f, 1f )]
|
||||
private Vector2 m_splineSampleRange = new Vector2( 0f, 1f );
|
||||
public Vector2 SplineSampleRange
|
||||
{
|
||||
get { return m_splineSampleRange; }
|
||||
set
|
||||
{
|
||||
value.x = Mathf.Clamp01( value.x );
|
||||
value.y = Mathf.Clamp01( value.y );
|
||||
|
||||
if( m_splineSampleRange != value )
|
||||
{
|
||||
m_splineSampleRange = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Bend Options" )]
|
||||
[SerializeField]
|
||||
private bool m_highQuality = false;
|
||||
public bool highQuality
|
||||
{
|
||||
get { return m_highQuality; }
|
||||
set
|
||||
{
|
||||
if( m_highQuality != value )
|
||||
{
|
||||
m_highQuality = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Axis m_bendAxis = Axis.Y;
|
||||
public Axis bendAxis
|
||||
{
|
||||
|
||||
get { return m_bendAxis; }
|
||||
set
|
||||
{
|
||||
if( m_bendAxis != value )
|
||||
{
|
||||
m_bendAxis = value;
|
||||
|
||||
RecalculateVertexRange();
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[Range( 0f, 360f )]
|
||||
private float m_extraRotation = 0f;
|
||||
public float extraRotation
|
||||
{
|
||||
get { return m_extraRotation; }
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp( value, 0f, 360f );
|
||||
|
||||
if( m_extraRotation != value )
|
||||
{
|
||||
m_extraRotation = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_invertDirection = false;
|
||||
public bool invertDirection
|
||||
{
|
||||
get { return m_invertDirection; }
|
||||
set
|
||||
{
|
||||
if( m_invertDirection != value )
|
||||
{
|
||||
m_invertDirection = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 m_thicknessMultiplier = Vector2.one;
|
||||
public Vector2 thicknessMultiplier
|
||||
{
|
||||
get { return m_thicknessMultiplier; }
|
||||
set
|
||||
{
|
||||
if( m_thicknessMultiplier != value )
|
||||
{
|
||||
m_thicknessMultiplier = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Vertex Attributes" )]
|
||||
[SerializeField]
|
||||
private VectorMode m_normalsMode = VectorMode.ModifyOriginals;
|
||||
public VectorMode normalsMode
|
||||
{
|
||||
get { return m_normalsMode; }
|
||||
set
|
||||
{
|
||||
if( m_normalsMode != value )
|
||||
{
|
||||
m_normalsMode = value;
|
||||
|
||||
if( mesh )
|
||||
{
|
||||
if( m_normalsMode == VectorMode.DontModify && originalNormals != null )
|
||||
{
|
||||
mesh.normals = originalNormals;
|
||||
originalNormals = null;
|
||||
}
|
||||
|
||||
if( m_normalsMode != VectorMode.ModifyOriginals )
|
||||
normals = null;
|
||||
}
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private VectorMode m_tangentsMode = VectorMode.ModifyOriginals;
|
||||
public VectorMode tangentsMode
|
||||
{
|
||||
get { return m_tangentsMode; }
|
||||
set
|
||||
{
|
||||
if( m_tangentsMode != value )
|
||||
{
|
||||
m_tangentsMode = value;
|
||||
|
||||
if( mesh )
|
||||
{
|
||||
if( m_tangentsMode == VectorMode.DontModify && originalTangents != null )
|
||||
{
|
||||
mesh.tangents = originalTangents;
|
||||
originalTangents = null;
|
||||
}
|
||||
|
||||
if( m_tangentsMode != VectorMode.ModifyOriginals )
|
||||
tangents = null;
|
||||
}
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Other Settings" )]
|
||||
[SerializeField]
|
||||
private bool m_autoRefresh = true;
|
||||
public bool autoRefresh
|
||||
{
|
||||
get { return m_autoRefresh; }
|
||||
set
|
||||
{
|
||||
if( m_autoRefresh != value )
|
||||
{
|
||||
m_autoRefresh = value;
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[SerializeField]
|
||||
private bool executeInEditMode = false;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private BezierSpline prevSpline;
|
||||
[SerializeField, HideInInspector]
|
||||
private VectorMode prevNormalsMode, prevTangentsMode;
|
||||
[SerializeField, HideInInspector]
|
||||
private bool prevHighQuality;
|
||||
#endif
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Mesh originalMesh; // If this isn't serialized, then sometimes exceptions occur on undo/redo
|
||||
#pragma warning restore 0649
|
||||
|
||||
private MeshFilter meshFilter;
|
||||
|
||||
private Mesh mesh;
|
||||
private Vector3[] vertices, originalVertices;
|
||||
private Vector3[] normals, originalNormals;
|
||||
private Vector4[] tangents, originalTangents;
|
||||
|
||||
private float minVertex, _1OverVertexRange;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Restore normals and tangents after assembly reload if they are set to DontModify because otherwise they become null automatically (i.e. information gets lost)
|
||||
if( mesh && originalMesh )
|
||||
{
|
||||
if( m_normalsMode == VectorMode.DontModify )
|
||||
mesh.normals = originalMesh.normals;
|
||||
if( m_tangentsMode == VectorMode.DontModify )
|
||||
mesh.tangents = originalMesh.tangents;
|
||||
}
|
||||
|
||||
EditorSceneManager.sceneSaving -= OnSceneSaving;
|
||||
EditorSceneManager.sceneSaving += OnSceneSaving;
|
||||
EditorSceneManager.sceneSaved -= OnSceneSaved;
|
||||
EditorSceneManager.sceneSaved += OnSceneSaved;
|
||||
#endif
|
||||
|
||||
if( m_spline )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
EditorSceneManager.sceneSaving -= OnSceneSaving;
|
||||
EditorSceneManager.sceneSaved -= OnSceneSaved;
|
||||
|
||||
if( !EditorApplication.isPlaying )
|
||||
OnDestroy();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
MeshFilter _meshFilter = meshFilter;
|
||||
meshFilter = null;
|
||||
|
||||
if( _meshFilter && originalMesh )
|
||||
_meshFilter.sharedMesh = originalMesh;
|
||||
|
||||
if( mesh )
|
||||
DestroyImmediate( mesh );
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2018_3_OR_NEWER
|
||||
// This allows removing the 'modified' flag of Mesh Filter's Mesh property but these sorts of things
|
||||
// may cause new problems in edge cases so it is commented out
|
||||
//if( !EditorApplication.isPlaying && _meshFilter && originalMesh )
|
||||
//{
|
||||
// // Revert modified status of the prefab instance's MeshFilter Mesh if possible
|
||||
// MeshFilter prefabMeshFilter = null;
|
||||
// if( PrefabUtility.GetPrefabInstanceStatus( _meshFilter ) == PrefabInstanceStatus.Connected )
|
||||
// prefabMeshFilter = PrefabUtility.GetCorrespondingObjectFromSource( _meshFilter ) as MeshFilter;
|
||||
|
||||
// if( prefabMeshFilter && prefabMeshFilter.sharedMesh == originalMesh )
|
||||
// PrefabUtility.RevertPropertyOverride( new SerializedObject( _meshFilter ).FindProperty( "m_Mesh" ), InteractionMode.AutomatedAction );
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
OnDestroy();
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
EditorApplication.update -= OnValidateImplementation;
|
||||
EditorApplication.update += OnValidateImplementation;
|
||||
}
|
||||
|
||||
// Calling this code inside OnValidate throws "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate" warnings
|
||||
private void OnValidateImplementation()
|
||||
{
|
||||
EditorApplication.update -= OnValidateImplementation;
|
||||
|
||||
if( !this )
|
||||
return;
|
||||
|
||||
BezierSpline _spline = m_spline;
|
||||
m_spline = prevSpline;
|
||||
spline = prevSpline = _spline;
|
||||
|
||||
bool _highQuality = m_highQuality;
|
||||
m_highQuality = prevHighQuality;
|
||||
highQuality = prevHighQuality = _highQuality;
|
||||
|
||||
VectorMode _normalsMode = m_normalsMode;
|
||||
m_normalsMode = prevNormalsMode;
|
||||
normalsMode = prevNormalsMode = _normalsMode;
|
||||
|
||||
VectorMode _tangentsMode = m_tangentsMode;
|
||||
m_tangentsMode = prevTangentsMode;
|
||||
tangentsMode = prevTangentsMode = _tangentsMode;
|
||||
|
||||
RecalculateVertexRange();
|
||||
|
||||
if( !executeInEditMode && !EditorApplication.isPlaying )
|
||||
OnDestroy();
|
||||
else if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
private void OnSceneSaving( UnityEngine.SceneManagement.Scene scene, string path )
|
||||
{
|
||||
// Restore original mesh before saving the scene
|
||||
if( scene == gameObject.scene )
|
||||
OnDestroy();
|
||||
}
|
||||
|
||||
private void OnSceneSaved( UnityEngine.SceneManagement.Scene scene )
|
||||
{
|
||||
// Restore modified mesh after saving the scene
|
||||
if( scene == gameObject.scene && isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnSplineChanged( BezierSpline spline, DirtyFlags dirtyFlags )
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if( !executeInEditMode && !EditorApplication.isPlaying )
|
||||
return;
|
||||
|
||||
if( BuildPipeline.isBuildingPlayer )
|
||||
return;
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
// Don't execute the script in prefab mode
|
||||
PrefabStage openPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
if( openPrefabStage != null && openPrefabStage.IsPartOfPrefabContents( gameObject ) )
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if( m_autoRefresh && ( dirtyFlags & ( DirtyFlags.SplineShapeChanged | DirtyFlags.NormalsChanged ) ) != DirtyFlags.None )
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
meshFilter = GetComponent<MeshFilter>();
|
||||
if( meshFilter.sharedMesh ) // It can sometimes be null during undo&redo which causes issues
|
||||
originalMesh = meshFilter.sharedMesh;
|
||||
|
||||
if( !originalMesh )
|
||||
return;
|
||||
|
||||
if( mesh )
|
||||
DestroyImmediate( mesh );
|
||||
|
||||
mesh = Instantiate( originalMesh );
|
||||
meshFilter.sharedMesh = mesh;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if( !EditorApplication.isPlaying )
|
||||
mesh.hideFlags = HideFlags.DontSave;
|
||||
#endif
|
||||
|
||||
originalVertices = mesh.vertices;
|
||||
originalNormals = null;
|
||||
originalTangents = null;
|
||||
|
||||
RecalculateVertexRange();
|
||||
}
|
||||
|
||||
private void RecalculateVertexRange()
|
||||
{
|
||||
if( originalVertices == null )
|
||||
return;
|
||||
|
||||
minVertex = float.PositiveInfinity;
|
||||
float maxVertex = float.NegativeInfinity;
|
||||
|
||||
switch( m_bendAxis )
|
||||
{
|
||||
case Axis.X:
|
||||
for( int i = 0; i < originalVertices.Length; i++ )
|
||||
{
|
||||
float vertex = originalVertices[i].x;
|
||||
if( vertex < minVertex )
|
||||
minVertex = originalVertices[i].x;
|
||||
if( vertex > maxVertex )
|
||||
maxVertex = originalVertices[i].x;
|
||||
}
|
||||
break;
|
||||
case Axis.Y:
|
||||
for( int i = 0; i < originalVertices.Length; i++ )
|
||||
{
|
||||
float vertex = originalVertices[i].y;
|
||||
if( vertex < minVertex )
|
||||
minVertex = originalVertices[i].y;
|
||||
if( vertex > maxVertex )
|
||||
maxVertex = originalVertices[i].y;
|
||||
}
|
||||
break;
|
||||
case Axis.Z:
|
||||
for( int i = 0; i < originalVertices.Length; i++ )
|
||||
{
|
||||
float vertex = originalVertices[i].z;
|
||||
if( vertex < minVertex )
|
||||
minVertex = originalVertices[i].z;
|
||||
if( vertex > maxVertex )
|
||||
maxVertex = originalVertices[i].z;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_1OverVertexRange = 1f / ( maxVertex - minVertex );
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if( !m_spline )
|
||||
return;
|
||||
|
||||
if( !meshFilter || ( meshFilter.sharedMesh && meshFilter.sharedMesh != mesh && meshFilter.sharedMesh != originalMesh ) )
|
||||
Initialize();
|
||||
|
||||
if( !originalMesh )
|
||||
return;
|
||||
|
||||
if( vertices == null || vertices.Length != originalVertices.Length )
|
||||
vertices = new Vector3[originalVertices.Length];
|
||||
|
||||
if( m_normalsMode == VectorMode.ModifyOriginals )
|
||||
{
|
||||
if( originalNormals == null )
|
||||
originalNormals = originalMesh.normals;
|
||||
|
||||
if( originalNormals == null || originalNormals.Length < originalVertices.Length ) // If somehow above statement returned null
|
||||
normals = null;
|
||||
else if( normals == null || normals.Length != originalNormals.Length )
|
||||
normals = new Vector3[originalNormals.Length];
|
||||
}
|
||||
else
|
||||
normals = null;
|
||||
|
||||
if( m_tangentsMode == VectorMode.ModifyOriginals )
|
||||
{
|
||||
if( originalTangents == null )
|
||||
originalTangents = originalMesh.tangents;
|
||||
|
||||
if( originalTangents == null || originalTangents.Length < originalVertices.Length ) // If somehow above statement returned null
|
||||
tangents = null;
|
||||
else if( tangents == null || tangents.Length != originalTangents.Length )
|
||||
tangents = new Vector4[originalTangents.Length];
|
||||
}
|
||||
else
|
||||
tangents = null;
|
||||
|
||||
Vector2 _splineSampleRange = m_splineSampleRange;
|
||||
if( m_invertDirection )
|
||||
{
|
||||
float temp = _splineSampleRange.x;
|
||||
_splineSampleRange.x = _splineSampleRange.y;
|
||||
_splineSampleRange.y = temp;
|
||||
}
|
||||
|
||||
bool isSampleRangeForwards = _splineSampleRange.x <= _splineSampleRange.y;
|
||||
float splineSampleLength = _splineSampleRange.y - _splineSampleRange.x;
|
||||
bool dontInvertModifiedVertexAttributes = ( m_thicknessMultiplier.x > 0f && m_thicknessMultiplier.y > 0f );
|
||||
|
||||
BezierSpline.EvenlySpacedPointsHolder evenlySpacedPoints = m_highQuality ? m_spline.evenlySpacedPoints : null;
|
||||
|
||||
Vector3 initialPoint = m_spline.GetPoint( 0f );
|
||||
for( int i = 0; i < originalVertices.Length; i++ )
|
||||
{
|
||||
Vector3 vertex = originalVertices[i];
|
||||
|
||||
float vertexPosition;
|
||||
Vector3 vertexOffset;
|
||||
switch( m_bendAxis )
|
||||
{
|
||||
case Axis.X:
|
||||
vertexPosition = vertex.x;
|
||||
vertexOffset = new Vector3( vertex.z * m_thicknessMultiplier.x, 0f, vertex.y * m_thicknessMultiplier.y );
|
||||
break;
|
||||
case Axis.Y:
|
||||
default:
|
||||
vertexPosition = vertex.y;
|
||||
vertexOffset = new Vector3( vertex.x * m_thicknessMultiplier.x, 0f, vertex.z * m_thicknessMultiplier.y );
|
||||
break;
|
||||
case Axis.Z:
|
||||
vertexPosition = vertex.z;
|
||||
vertexOffset = new Vector3( vertex.y * m_thicknessMultiplier.x, 0f, vertex.x * m_thicknessMultiplier.y );
|
||||
break;
|
||||
}
|
||||
|
||||
float normalizedT = _splineSampleRange.x + ( vertexPosition - minVertex ) * _1OverVertexRange * splineSampleLength; // Remap from [minVertex,maxVertex] to _splineSampleRange
|
||||
if( m_highQuality )
|
||||
normalizedT = evenlySpacedPoints.GetNormalizedTAtPercentage( normalizedT );
|
||||
|
||||
BezierSpline.Segment segment = m_spline.GetSegmentAt( normalizedT );
|
||||
|
||||
Vector3 point = segment.GetPoint() - initialPoint;
|
||||
Vector3 tangent = isSampleRangeForwards ? segment.GetTangent() : -segment.GetTangent();
|
||||
Quaternion rotation = Quaternion.AngleAxis( m_extraRotation, tangent ) * Quaternion.LookRotation( segment.GetNormal(), tangent );
|
||||
|
||||
Vector3 direction = rotation * vertexOffset;
|
||||
vertices[i] = point + direction;
|
||||
|
||||
if( normals != null ) // The only case this happens is when Normals Mode is ModifyOriginals and the original mesh has normals
|
||||
normals[i] = rotation * ( dontInvertModifiedVertexAttributes ? originalNormals[i] : -originalNormals[i] );
|
||||
if( tangents != null ) // The only case this happens is when Tangents Mode is ModifyOriginals and the original mesh has tangents
|
||||
{
|
||||
float tangentW = originalTangents[i].w;
|
||||
tangents[i] = rotation * ( dontInvertModifiedVertexAttributes ? originalTangents[i] : -originalTangents[i] );
|
||||
tangents[i].w = tangentW;
|
||||
}
|
||||
}
|
||||
|
||||
mesh.vertices = vertices;
|
||||
if( m_normalsMode == VectorMode.ModifyOriginals )
|
||||
mesh.normals = normals;
|
||||
if( m_tangentsMode == VectorMode.ModifyOriginals )
|
||||
mesh.tangents = tangents;
|
||||
|
||||
if( m_normalsMode == VectorMode.RecalculateFromScratch )
|
||||
{
|
||||
mesh.RecalculateNormals();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Cache original normals so that we can reset normals in OnValidate when normals are reset back to DontModify
|
||||
if( originalNormals == null )
|
||||
originalNormals = originalMesh.normals;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( m_tangentsMode == VectorMode.RecalculateFromScratch )
|
||||
{
|
||||
mesh.RecalculateTangents();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Cache original tangents so that we can reset tangents in OnValidate when tangents are reset back to DontModify
|
||||
if( originalTangents == null )
|
||||
originalTangents = originalMesh.tangents;
|
||||
#endif
|
||||
}
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0e815427364673446939224ffdf5e5fd
|
||||
timeCreated: 1620245307
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,231 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Attachment" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
[ExecuteInEditMode]
|
||||
public class BezierAttachment : MonoBehaviour
|
||||
{
|
||||
public enum RotationMode { No = 0, UseSplineNormals = 1, UseEndPointRotations = 2 };
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private BezierSpline m_spline;
|
||||
public BezierSpline spline
|
||||
{
|
||||
get { return m_spline; }
|
||||
set
|
||||
{
|
||||
if( m_spline != value )
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
|
||||
m_spline = value;
|
||||
|
||||
if( m_spline && isActiveAndEnabled )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[Range( 0f, 1f )]
|
||||
private float m_normalizedT = 0f;
|
||||
public float normalizedT
|
||||
{
|
||||
get { return m_normalizedT; }
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp01( value );
|
||||
|
||||
if( m_normalizedT != value )
|
||||
{
|
||||
m_normalizedT = value;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Position" )]
|
||||
[SerializeField]
|
||||
private bool m_updatePosition = true;
|
||||
public bool updatePosition
|
||||
{
|
||||
get { return m_updatePosition; }
|
||||
set
|
||||
{
|
||||
if( m_updatePosition != value )
|
||||
{
|
||||
m_updatePosition = value;
|
||||
|
||||
if( m_updatePosition && isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.SplineShapeChanged );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 m_positionOffset;
|
||||
public Vector3 positionOffset
|
||||
{
|
||||
get { return m_positionOffset; }
|
||||
set
|
||||
{
|
||||
if( m_positionOffset != value )
|
||||
{
|
||||
m_positionOffset = value;
|
||||
|
||||
if( m_updatePosition && isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.SplineShapeChanged );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Rotation" )]
|
||||
[SerializeField]
|
||||
private RotationMode m_updateRotation = RotationMode.UseSplineNormals;
|
||||
public RotationMode updateRotation
|
||||
{
|
||||
get { return m_updateRotation; }
|
||||
set
|
||||
{
|
||||
if( m_updateRotation != value )
|
||||
{
|
||||
m_updateRotation = value;
|
||||
|
||||
if( m_updateRotation != RotationMode.No && isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.SplineShapeChanged );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 m_rotationOffset;
|
||||
public Vector3 rotationOffset
|
||||
{
|
||||
get { return m_rotationOffset; }
|
||||
set
|
||||
{
|
||||
if( m_rotationOffset != value )
|
||||
{
|
||||
m_rotationOffset = value;
|
||||
|
||||
if( m_updateRotation != RotationMode.No && isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.SplineShapeChanged );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[Header( "Other Settings" )]
|
||||
[SerializeField]
|
||||
private bool executeInEditMode = false;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private BezierSpline prevSpline;
|
||||
#endif
|
||||
#pragma warning restore 0649
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if( m_spline )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
UnityEditor.Undo.RecordObject( transform, "Modify BezierAttachment" );
|
||||
|
||||
BezierSpline _spline = m_spline;
|
||||
m_spline = prevSpline;
|
||||
spline = prevSpline = _spline;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if( transform.hasChanged )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnSplineChanged( BezierSpline spline, DirtyFlags dirtyFlags )
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if( !executeInEditMode && !UnityEditor.EditorApplication.isPlaying )
|
||||
return;
|
||||
#endif
|
||||
|
||||
RefreshInternal( dirtyFlags );
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
RefreshInternal( DirtyFlags.All );
|
||||
}
|
||||
|
||||
private void RefreshInternal( DirtyFlags dirtyFlags )
|
||||
{
|
||||
if( !m_spline || m_spline.Count < 2 )
|
||||
return;
|
||||
|
||||
if( !m_updatePosition && m_updateRotation == RotationMode.No )
|
||||
return;
|
||||
|
||||
BezierSpline.Segment segment = m_spline.GetSegmentAt( m_normalizedT );
|
||||
|
||||
switch( m_updateRotation )
|
||||
{
|
||||
case RotationMode.UseSplineNormals:
|
||||
if( m_rotationOffset == Vector3.zero )
|
||||
transform.rotation = Quaternion.LookRotation( segment.GetTangent(), segment.GetNormal() );
|
||||
else
|
||||
transform.rotation = Quaternion.LookRotation( segment.GetTangent(), segment.GetNormal() ) * Quaternion.Euler( m_rotationOffset );
|
||||
|
||||
break;
|
||||
case RotationMode.UseEndPointRotations:
|
||||
if( m_rotationOffset == Vector3.zero )
|
||||
transform.rotation = Quaternion.LerpUnclamped( segment.point1.rotation, segment.point2.rotation, segment.localT );
|
||||
else
|
||||
transform.rotation = Quaternion.LerpUnclamped( segment.point1.rotation, segment.point2.rotation, segment.localT ) * Quaternion.Euler( m_rotationOffset );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_updatePosition && ( dirtyFlags & DirtyFlags.SplineShapeChanged ) == DirtyFlags.SplineShapeChanged )
|
||||
{
|
||||
if( m_positionOffset == Vector3.zero )
|
||||
transform.position = segment.GetPoint();
|
||||
else
|
||||
transform.position = segment.GetPoint() + transform.rotation * m_positionOffset;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
transform.hasChanged = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9b6258aafd9a87344833937e5e546638
|
||||
timeCreated: 1620400687
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,206 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Line Renderer" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
[RequireComponent( typeof( LineRenderer ) )]
|
||||
[ExecuteInEditMode]
|
||||
public class BezierLineRenderer : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private BezierSpline m_spline;
|
||||
public BezierSpline spline
|
||||
{
|
||||
get { return m_spline; }
|
||||
set
|
||||
{
|
||||
if( m_spline != value )
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
|
||||
m_spline = value;
|
||||
|
||||
if( m_spline && isActiveAndEnabled )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[MinMaxRange( 0f, 1f )]
|
||||
private Vector2 m_splineSampleRange = new Vector2( 0f, 1f );
|
||||
public Vector2 SplineSampleRange
|
||||
{
|
||||
get { return m_splineSampleRange; }
|
||||
set
|
||||
{
|
||||
value.x = Mathf.Clamp01( value.x );
|
||||
value.y = Mathf.Clamp01( value.y );
|
||||
|
||||
if( m_splineSampleRange != value )
|
||||
{
|
||||
m_splineSampleRange = value;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header( "Line Options" )]
|
||||
[SerializeField]
|
||||
[Range( 0, 30 )]
|
||||
private int m_smoothness = 5;
|
||||
public int smoothness
|
||||
{
|
||||
get { return m_smoothness; }
|
||||
set
|
||||
{
|
||||
if( m_smoothness != value )
|
||||
{
|
||||
m_smoothness = value;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[Header( "Other Settings" )]
|
||||
[SerializeField]
|
||||
private bool executeInEditMode = false;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private BezierSpline prevSpline;
|
||||
#endif
|
||||
#pragma warning restore 0649
|
||||
|
||||
private LineRenderer lineRenderer;
|
||||
private Vector3[] lineRendererPoints;
|
||||
#if UNITY_EDITOR
|
||||
private bool lineRendererUseWorldSpace = true;
|
||||
#endif
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if( m_spline )
|
||||
{
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
m_spline.onSplineChanged += OnSplineChanged;
|
||||
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if( m_spline )
|
||||
m_spline.onSplineChanged -= OnSplineChanged;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void Update()
|
||||
{
|
||||
if( lineRenderer && lineRenderer.useWorldSpace != lineRendererUseWorldSpace )
|
||||
{
|
||||
lineRendererUseWorldSpace = !lineRendererUseWorldSpace;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
BezierSpline _spline = m_spline;
|
||||
m_spline = prevSpline;
|
||||
spline = prevSpline = _spline;
|
||||
|
||||
if( isActiveAndEnabled )
|
||||
OnSplineChanged( m_spline, DirtyFlags.All );
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnSplineChanged( BezierSpline spline, DirtyFlags dirtyFlags )
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if( !executeInEditMode && !UnityEditor.EditorApplication.isPlaying )
|
||||
return;
|
||||
#endif
|
||||
|
||||
if( ( dirtyFlags & DirtyFlags.SplineShapeChanged ) == DirtyFlags.SplineShapeChanged )
|
||||
Refresh( m_smoothness );
|
||||
}
|
||||
|
||||
public void Refresh( int smoothness )
|
||||
{
|
||||
if( !m_spline || m_spline.Count < 2 )
|
||||
return;
|
||||
|
||||
if( !lineRenderer )
|
||||
lineRenderer = GetComponent<LineRenderer>();
|
||||
|
||||
smoothness = Mathf.Clamp( smoothness, 1, 30 );
|
||||
|
||||
int numberOfPoints = ( m_spline.Count - 1 ) * smoothness;
|
||||
if( !m_spline.loop )
|
||||
numberOfPoints++; // spline.GetPoint( 1f )
|
||||
else
|
||||
numberOfPoints += smoothness; // Final point is connected to the first point via lineRenderer.loop, so no "numberOfPoints++" here
|
||||
|
||||
if( lineRendererPoints == null || lineRendererPoints.Length != numberOfPoints )
|
||||
lineRendererPoints = new Vector3[numberOfPoints];
|
||||
|
||||
if( m_splineSampleRange.x <= 0f && m_splineSampleRange.y >= 1f )
|
||||
{
|
||||
int pointIndex = 0;
|
||||
float smoothnessStep = 1f / smoothness;
|
||||
for( int i = 0; i < m_spline.Count - 1; i++ )
|
||||
{
|
||||
BezierSpline.Segment segment = new BezierSpline.Segment( m_spline[i], m_spline[i + 1], 0f );
|
||||
for( int j = 0; j < smoothness; j++, pointIndex++ )
|
||||
lineRendererPoints[pointIndex] = segment.GetPoint( j * smoothnessStep );
|
||||
}
|
||||
|
||||
if( !m_spline.loop )
|
||||
lineRendererPoints[numberOfPoints - 1] = m_spline.GetPoint( 1f );
|
||||
else
|
||||
{
|
||||
BezierSpline.Segment segment = new BezierSpline.Segment( m_spline[m_spline.Count - 1], m_spline[0], 0f );
|
||||
for( int j = 0; j < smoothness; j++, pointIndex++ )
|
||||
lineRendererPoints[pointIndex] = segment.GetPoint( j * smoothnessStep );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float smoothnessStep = ( m_splineSampleRange.y - m_splineSampleRange.x ) / ( numberOfPoints - 1 );
|
||||
for( int i = 0; i < numberOfPoints; i++ )
|
||||
lineRendererPoints[i] = spline.GetPoint( m_splineSampleRange.x + i * smoothnessStep );
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
lineRendererUseWorldSpace = lineRenderer.useWorldSpace;
|
||||
#endif
|
||||
if( !lineRenderer.useWorldSpace )
|
||||
{
|
||||
Vector3 initialPoint = m_spline.GetPoint( 0f );
|
||||
for( int i = 0; i < numberOfPoints; i++ )
|
||||
lineRendererPoints[i] -= initialPoint;
|
||||
}
|
||||
|
||||
lineRenderer.positionCount = lineRendererPoints.Length;
|
||||
lineRenderer.SetPositions( lineRendererPoints );
|
||||
lineRenderer.loop = m_spline.loop && m_splineSampleRange.x <= 0f && m_splineSampleRange.y >= 1f;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09bf7d81c21c8564abb7c13d3e848e94
|
||||
timeCreated: 1620206953
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,23 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
public enum TravelMode { Once = 0, Loop = 1, PingPong = 2 };
|
||||
public enum LookAtMode { None = 0, Forward = 1, SplineExtraData = 2 }
|
||||
|
||||
public abstract class BezierWalker : MonoBehaviour
|
||||
{
|
||||
public abstract BezierSpline Spline { get; }
|
||||
public abstract bool MovingForward { get; }
|
||||
public abstract float NormalizedT { get; set; }
|
||||
|
||||
public abstract void Execute( float deltaTime );
|
||||
|
||||
public static readonly ExtraDataLerpFunction extraDataLerpAsQuaternionFunction = InterpolateExtraDataAsQuaternion;
|
||||
|
||||
private static BezierPoint.ExtraData InterpolateExtraDataAsQuaternion( BezierPoint.ExtraData data1, BezierPoint.ExtraData data2, float normalizedT )
|
||||
{
|
||||
return Quaternion.LerpUnclamped( data1, data2, normalizedT );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2e3fd6f386de3644ba3090712795517d
|
||||
timeCreated: 1542623772
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,155 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Walker Locomotion" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
public class BezierWalkerLocomotion : BezierWalker
|
||||
{
|
||||
public BezierWalker walker;
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField]
|
||||
private List<Transform> tailObjects;
|
||||
public List<Transform> Tail { get { return tailObjects; } }
|
||||
|
||||
[SerializeField]
|
||||
private List<float> tailObjectDistances;
|
||||
public List<float> TailDistances { get { return tailObjectDistances; } }
|
||||
#pragma warning restore 0649
|
||||
|
||||
public bool highQuality = true; // true by default because when it is set to false, tail objects can jitter too much
|
||||
|
||||
public float movementLerpModifier = 10f;
|
||||
public float rotationLerpModifier = 10f;
|
||||
|
||||
public LookAtMode lookAt = LookAtMode.Forward;
|
||||
|
||||
public override BezierSpline Spline { get { return walker.Spline; } }
|
||||
public override bool MovingForward { get { return walker.MovingForward; } }
|
||||
public override float NormalizedT
|
||||
{
|
||||
get { return walker.NormalizedT; }
|
||||
set { walker.NormalizedT = value; }
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if( !walker )
|
||||
{
|
||||
Debug.LogError( "Need to attach BezierWalkerLocomotion to a BezierWalker!" );
|
||||
Destroy( this );
|
||||
}
|
||||
|
||||
if( tailObjects.Count != tailObjectDistances.Count )
|
||||
{
|
||||
Debug.LogError( "One distance per tail object is needed!" );
|
||||
Destroy( this );
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
Execute( Time.deltaTime );
|
||||
}
|
||||
|
||||
public override void Execute( float deltaTime )
|
||||
{
|
||||
BezierSpline spline = Spline;
|
||||
float t = highQuality ? spline.evenlySpacedPoints.GetPercentageAtNormalizedT( NormalizedT ) : NormalizedT;
|
||||
bool forward = MovingForward;
|
||||
|
||||
for( int i = 0; i < tailObjects.Count; i++ )
|
||||
{
|
||||
Transform tailObject = tailObjects[i];
|
||||
Vector3 tailPosition;
|
||||
float tailNormalizedT;
|
||||
if( highQuality )
|
||||
{
|
||||
if( forward )
|
||||
t -= tailObjectDistances[i] / spline.evenlySpacedPoints.splineLength;
|
||||
else
|
||||
t += tailObjectDistances[i] / spline.evenlySpacedPoints.splineLength;
|
||||
|
||||
tailNormalizedT = spline.evenlySpacedPoints.GetNormalizedTAtPercentage( t );
|
||||
tailPosition = spline.GetPoint( tailNormalizedT );
|
||||
}
|
||||
else
|
||||
{
|
||||
tailPosition = spline.MoveAlongSpline( ref t, forward ? -tailObjectDistances[i] : tailObjectDistances[i] );
|
||||
tailNormalizedT = t;
|
||||
}
|
||||
|
||||
tailObject.position = Vector3.Lerp( tailObject.position, tailPosition, movementLerpModifier * deltaTime );
|
||||
|
||||
if( lookAt == LookAtMode.Forward )
|
||||
{
|
||||
BezierSpline.Segment segment = spline.GetSegmentAt( tailNormalizedT );
|
||||
tailObject.rotation = Quaternion.Lerp( tailObject.rotation, Quaternion.LookRotation( forward ? segment.GetTangent() : -segment.GetTangent(), segment.GetNormal() ), rotationLerpModifier * deltaTime );
|
||||
}
|
||||
else if( lookAt == LookAtMode.SplineExtraData )
|
||||
tailObject.rotation = Quaternion.Lerp( tailObject.rotation, spline.GetExtraData( tailNormalizedT, extraDataLerpAsQuaternionFunction ), rotationLerpModifier * deltaTime );
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToTail( Transform transform, float distanceToPreviousObject )
|
||||
{
|
||||
if( transform == null )
|
||||
{
|
||||
Debug.LogError( "Object is null!" );
|
||||
return;
|
||||
}
|
||||
|
||||
tailObjects.Add( transform );
|
||||
tailObjectDistances.Add( distanceToPreviousObject );
|
||||
}
|
||||
|
||||
public void InsertIntoTail( int index, Transform transform, float distanceToPreviousObject )
|
||||
{
|
||||
if( transform == null )
|
||||
{
|
||||
Debug.LogError( "Object is null!" );
|
||||
return;
|
||||
}
|
||||
|
||||
tailObjects.Insert( index, transform );
|
||||
tailObjectDistances.Insert( index, distanceToPreviousObject );
|
||||
}
|
||||
|
||||
public void RemoveFromTail( Transform transform )
|
||||
{
|
||||
if( transform == null )
|
||||
{
|
||||
Debug.LogError( "Object is null!" );
|
||||
return;
|
||||
}
|
||||
|
||||
for( int i = 0; i < tailObjects.Count; i++ )
|
||||
{
|
||||
if( tailObjects[i] == transform )
|
||||
{
|
||||
tailObjects.RemoveAt( i );
|
||||
tailObjectDistances.RemoveAt( i );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void Reset()
|
||||
{
|
||||
BezierWalker[] walkerComponents = GetComponents<BezierWalker>();
|
||||
for( int i = 0; i < walkerComponents.Length; i++ )
|
||||
{
|
||||
if( !( walkerComponents[i] is BezierWalkerLocomotion ) && ( (MonoBehaviour) walkerComponents[i] ).enabled )
|
||||
{
|
||||
walker = walkerComponents[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 17b675957a920ef4e8da909ede6d0d04
|
||||
timeCreated: 1542623444
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,126 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Walker With Speed" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
public class BezierWalkerWithSpeed : BezierWalker
|
||||
{
|
||||
public BezierSpline spline;
|
||||
public TravelMode travelMode;
|
||||
|
||||
public float speed = 5f;
|
||||
[SerializeField]
|
||||
[Range( 0f, 1f )]
|
||||
private float m_normalizedT = 0f;
|
||||
|
||||
public override BezierSpline Spline { get { return spline; } }
|
||||
|
||||
public override float NormalizedT
|
||||
{
|
||||
get { return m_normalizedT; }
|
||||
set { m_normalizedT = value; }
|
||||
}
|
||||
|
||||
//public float movementLerpModifier = 10f;
|
||||
public float rotationLerpModifier = 10f;
|
||||
|
||||
public LookAtMode lookAt = LookAtMode.Forward;
|
||||
|
||||
private bool isGoingForward = true;
|
||||
public override bool MovingForward { get { return ( speed > 0f ) == isGoingForward; } }
|
||||
|
||||
public UnityEvent onPathCompleted = new UnityEvent();
|
||||
private bool onPathCompletedCalledAt1 = false;
|
||||
private bool onPathCompletedCalledAt0 = false;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Execute( Time.deltaTime );
|
||||
}
|
||||
|
||||
public override void Execute( float deltaTime )
|
||||
{
|
||||
float targetSpeed = ( isGoingForward ) ? speed : -speed;
|
||||
|
||||
Vector3 targetPos = spline.MoveAlongSpline( ref m_normalizedT, targetSpeed * deltaTime );
|
||||
|
||||
transform.position = targetPos;
|
||||
//transform.position = Vector3.Lerp( transform.position, targetPos, movementLerpModifier * deltaTime );
|
||||
|
||||
bool movingForward = MovingForward;
|
||||
|
||||
if( lookAt == LookAtMode.Forward )
|
||||
{
|
||||
BezierSpline.Segment segment = spline.GetSegmentAt( m_normalizedT );
|
||||
Quaternion targetRotation;
|
||||
if( movingForward )
|
||||
targetRotation = Quaternion.LookRotation( segment.GetTangent(), segment.GetNormal() );
|
||||
else
|
||||
targetRotation = Quaternion.LookRotation( -segment.GetTangent(), segment.GetNormal() );
|
||||
|
||||
transform.rotation = Quaternion.Lerp( transform.rotation, targetRotation, rotationLerpModifier * deltaTime );
|
||||
}
|
||||
else if( lookAt == LookAtMode.SplineExtraData )
|
||||
transform.rotation = Quaternion.Lerp( transform.rotation, spline.GetExtraData( m_normalizedT, extraDataLerpAsQuaternionFunction ), rotationLerpModifier * deltaTime );
|
||||
|
||||
if( movingForward )
|
||||
{
|
||||
if( m_normalizedT >= 1f )
|
||||
{
|
||||
if( travelMode == TravelMode.Once )
|
||||
m_normalizedT = 1f;
|
||||
else if( travelMode == TravelMode.Loop )
|
||||
m_normalizedT -= 1f;
|
||||
else
|
||||
{
|
||||
m_normalizedT = 2f - m_normalizedT;
|
||||
isGoingForward = !isGoingForward;
|
||||
}
|
||||
|
||||
if( !onPathCompletedCalledAt1 )
|
||||
{
|
||||
onPathCompletedCalledAt1 = true;
|
||||
#if UNITY_EDITOR
|
||||
if( UnityEditor.EditorApplication.isPlaying )
|
||||
#endif
|
||||
onPathCompleted.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onPathCompletedCalledAt1 = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_normalizedT <= 0f )
|
||||
{
|
||||
if( travelMode == TravelMode.Once )
|
||||
m_normalizedT = 0f;
|
||||
else if( travelMode == TravelMode.Loop )
|
||||
m_normalizedT += 1f;
|
||||
else
|
||||
{
|
||||
m_normalizedT = -m_normalizedT;
|
||||
isGoingForward = !isGoingForward;
|
||||
}
|
||||
|
||||
if( !onPathCompletedCalledAt0 )
|
||||
{
|
||||
onPathCompletedCalledAt0 = true;
|
||||
#if UNITY_EDITOR
|
||||
if( UnityEditor.EditorApplication.isPlaying )
|
||||
#endif
|
||||
onPathCompleted.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onPathCompletedCalledAt0 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 148310ac13c958d4c93f53cdfe985375
|
||||
timeCreated: 1473251134
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,127 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Bezier Walker With Time" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
public class BezierWalkerWithTime : BezierWalker
|
||||
{
|
||||
public BezierSpline spline;
|
||||
public TravelMode travelMode;
|
||||
|
||||
public float travelTime = 5f;
|
||||
[SerializeField]
|
||||
[Range( 0f, 1f )]
|
||||
private float m_normalizedT = 0f;
|
||||
|
||||
public bool highQuality = false;
|
||||
|
||||
public override BezierSpline Spline { get { return spline; } }
|
||||
|
||||
public override float NormalizedT
|
||||
{
|
||||
get { return m_normalizedT; }
|
||||
set { m_normalizedT = value; }
|
||||
}
|
||||
|
||||
public float movementLerpModifier = 10f;
|
||||
public float rotationLerpModifier = 10f;
|
||||
|
||||
public LookAtMode lookAt = LookAtMode.Forward;
|
||||
|
||||
private bool isGoingForward = true;
|
||||
public override bool MovingForward { get { return isGoingForward; } }
|
||||
|
||||
public UnityEvent onPathCompleted = new UnityEvent();
|
||||
private bool onPathCompletedCalledAt1 = false;
|
||||
private bool onPathCompletedCalledAt0 = false;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Execute( Time.deltaTime );
|
||||
}
|
||||
|
||||
public override void Execute( float deltaTime )
|
||||
{
|
||||
float _normalizedT = highQuality ? spline.evenlySpacedPoints.GetNormalizedTAtPercentage( m_normalizedT ) : m_normalizedT;
|
||||
|
||||
transform.position = Vector3.Lerp( transform.position, spline.GetPoint( _normalizedT ), movementLerpModifier * deltaTime );
|
||||
|
||||
if( lookAt == LookAtMode.Forward )
|
||||
{
|
||||
BezierSpline.Segment segment = spline.GetSegmentAt( _normalizedT );
|
||||
Quaternion targetRotation;
|
||||
if( isGoingForward )
|
||||
targetRotation = Quaternion.LookRotation( segment.GetTangent(), segment.GetNormal() );
|
||||
else
|
||||
targetRotation = Quaternion.LookRotation( -segment.GetTangent(), segment.GetNormal() );
|
||||
|
||||
transform.rotation = Quaternion.Lerp( transform.rotation, targetRotation, rotationLerpModifier * deltaTime );
|
||||
}
|
||||
else if( lookAt == LookAtMode.SplineExtraData )
|
||||
transform.rotation = Quaternion.Lerp( transform.rotation, spline.GetExtraData( _normalizedT, extraDataLerpAsQuaternionFunction ), rotationLerpModifier * deltaTime );
|
||||
|
||||
if( isGoingForward )
|
||||
{
|
||||
m_normalizedT += deltaTime / travelTime;
|
||||
|
||||
if( m_normalizedT > 1f )
|
||||
{
|
||||
if( travelMode == TravelMode.Once )
|
||||
m_normalizedT = 1f;
|
||||
else if( travelMode == TravelMode.Loop )
|
||||
m_normalizedT -= 1f;
|
||||
else
|
||||
{
|
||||
m_normalizedT = 2f - m_normalizedT;
|
||||
isGoingForward = false;
|
||||
}
|
||||
|
||||
if( !onPathCompletedCalledAt1 )
|
||||
{
|
||||
onPathCompletedCalledAt1 = true;
|
||||
#if UNITY_EDITOR
|
||||
if( UnityEditor.EditorApplication.isPlaying )
|
||||
#endif
|
||||
onPathCompleted.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onPathCompletedCalledAt1 = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_normalizedT -= deltaTime / travelTime;
|
||||
|
||||
if( m_normalizedT < 0f )
|
||||
{
|
||||
if( travelMode == TravelMode.Once )
|
||||
m_normalizedT = 0f;
|
||||
else if( travelMode == TravelMode.Loop )
|
||||
m_normalizedT += 1f;
|
||||
else
|
||||
{
|
||||
m_normalizedT = -m_normalizedT;
|
||||
isGoingForward = true;
|
||||
}
|
||||
|
||||
if( !onPathCompletedCalledAt0 )
|
||||
{
|
||||
onPathCompletedCalledAt0 = true;
|
||||
#if UNITY_EDITOR
|
||||
if( UnityEditor.EditorApplication.isPlaying )
|
||||
#endif
|
||||
onPathCompleted.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onPathCompletedCalledAt0 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 46d12b9f97514694e962a3395a73e638
|
||||
timeCreated: 1473251134
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,106 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BezierSolution
|
||||
{
|
||||
[AddComponentMenu( "Bezier Solution/Particles Follow Bezier" )]
|
||||
[HelpURL( "https://github.com/yasirkula/UnityBezierSolution" )]
|
||||
[RequireComponent( typeof( ParticleSystem ) )]
|
||||
[ExecuteInEditMode]
|
||||
public class ParticlesFollowBezier : MonoBehaviour
|
||||
{
|
||||
private const int MAX_PARTICLE_COUNT = 25000;
|
||||
|
||||
public enum FollowMode { Relaxed, Strict };
|
||||
|
||||
public BezierSpline spline;
|
||||
public FollowMode followMode = FollowMode.Relaxed;
|
||||
|
||||
private Transform cachedTransform;
|
||||
private ParticleSystem cachedPS;
|
||||
private ParticleSystem.MainModule cachedMainModule;
|
||||
|
||||
private ParticleSystem.Particle[] particles;
|
||||
private List<Vector4> particleData;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
cachedTransform = transform;
|
||||
cachedPS = GetComponent<ParticleSystem>();
|
||||
|
||||
cachedMainModule = cachedPS.main;
|
||||
particles = new ParticleSystem.Particle[cachedMainModule.maxParticles];
|
||||
|
||||
if( followMode == FollowMode.Relaxed )
|
||||
particleData = new List<Vector4>( particles.Length );
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnEnable()
|
||||
{
|
||||
Awake();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void LateUpdate()
|
||||
{
|
||||
if( !UnityEditor.EditorApplication.isPlaying )
|
||||
FixedUpdate();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if( spline == null || cachedPS == null )
|
||||
return;
|
||||
|
||||
if( particles.Length < cachedMainModule.maxParticles && particles.Length < MAX_PARTICLE_COUNT )
|
||||
System.Array.Resize( ref particles, Mathf.Min( cachedMainModule.maxParticles, MAX_PARTICLE_COUNT ) );
|
||||
|
||||
bool isLocalSpace = cachedMainModule.simulationSpace != ParticleSystemSimulationSpace.World;
|
||||
int aliveParticles = cachedPS.GetParticles( particles );
|
||||
|
||||
Vector3 initialPoint = spline.GetPoint( 0f );
|
||||
if( followMode == FollowMode.Relaxed )
|
||||
{
|
||||
if( particleData == null )
|
||||
particleData = new List<Vector4>( particles.Length );
|
||||
|
||||
cachedPS.GetCustomParticleData( particleData, ParticleSystemCustomData.Custom1 );
|
||||
|
||||
// Credit: https://forum.unity3d.com/threads/access-to-the-particle-system-lifecycle-events.328918/#post-2295977
|
||||
for( int i = 0; i < aliveParticles; i++ )
|
||||
{
|
||||
Vector4 particleDat = particleData[i];
|
||||
Vector3 point = spline.GetPoint( 1f - ( particles[i].remainingLifetime / particles[i].startLifetime ) );
|
||||
if( !isLocalSpace )
|
||||
point = cachedTransform.TransformPoint( point - initialPoint );
|
||||
|
||||
// Move particles alongside the spline
|
||||
if( particleDat.w != 0f )
|
||||
particles[i].position += point - (Vector3) particleDat;
|
||||
|
||||
particleDat = point;
|
||||
particleDat.w = 1f;
|
||||
particleData[i] = particleDat;
|
||||
}
|
||||
|
||||
cachedPS.SetCustomParticleData( particleData, ParticleSystemCustomData.Custom1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < aliveParticles; i++ )
|
||||
{
|
||||
Vector3 point = spline.GetPoint( 1f - ( particles[i].remainingLifetime / particles[i].startLifetime ) ) - initialPoint;
|
||||
if( !isLocalSpace )
|
||||
point = cachedTransform.TransformPoint( point );
|
||||
|
||||
particles[i].position = point;
|
||||
}
|
||||
}
|
||||
|
||||
cachedPS.SetParticles( particles, aliveParticles );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 954f54b0dafe0cf488e4e15934cae013
|
||||
timeCreated: 1510521621
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
|
@ -0,0 +1,96 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 55bb46a7614176b4c941a5caf846f7e8
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -534,6 +534,17 @@ AnimationClip:
|
|||
path: Holder/LowerTorso
|
||||
classID: 212
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
- time: 0
|
||||
value: {fileID: -4339478730206458095, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- time: 0.1
|
||||
value: {fileID: -4756013695868691969, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- time: 0.26666668
|
||||
value: {fileID: -4901794926734046506, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
attribute: m_Sprite
|
||||
path: Holder/Head
|
||||
classID: 212
|
||||
script: {fileID: 0}
|
||||
m_SampleRate: 60
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
|
@ -653,6 +664,13 @@ AnimationClip:
|
|||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
- serializedVersion: 2
|
||||
path: 862337961
|
||||
attribute: 0
|
||||
script: {fileID: 0}
|
||||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
pptrCurveMapping:
|
||||
- {fileID: 8448038167059441282, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -8827699967261475670, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
|
@ -688,6 +706,9 @@ AnimationClip:
|
|||
- {fileID: -1720273043946688001, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: 3897377649561355716, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -1720273043946688001, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4339478730206458095, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4756013695868691969, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4901794926734046506, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
|
|
|
@ -525,6 +525,17 @@ AnimationClip:
|
|||
path: Holder/LowerTorso
|
||||
classID: 212
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
- time: 0
|
||||
value: {fileID: -4339478730206458095, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- time: 0.1
|
||||
value: {fileID: -4756013695868691969, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- time: 0.26666668
|
||||
value: {fileID: -4901794926734046506, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
attribute: m_Sprite
|
||||
path: Holder/Head
|
||||
classID: 212
|
||||
script: {fileID: 0}
|
||||
m_SampleRate: 60
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
|
@ -637,6 +648,13 @@ AnimationClip:
|
|||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
- serializedVersion: 2
|
||||
path: 862337961
|
||||
attribute: 0
|
||||
script: {fileID: 0}
|
||||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
- serializedVersion: 2
|
||||
path: 354493626
|
||||
attribute: 1
|
||||
|
@ -679,6 +697,9 @@ AnimationClip:
|
|||
- {fileID: -1720273043946688001, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: 3897377649561355716, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -1720273043946688001, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4339478730206458095, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4756013695868691969, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -4901794926734046506, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
|
|
|
@ -404,6 +404,22 @@ AnimationClip:
|
|||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
path: Holder/LowerTorso
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: {x: -2.36, y: -1.87, z: 0}
|
||||
inSlope: {x: 0, y: 0, z: 0}
|
||||
outSlope: {x: 0, y: 0, z: 0}
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: {x: 0, y: 0.33333334, z: 0.33333334}
|
||||
outWeight: {x: 0, y: 0.33333334, z: 0.33333334}
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
path: Holder/toeFX
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves:
|
||||
- curve:
|
||||
|
@ -444,6 +460,34 @@ AnimationClip:
|
|||
path: Holder/RightArm/Hand
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- serializedVersion: 3
|
||||
time: 0.033333335
|
||||
value: 0
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_IsActive
|
||||
path: Holder/toeFX
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
m_PPtrCurves:
|
||||
- curve:
|
||||
- time: 0
|
||||
|
@ -655,6 +699,13 @@ AnimationClip:
|
|||
typeID: 1
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 3009155107
|
||||
attribute: 2086281974
|
||||
script: {fileID: 0}
|
||||
typeID: 1
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 2827832259
|
||||
attribute: 0
|
||||
|
@ -704,6 +755,13 @@ AnimationClip:
|
|||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
- serializedVersion: 2
|
||||
path: 3009155107
|
||||
attribute: 1
|
||||
script: {fileID: 0}
|
||||
typeID: 4
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
pptrCurveMapping:
|
||||
- {fileID: 21300000, guid: c5b59e91368953049893b676adf67b31, type: 3}
|
||||
- {fileID: 21300000, guid: 90f0b2f80c7edac43b09f918f1ff580b, type: 3}
|
||||
|
@ -2052,6 +2110,91 @@ AnimationClip:
|
|||
path: Holder/LowerTorso
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: -2.36
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.x
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: -1.87
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.y
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.z
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- serializedVersion: 3
|
||||
time: 0.033333335
|
||||
value: 0
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_IsActive
|
||||
path: Holder/toeFX
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
m_EulerEditorCurves:
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
|
|
|
@ -433,6 +433,22 @@ AnimationClip:
|
|||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
path: Holder/Torso
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: {x: -2.441, y: -1.702, z: 0}
|
||||
inSlope: {x: 0, y: 0, z: 0}
|
||||
outSlope: {x: 0, y: 0, z: 0}
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: {x: 0, y: 0.33333334, z: 0.33333334}
|
||||
outWeight: {x: 0, y: 0.33333334, z: 0.33333334}
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
path: Holder/toeFX
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves:
|
||||
- curve:
|
||||
|
@ -473,6 +489,34 @@ AnimationClip:
|
|||
path: Holder/RightArm/Hand
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- serializedVersion: 3
|
||||
time: 0.033333335
|
||||
value: 0
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_IsActive
|
||||
path: Holder/toeFX
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
m_PPtrCurves:
|
||||
- curve:
|
||||
- time: 0
|
||||
|
@ -679,6 +723,13 @@ AnimationClip:
|
|||
typeID: 1
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 3009155107
|
||||
attribute: 2086281974
|
||||
script: {fileID: 0}
|
||||
typeID: 1
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 862337961
|
||||
attribute: 0
|
||||
|
@ -728,6 +779,13 @@ AnimationClip:
|
|||
typeID: 212
|
||||
customType: 23
|
||||
isPPtrCurve: 1
|
||||
- serializedVersion: 2
|
||||
path: 3009155107
|
||||
attribute: 1
|
||||
script: {fileID: 0}
|
||||
typeID: 4
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
pptrCurveMapping:
|
||||
- {fileID: 1450434439674949499, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
- {fileID: -2516537432793170592, guid: ed47c3fa4e916ff478c0f1b6fb057aa4, type: 3}
|
||||
|
@ -2155,6 +2213,91 @@ AnimationClip:
|
|||
path: Holder/Torso
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: -2.441
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.x
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: -1.702
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.y
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_LocalPosition.z
|
||||
path: Holder/toeFX
|
||||
classID: 4
|
||||
script: {fileID: 0}
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- serializedVersion: 3
|
||||
time: 0.033333335
|
||||
value: 0
|
||||
inSlope: Infinity
|
||||
outSlope: Infinity
|
||||
tangentMode: 103
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_IsActive
|
||||
path: Holder/toeFX
|
||||
classID: 1
|
||||
script: {fileID: 0}
|
||||
m_EulerEditorCurves:
|
||||
- curve:
|
||||
serializedVersion: 2
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 452 KiB |
|
@ -7,10 +7,10 @@ TextureImporter:
|
|||
second: platform_0
|
||||
- first:
|
||||
213: -6047660829741247071
|
||||
second: platform_1
|
||||
second: kick_fx
|
||||
- first:
|
||||
213: -1664293819527379378
|
||||
second: platform_2
|
||||
second: toe_fx
|
||||
- first:
|
||||
213: -4901794926734046506
|
||||
second: kicker_head_0
|
||||
|
@ -206,7 +206,7 @@ TextureImporter:
|
|||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
|
@ -1452,6 +1452,48 @@ TextureImporter:
|
|||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: kick_fx
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 532
|
||||
y: 566
|
||||
width: 184
|
||||
height: 120
|
||||
alignment: 0
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 1a59a396484621ca0800000000000000
|
||||
internalID: -6047660829741247071
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: toe_fx
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 720
|
||||
y: 334
|
||||
width: 241
|
||||
height: 264
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: e464135c69d37e8e0800000000000000
|
||||
internalID: -1664293819527379378
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
|
|
|
@ -775,7 +775,7 @@ RectTransform:
|
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: -50, y: 0}
|
||||
m_AnchoredPosition: {x: -95, y: 0}
|
||||
m_SizeDelta: {x: 39.99997, y: 40}
|
||||
m_Pivot: {x: 1, y: 0.5}
|
||||
--- !u!114 &121871281
|
||||
|
@ -915,7 +915,7 @@ RectTransform:
|
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: -5, y: 0}
|
||||
m_AnchoredPosition: {x: -50, y: 0}
|
||||
m_SizeDelta: {x: 39.99997, y: 40}
|
||||
m_Pivot: {x: 1, y: 0.5}
|
||||
--- !u!114 &129013734
|
||||
|
@ -1000,6 +1000,139 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 129013732}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &151246936
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 151246937}
|
||||
- component: {fileID: 151246940}
|
||||
- component: {fileID: 151246939}
|
||||
- component: {fileID: 151246938}
|
||||
m_Layer: 5
|
||||
m_Name: FullscreenBTN
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &151246937
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 151246936}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1981150264}
|
||||
m_Father: {fileID: 1709317943}
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: -5, y: 0}
|
||||
m_SizeDelta: {x: 39.99997, y: 40}
|
||||
m_Pivot: {x: 1, y: 0.5}
|
||||
--- !u!114 &151246938
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 151246936}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 0
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.7490196, g: 1, b: 1, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 151246939}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1423699437}
|
||||
m_TargetAssemblyTypeName: RhythmHeavenMania.Editor.Editor, Assembly-CSharp
|
||||
m_MethodName: Fullscreen
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!114 &151246939
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 151246936}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 10
|
||||
--- !u!222 &151246940
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 151246936}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &151438063
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -9686,6 +9819,7 @@ MonoBehaviour:
|
|||
MusicSelectBTN: {fileID: 1055877579}
|
||||
EditorSettingsBTN: {fileID: 3236232}
|
||||
EditorThemeBTN: {fileID: 528192061}
|
||||
FullScreenBTN: {fileID: 151246938}
|
||||
--- !u!114 &1423699438
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -11116,6 +11250,7 @@ RectTransform:
|
|||
- {fileID: 1783491358}
|
||||
- {fileID: 121871280}
|
||||
- {fileID: 129013733}
|
||||
- {fileID: 151246937}
|
||||
m_Father: {fileID: 1110073995}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
@ -12655,6 +12790,81 @@ CanvasRenderer:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1964271230}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1981150263
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1981150264}
|
||||
- component: {fileID: 1981150266}
|
||||
- component: {fileID: 1981150265}
|
||||
m_Layer: 5
|
||||
m_Name: Graphic
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1981150264
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1981150263}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 151246937}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 40, y: 40}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1981150265
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1981150263}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.3254717, g: 1, b: 0.4334381, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 55bb46a7614176b4c941a5caf846f7e8, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &1981150266
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1981150263}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1997273392
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -13047,8 +13257,7 @@ GameObject:
|
|||
- component: {fileID: 2047408676}
|
||||
- component: {fileID: 2047408675}
|
||||
- component: {fileID: 2047408674}
|
||||
- component: {fileID: 2047408677}
|
||||
- component: {fileID: 2047408678}
|
||||
- component: {fileID: 2047408679}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
|
@ -13121,7 +13330,7 @@ Transform:
|
|||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2047408677
|
||||
--- !u!114 &2047408679
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
|
@ -13130,21 +13339,30 @@ MonoBehaviour:
|
|||
m_GameObject: {fileID: 2047408673}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a66fbd5ffe9b9d64da304996f1919f40, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &2047408678
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2047408673}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e55bddfe16e69224c8c4b4eb165695d4, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_RenderShadows: 1
|
||||
m_RequiresDepthTextureOption: 2
|
||||
m_RequiresOpaqueTextureOption: 2
|
||||
m_CameraType: 0
|
||||
m_Cameras: []
|
||||
m_RendererIndex: -1
|
||||
m_VolumeLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 1
|
||||
m_VolumeTrigger: {fileID: 0}
|
||||
m_VolumeFrameworkUpdateModeOption: 2
|
||||
m_RenderPostProcessing: 0
|
||||
m_Antialiasing: 0
|
||||
m_AntialiasingQuality: 2
|
||||
m_StopNaN: 0
|
||||
m_Dithering: 0
|
||||
m_ClearDepth: 1
|
||||
m_AllowXRRendering: 1
|
||||
m_RequiresDepthTexture: 0
|
||||
m_RequiresColorTexture: 0
|
||||
m_Version: 2
|
||||
--- !u!1 &2051557110
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -51,13 +51,13 @@ namespace RhythmHeavenMania
|
|||
|
||||
public void Init()
|
||||
{
|
||||
this.transform.localScale = new Vector3(3000, 3000);
|
||||
this.transform.localScale = new Vector3(30000000, 30000000);
|
||||
SpriteRenderer sp = this.gameObject.AddComponent<SpriteRenderer>();
|
||||
sp.enabled = false;
|
||||
sp.color = Color.black;
|
||||
sp.sprite = Resources.Load<Sprite>("Sprites/GeneralPurpose/Square");
|
||||
sp.sortingOrder = 30000;
|
||||
this.gameObject.layer = 3;
|
||||
// this.gameObject.layer = 3;
|
||||
|
||||
if (txt != null)
|
||||
{
|
||||
|
|
|
@ -27,14 +27,15 @@ namespace RhythmHeavenMania.Games
|
|||
autoPlayEnabledOnStart = GameManager.instance.autoplay;
|
||||
}
|
||||
|
||||
private void CheckForAce(float normalizedBeat)
|
||||
private void CheckForAce(float normalizedBeat, bool autoPlay = false)
|
||||
{
|
||||
if (aceTimes == 0)
|
||||
{
|
||||
if (GameManager.instance.autoplay && normalizedBeat > 0.99f)
|
||||
if (GameManager.instance.autoplay && normalizedBeat > 0.99f || autoPlay && normalizedBeat > 0.99f)
|
||||
{
|
||||
OnAce();
|
||||
AceVisuals();
|
||||
if (!autoPlay)
|
||||
AceVisuals();
|
||||
// aceTimes++;
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +53,9 @@ namespace RhythmHeavenMania.Games
|
|||
}
|
||||
|
||||
// could possibly add support for custom early, perfect, and end times if needed.
|
||||
public void StateCheck(float normalizedBeat)
|
||||
public void StateCheck(float normalizedBeat, bool autoPlay = false)
|
||||
{
|
||||
CheckForAce(normalizedBeat);
|
||||
CheckForAce(normalizedBeat, autoPlay);
|
||||
if (normalizedBeat > Minigame.EarlyTime() && normalizedBeat < Minigame.PerfectTime() && lastState == 0)
|
||||
{
|
||||
MakeEligible(true, false, false);
|
||||
|
|
|
@ -10,9 +10,10 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
public class Ball : MonoBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private Kicker kicker;
|
||||
[HideInInspector] public Kicker kicker;
|
||||
[SerializeField] private GameObject holder;
|
||||
[SerializeField] private GameObject spriteHolder;
|
||||
[SerializeField] private GameObject kickFX;
|
||||
[Space(10)]
|
||||
[SerializeField] private BezierCurve3D dispenseCurve;
|
||||
[SerializeField] private BezierCurve3D kickCurve;
|
||||
|
@ -30,8 +31,13 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
public GameEvent toe = new GameEvent();
|
||||
private bool lastKickLeft;
|
||||
|
||||
public void Kick()
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
|
||||
public void Kick(bool player)
|
||||
{
|
||||
if (player)
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/ballHit");
|
||||
|
||||
lastSpriteRot = spriteHolder.transform.eulerAngles.z;
|
||||
|
@ -54,6 +60,8 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
kickCurve.transform.localScale = new Vector3(1, 1);
|
||||
}
|
||||
kickCurve.KeyPoints[0].transform.position = holder.transform.position;
|
||||
|
||||
HitFX();
|
||||
}
|
||||
|
||||
public void HighKick()
|
||||
|
@ -68,6 +76,9 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
highKicked.startBeat = Conductor.instance.songPositionInBeats;
|
||||
|
||||
highKickCurve.KeyPoints[0].transform.position = holder.transform.position;
|
||||
|
||||
|
||||
HitFX();
|
||||
}
|
||||
|
||||
public void Toe()
|
||||
|
@ -91,6 +102,9 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
{
|
||||
toeCurve.KeyPoints[1].transform.localPosition = new Vector3(6.49f, 0);
|
||||
}
|
||||
|
||||
|
||||
HitFX();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
@ -98,6 +112,10 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
if (dispensing)
|
||||
{
|
||||
float normalizedBeatAnim = Conductor.instance.GetLoopPositionFromBeat(dispensedBeat, 2.35f);
|
||||
|
||||
dispenseCurve.KeyPoints[0].transform.position = new Vector3(kicker.transform.position.x - 6f, kicker.transform.position.y - 6f);
|
||||
dispenseCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x - 1f, kicker.transform.position.y - 6f);
|
||||
|
||||
holder.transform.localPosition = dispenseCurve.GetPoint(normalizedBeatAnim);
|
||||
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(0f, -1440f, normalizedBeatAnim));
|
||||
|
||||
|
@ -112,16 +130,20 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
else if (kicked.enabled)
|
||||
{
|
||||
float normalizedBeatAnim = Conductor.instance.GetLoopPositionFromBeat(kicked.startBeat, 1.5f);
|
||||
holder.transform.localPosition = kickCurve.GetPoint(normalizedBeatAnim);
|
||||
|
||||
if (!lastKickLeft)
|
||||
{
|
||||
kickCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x + 0.5f, kicker.transform.position.y - 6f);
|
||||
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, lastSpriteRot - 360f, normalizedBeatAnim));
|
||||
}
|
||||
else
|
||||
{
|
||||
kickCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x - 2.5f, kicker.transform.position.y - 6f);
|
||||
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, lastSpriteRot + 360f, normalizedBeatAnim));
|
||||
}
|
||||
|
||||
holder.transform.localPosition = kickCurve.GetPoint(normalizedBeatAnim);
|
||||
|
||||
/*if (PlayerInput.Pressed())
|
||||
{
|
||||
if (state.perfect)
|
||||
|
@ -141,6 +163,9 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
else if (highKicked.enabled)
|
||||
{
|
||||
float normalizedBeatAnim = Conductor.instance.GetLoopPositionFromBeat(highKicked.startBeat, 1.8f);
|
||||
|
||||
highKickCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x - 3.5f, kicker.transform.position.y - 6f);
|
||||
|
||||
holder.transform.localPosition = highKickCurve.GetPoint(normalizedBeatAnim);
|
||||
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, lastSpriteRot + 360f, normalizedBeatAnim));
|
||||
|
||||
|
@ -165,9 +190,28 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
else if (toe.enabled)
|
||||
{
|
||||
float normalizedBeatAnim = Conductor.instance.GetLoopPositionFromBeat(toe.startBeat, 1.85f);
|
||||
|
||||
if (!lastKickLeft)
|
||||
{
|
||||
toeCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x + 0.5f, kicker.transform.position.y - 6f);
|
||||
}
|
||||
else
|
||||
{
|
||||
toeCurve.KeyPoints[1].transform.position = new Vector3(kicker.transform.position.x - 0.7f, kicker.transform.position.y - 6f);
|
||||
}
|
||||
|
||||
holder.transform.localPosition = toeCurve.GetPoint(normalizedBeatAnim);
|
||||
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, -860f, normalizedBeatAnim));
|
||||
}
|
||||
|
||||
holder.transform.position = new Vector3(holder.transform.position.x, holder.transform.position.y, kicker.transform.localPosition.z);
|
||||
}
|
||||
|
||||
private void HitFX()
|
||||
{
|
||||
GameObject kickfx = Instantiate(kickFX.gameObject, SpaceSoccer.instance.transform);
|
||||
kickfx.SetActive(true);
|
||||
kickfx.transform.position = holder.transform.position;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,14 +15,27 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
public bool kickLeft;
|
||||
public float dispenserBeat;
|
||||
public int kickTimes = 0;
|
||||
public bool player;
|
||||
|
||||
[Header("Components")]
|
||||
private Animator anim;
|
||||
public Ball ball;
|
||||
public Transform rightLeg;
|
||||
public Transform leftLeg;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
anim = GetComponent<Animator>();
|
||||
GameObject rightLeg = new GameObject();
|
||||
rightLeg.transform.SetParent(this.transform);
|
||||
rightLeg.transform.position = new Vector3(-0.67f, -1.48f);
|
||||
|
||||
GameObject leftLeg = new GameObject("leftLeg");
|
||||
leftLeg.transform.SetParent(this.transform);
|
||||
leftLeg.transform.position = new Vector3(0f, -1.48f);
|
||||
|
||||
this.rightLeg = rightLeg.transform;
|
||||
this.leftLeg = leftLeg.transform;
|
||||
}
|
||||
|
||||
public override void OnAce()
|
||||
|
@ -56,7 +69,8 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
kickTimes++;
|
||||
aceTimes = 0;
|
||||
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/kick");
|
||||
if (player)
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/kick");
|
||||
|
||||
if (highKick)
|
||||
{
|
||||
|
@ -86,7 +100,7 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
if (highKick == false)
|
||||
{
|
||||
if (ball != null && hit)
|
||||
ball.Kick();
|
||||
ball.Kick(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -109,14 +123,17 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
anim.Play("HighKickRight_0", 0, 0);
|
||||
}
|
||||
|
||||
if (ball && hit)
|
||||
if (hit && ball)
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1_hit");
|
||||
ball.HighKick();
|
||||
|
||||
if (player)
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1_hit");
|
||||
}
|
||||
else
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1");
|
||||
if (player)
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1");
|
||||
}
|
||||
|
||||
ResetState();
|
||||
|
@ -133,15 +150,20 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
anim.Play("ToeRight", 0, 0);
|
||||
}
|
||||
|
||||
if (player)
|
||||
{
|
||||
if (hit && ball)
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe3_hit");
|
||||
}
|
||||
else
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe3");
|
||||
}
|
||||
}
|
||||
|
||||
if (hit && ball)
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe3_hit");
|
||||
ball.Toe();
|
||||
}
|
||||
else
|
||||
{
|
||||
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe3");
|
||||
}
|
||||
|
||||
kickPrepare = false;
|
||||
ResetState();
|
||||
|
@ -149,7 +171,6 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
|
||||
private void Update()
|
||||
{
|
||||
|
||||
if (kickTimes % 2 == 0)
|
||||
{
|
||||
kickLeft = false;
|
||||
|
@ -193,36 +214,42 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
if (ball.dispensing)
|
||||
{
|
||||
float normalizedBeat = Conductor.instance.GetLoopPositionFromBeat(ball.dispensedBeat, 2f);
|
||||
StateCheck(normalizedBeat);
|
||||
StateCheck(normalizedBeat, !player);
|
||||
CheckIfFall(normalizedBeat);
|
||||
|
||||
if (PlayerInput.Pressed())
|
||||
if (player)
|
||||
{
|
||||
if (state.perfect)
|
||||
if (PlayerInput.Pressed())
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
if (state.perfect)
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ball.kicked.enabled)
|
||||
{
|
||||
float normalizedBeat = Conductor.instance.GetLoopPositionFromBeat(ball.kicked.startBeat, 1f);
|
||||
StateCheck(normalizedBeat);
|
||||
StateCheck(normalizedBeat, !player);
|
||||
CheckIfFall(normalizedBeat);
|
||||
|
||||
if (PlayerInput.Pressed())
|
||||
if (player)
|
||||
{
|
||||
if (state.perfect)
|
||||
if (PlayerInput.Pressed())
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
if (state.perfect)
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,28 +259,34 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
if (!kickPrepare)
|
||||
{
|
||||
float normalizedBeatPrepare = Conductor.instance.GetLoopPositionFromBeat(ball.highKicked.startBeat, 1f);
|
||||
StateCheck(normalizedBeatPrepare);
|
||||
StateCheck(normalizedBeatPrepare, !player);
|
||||
CheckIfFall(normalizedBeat);
|
||||
|
||||
if (PlayerInput.AltPressed())
|
||||
if (player)
|
||||
{
|
||||
Kick(false, true);
|
||||
if (PlayerInput.AltPressed())
|
||||
{
|
||||
Kick(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StateCheck(normalizedBeat);
|
||||
StateCheck(normalizedBeat, !player);
|
||||
CheckIfFall(normalizedBeat);
|
||||
|
||||
if (PlayerInput.AltPressedUp())
|
||||
if (player)
|
||||
{
|
||||
if (state.perfect)
|
||||
if (PlayerInput.AltPressedUp())
|
||||
{
|
||||
Toe(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toe(false);
|
||||
if (state.perfect)
|
||||
{
|
||||
Toe(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toe(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,27 +294,33 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
else if (ball.toe.enabled)
|
||||
{
|
||||
float normalizedBeat = Conductor.instance.GetLoopPositionFromBeat(ball.toe.startBeat, 1.5f);
|
||||
StateCheck(normalizedBeat);
|
||||
StateCheck(normalizedBeat, !player);
|
||||
CheckIfFall(normalizedBeat);
|
||||
|
||||
if (PlayerInput.Pressed())
|
||||
if (player)
|
||||
{
|
||||
if (state.perfect)
|
||||
if (PlayerInput.Pressed())
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
if (state.perfect)
|
||||
{
|
||||
KickCheck(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
KickCheck(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PlayerInput.Pressed())
|
||||
if (player)
|
||||
{
|
||||
KickCheck(false, true);
|
||||
if (PlayerInput.Pressed())
|
||||
{
|
||||
KickCheck(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private GameObject ballRef;
|
||||
[SerializeField] private Kicker kicker;
|
||||
[SerializeField] private List<Kicker> kickers;
|
||||
[SerializeField] private GameObject Background;
|
||||
[SerializeField] private Sprite[] backgroundSprite;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
|
||||
private void Start()
|
||||
{
|
||||
for (int x = 0; x < Random.Range(9, 12); x++)
|
||||
/*for (int x = 0; x < Random.Range(9, 12); x++)
|
||||
{
|
||||
for (int y = 0; y < Random.Range(6, 9); y++)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
test.transform.localPosition = new Vector3(Random.Range(-15f, 15f), Random.Range(-15f, 15f));
|
||||
test.transform.localScale = new Vector3(0.52f, 0.52f);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
@ -45,22 +45,27 @@ namespace RhythmHeavenMania.Games.SpaceSoccer
|
|||
if (ballDispensed)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Dispense(float beat)
|
||||
{
|
||||
if (kicker.ball != null) return;
|
||||
ballDispensed = true;
|
||||
for (int i = 0; i < kickers.Count; i++)
|
||||
{
|
||||
Kicker kicker = kickers[i];
|
||||
if (i == 0) kicker.player = true;
|
||||
|
||||
GameObject ball = Instantiate(ballRef, this.transform);
|
||||
Ball ball_ = ball.GetComponent<Ball>();
|
||||
ball_.dispensedBeat = beat;
|
||||
ball_.dispensing = true;
|
||||
kicker.ball = ball_;
|
||||
kicker.dispenserBeat = beat;
|
||||
kicker.kickTimes = 0;
|
||||
if (kicker.ball != null) return;
|
||||
ballDispensed = true;
|
||||
|
||||
GameObject ball = Instantiate(ballRef, transform);
|
||||
Ball ball_ = ball.GetComponent<Ball>();
|
||||
ball_.kicker = kicker;
|
||||
ball_.dispensedBeat = beat;
|
||||
ball_.dispensing = true;
|
||||
kicker.ball = ball_;
|
||||
kicker.dispenserBeat = beat;
|
||||
kicker.kickTimes = 0;
|
||||
}
|
||||
|
||||
MultiSound.Play(new MultiSound.Sound[]
|
||||
{
|
||||
|
|
|
@ -46,11 +46,13 @@ namespace RhythmHeavenMania.Editor
|
|||
[SerializeField] private Button MusicSelectBTN;
|
||||
[SerializeField] private Button EditorSettingsBTN;
|
||||
[SerializeField] private Button EditorThemeBTN;
|
||||
[SerializeField] private Button FullScreenBTN;
|
||||
|
||||
[Header("Properties")]
|
||||
private bool changedMusic = false;
|
||||
private string currentRemixPath = "";
|
||||
private int lastEditorObjectsCount = 0;
|
||||
private bool fullscreen;
|
||||
|
||||
public static Editor instance { get; private set; }
|
||||
|
||||
|
@ -85,6 +87,7 @@ namespace RhythmHeavenMania.Editor
|
|||
Tooltip.AddTooltip(MusicSelectBTN.gameObject, "Music Select");
|
||||
Tooltip.AddTooltip(EditorSettingsBTN.gameObject, "Editor Settings <color=#adadad>[Ctrl+Shift+O]</color>");
|
||||
Tooltip.AddTooltip(EditorThemeBTN.gameObject, "Editor Theme");
|
||||
Tooltip.AddTooltip(FullScreenBTN.gameObject, "Preview <color=#adadad>[Tab]</color>");
|
||||
|
||||
UpdateEditorStatus(true);
|
||||
}
|
||||
|
@ -105,6 +108,11 @@ namespace RhythmHeavenMania.Editor
|
|||
GetComponent<BoxSelection>().enabled = true;
|
||||
}*/
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
Fullscreen();
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Delete))
|
||||
{
|
||||
List<TimelineEventObj> ev = new List<TimelineEventObj>();
|
||||
|
@ -368,6 +376,25 @@ namespace RhythmHeavenMania.Editor
|
|||
|
||||
#endregion
|
||||
|
||||
public void Fullscreen()
|
||||
{
|
||||
if (fullscreen == false)
|
||||
{
|
||||
MainCanvas.enabled = false;
|
||||
EditorCamera.enabled = false;
|
||||
GameManager.instance.GameCamera.targetTexture = null;
|
||||
// GameManager.instance.GameCamera.transform.parent.GetChild(1).GetComponent<Camera>().enabled = false;
|
||||
fullscreen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MainCanvas.enabled = true;
|
||||
EditorCamera.enabled = true;
|
||||
GameManager.instance.GameCamera.targetTexture = ScreenRenderTexture;
|
||||
// GameManager.instance.GameCamera.transform.parent.GetChild(1).GetComponent<Camera>().enabled = true;
|
||||
fullscreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEditorStatus(bool updateTime)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ GraphicsSettings:
|
|||
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_PreloadedShaders: []
|
||||
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_CustomRenderPipeline: {fileID: 11400000, guid: 101cb6f0eda36514fa0bb49e41c8fae1, type: 2}
|
||||
m_CustomRenderPipeline: {fileID: 0}
|
||||
m_TransparencySortMode: 0
|
||||
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
|
||||
m_DefaultRenderingPath: 1
|
||||
|
|
Loading…
Reference in New Issue