419 lines
16 KiB
C#
419 lines
16 KiB
C#
|
using UnityEngine;
|
|||
|
|
|||
|
|
|||
|
namespace AmazingAssets.CurvedWorld
|
|||
|
{
|
|||
|
public enum BEND_TYPE
|
|||
|
{
|
|||
|
ClassicRunner_X_Positive = 0, ClassicRunner_X_Negative, ClassicRunner_Z_Positive, ClassicRunner_Z_Negative,
|
|||
|
LittlePlanet_X, LittlePlanet_Y, LittlePlanet_Z,
|
|||
|
CylindricalTower_X, CylindricalTower_Z,
|
|||
|
CylindricalRolloff_X, CylindricalRolloff_Z,
|
|||
|
|
|||
|
SpiralHorizontal_X_Positive, SpiralHorizontal_X_Negative, SpiralHorizontal_Z_Positive, SpiralHorizontal_Z_Negative,
|
|||
|
SpiralHorizontalDouble_X, SpiralHorizontalDouble_Z,
|
|||
|
SpiralHorizontalRolloff_X, SpiralHorizontalRolloff_Z,
|
|||
|
|
|||
|
SpiralVertical_X_Positive, SpiralVertical_X_Negative, SpiralVertical_Z_Positive, SpiralVertical_Z_Negative,
|
|||
|
SpiralVerticalDouble_X, SpiralVerticalDouble_Z,
|
|||
|
SpiralVerticalRolloff_X, SpiralVerticalRolloff_Z,
|
|||
|
|
|||
|
TwistedSpiral_X_Positive, TwistedSpiral_X_Negative, TwistedSpiral_Z_Positive, TwistedSpiral_Z_Negative,
|
|||
|
};
|
|||
|
|
|||
|
[ExecuteAlways]
|
|||
|
public class CurvedWorldController : MonoBehaviour
|
|||
|
{
|
|||
|
public enum AXIS_TYPE { Transform, Custom, CustomNormalized }
|
|||
|
|
|||
|
public BEND_TYPE bendType;
|
|||
|
[Range(1, 32)]
|
|||
|
public int bendID = 1;
|
|||
|
|
|||
|
public Transform bendPivotPoint; public Vector3 bendPivotPointPosition;
|
|||
|
public Transform bendRotationCenter; public Vector3 bendRotationCenterPosition; public Vector3 bendRotationAxis; public AXIS_TYPE bendRotationAxisType;
|
|||
|
public Transform bendRotationCenter2; public Vector3 bendRotationCenter2Position;
|
|||
|
|
|||
|
|
|||
|
public float bendVerticalSize, bendVerticalOffset;
|
|||
|
public float bendHorizontalSize, bendHorizontalOffset;
|
|||
|
public float bendCurvatureSize, bendCurvatureOffset;
|
|||
|
|
|||
|
public float bendAngle;
|
|||
|
public float bendAngle2;
|
|||
|
public float bendMinimumRadius;
|
|||
|
public float bendMinimumRadius2;
|
|||
|
public float bendRolloff;
|
|||
|
|
|||
|
public bool disableInEditor = false;
|
|||
|
public bool manualUpdate = false;
|
|||
|
|
|||
|
|
|||
|
BEND_TYPE previousBentType;
|
|||
|
int previousID;
|
|||
|
|
|||
|
int materialPropertyID_PivotPoint;
|
|||
|
int materialPropertyID_RotationCenter;
|
|||
|
int materialPropertyID_RotationCenter2;
|
|||
|
int materialPropertyID_RotationAxis;
|
|||
|
int materialPropertyID_BendSize;
|
|||
|
int materialPropertyID_BendOffset;
|
|||
|
int materialPropertyID_BendAngle;
|
|||
|
int materialPropertyID_BendMinimumRadius;
|
|||
|
int materialPropertyID_BendRolloff;
|
|||
|
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
public bool isExpanded = true;
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void OnDisable()
|
|||
|
{
|
|||
|
DisableBend();
|
|||
|
}
|
|||
|
|
|||
|
void OnDestroy()
|
|||
|
{
|
|||
|
DisableBend();
|
|||
|
}
|
|||
|
|
|||
|
void OnEnable()
|
|||
|
{
|
|||
|
EnableBend();
|
|||
|
}
|
|||
|
|
|||
|
void Start()
|
|||
|
{
|
|||
|
GenerateShaderPropertyIDs();
|
|||
|
}
|
|||
|
|
|||
|
void Update()
|
|||
|
{
|
|||
|
if (manualUpdate)
|
|||
|
return;
|
|||
|
|
|||
|
UpdateShaderdata();
|
|||
|
}
|
|||
|
|
|||
|
private void OnDrawGizmos()
|
|||
|
{
|
|||
|
Gizmos.color = Color.yellow;
|
|||
|
switch (bendType)
|
|||
|
{
|
|||
|
case BEND_TYPE.TwistedSpiral_X_Positive:
|
|||
|
case BEND_TYPE.TwistedSpiral_X_Negative:
|
|||
|
case BEND_TYPE.TwistedSpiral_Z_Positive:
|
|||
|
case BEND_TYPE.TwistedSpiral_Z_Negative:
|
|||
|
{
|
|||
|
Gizmos.DrawRay(bendPivotPointPosition, bendRotationAxis.normalized * 10);
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void UpdateShaderdata()
|
|||
|
{
|
|||
|
CheckBendChanging();
|
|||
|
|
|||
|
|
|||
|
if (isActiveAndEnabled == true)
|
|||
|
{
|
|||
|
if (disableInEditor && Application.isEditor && Application.isPlaying == false)
|
|||
|
{
|
|||
|
UpdateShaderDataDisabled();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bendPivotPoint != null)
|
|||
|
bendPivotPointPosition = bendPivotPoint.transform.position;
|
|||
|
|
|||
|
if (bendRotationCenter != null)
|
|||
|
bendRotationCenterPosition = bendRotationCenter.position;
|
|||
|
|
|||
|
if (bendRotationCenter2 != null)
|
|||
|
bendRotationCenter2Position = bendRotationCenter2.position;
|
|||
|
|
|||
|
|
|||
|
switch (bendType)
|
|||
|
{
|
|||
|
case BEND_TYPE.ClassicRunner_X_Positive:
|
|||
|
case BEND_TYPE.ClassicRunner_X_Negative:
|
|||
|
case BEND_TYPE.ClassicRunner_Z_Positive:
|
|||
|
case BEND_TYPE.ClassicRunner_Z_Negative:
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendSize, new Vector2(bendVerticalSize, bendHorizontalSize));
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendOffset, new Vector2(bendVerticalOffset, bendHorizontalOffset));
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BEND_TYPE.LittlePlanet_X:
|
|||
|
case BEND_TYPE.LittlePlanet_Y:
|
|||
|
case BEND_TYPE.LittlePlanet_Z:
|
|||
|
case BEND_TYPE.CylindricalTower_X:
|
|||
|
case BEND_TYPE.CylindricalTower_Z:
|
|||
|
case BEND_TYPE.CylindricalRolloff_X:
|
|||
|
case BEND_TYPE.CylindricalRolloff_Z:
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendSize, bendCurvatureSize);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendOffset, bendCurvatureOffset);
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BEND_TYPE.SpiralHorizontal_X_Positive:
|
|||
|
case BEND_TYPE.SpiralHorizontal_X_Negative:
|
|||
|
case BEND_TYPE.SpiralHorizontal_Z_Positive:
|
|||
|
case BEND_TYPE.SpiralHorizontal_Z_Negative:
|
|||
|
case BEND_TYPE.SpiralVertical_X_Positive:
|
|||
|
case BEND_TYPE.SpiralVertical_X_Negative:
|
|||
|
case BEND_TYPE.SpiralVertical_Z_Positive:
|
|||
|
case BEND_TYPE.SpiralVertical_Z_Negative:
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter, bendRotationCenterPosition);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendAngle, bendAngle);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendMinimumRadius, bendMinimumRadius);
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BEND_TYPE.SpiralHorizontalDouble_X:
|
|||
|
case BEND_TYPE.SpiralHorizontalDouble_Z:
|
|||
|
case BEND_TYPE.SpiralVerticalDouble_X:
|
|||
|
case BEND_TYPE.SpiralVerticalDouble_Z:
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter, bendRotationCenterPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter2, bendRotationCenter2Position);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendAngle, new Vector2(bendAngle, bendAngle2));
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendMinimumRadius, new Vector2(bendMinimumRadius, bendMinimumRadius2));
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BEND_TYPE.SpiralHorizontalRolloff_X:
|
|||
|
case BEND_TYPE.SpiralHorizontalRolloff_Z:
|
|||
|
case BEND_TYPE.SpiralVerticalRolloff_X:
|
|||
|
case BEND_TYPE.SpiralVerticalRolloff_Z:
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter, bendRotationCenterPosition);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendAngle, bendAngle);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendMinimumRadius, bendMinimumRadius);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendRolloff, bendRolloff);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BEND_TYPE.TwistedSpiral_X_Positive:
|
|||
|
case BEND_TYPE.TwistedSpiral_X_Negative:
|
|||
|
case BEND_TYPE.TwistedSpiral_Z_Positive:
|
|||
|
case BEND_TYPE.TwistedSpiral_Z_Negative:
|
|||
|
{
|
|||
|
switch (bendRotationAxisType)
|
|||
|
{
|
|||
|
case AXIS_TYPE.Transform:
|
|||
|
{
|
|||
|
if (bendPivotPoint == null)
|
|||
|
{
|
|||
|
switch (bendType)
|
|||
|
{
|
|||
|
case BEND_TYPE.ClassicRunner_X_Positive: bendRotationAxis = Vector3.left; break;
|
|||
|
case BEND_TYPE.ClassicRunner_X_Negative: bendRotationAxis = Vector3.right; break;
|
|||
|
case BEND_TYPE.ClassicRunner_Z_Positive: bendRotationAxis = Vector3.back; break;
|
|||
|
case BEND_TYPE.ClassicRunner_Z_Negative: bendRotationAxis = Vector3.forward; break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bendRotationAxis = bendPivotPoint.forward;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case AXIS_TYPE.Custom:
|
|||
|
break;
|
|||
|
|
|||
|
case AXIS_TYPE.CustomNormalized:
|
|||
|
bendRotationAxis = bendRotationAxis.normalized;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, bendPivotPointPosition);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationAxis, bendRotationAxis);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendSize, new Vector3(bendCurvatureSize, bendVerticalSize, bendHorizontalSize));
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendOffset, new Vector3(bendCurvatureOffset, bendVerticalOffset, bendHorizontalOffset));
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void UpdateShaderDataDisabled()
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(materialPropertyID_PivotPoint, Vector3.zero);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter, Vector3.zero);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationCenter2, Vector3.zero);
|
|||
|
Shader.SetGlobalVector(materialPropertyID_RotationAxis, Vector3.zero);
|
|||
|
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendSize, Vector3.zero);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendSize, 0);
|
|||
|
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendOffset, Vector3.zero);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendOffset, 0);
|
|||
|
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendAngle, Vector2.zero);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendAngle, 0);
|
|||
|
|
|||
|
Shader.SetGlobalVector(materialPropertyID_BendMinimumRadius, Vector2.zero);
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendMinimumRadius, 0);
|
|||
|
|
|||
|
Shader.SetGlobalFloat(materialPropertyID_BendRolloff, 10);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void DisableBend()
|
|||
|
{
|
|||
|
GenerateShaderPropertyIDs();
|
|||
|
|
|||
|
UpdateShaderDataDisabled();
|
|||
|
}
|
|||
|
|
|||
|
public void EnableBend()
|
|||
|
{
|
|||
|
GenerateShaderPropertyIDs();
|
|||
|
|
|||
|
|
|||
|
previousBentType = bendType;
|
|||
|
previousID = bendID;
|
|||
|
|
|||
|
UpdateShaderdata();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void ManualUpdate()
|
|||
|
{
|
|||
|
UpdateShaderdata();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void CheckBendChanging()
|
|||
|
{
|
|||
|
if (previousBentType != bendType || previousID != bendID)
|
|||
|
{
|
|||
|
DisableBend();
|
|||
|
|
|||
|
|
|||
|
previousBentType = bendType;
|
|||
|
|
|||
|
if (bendID < 1) bendID = 1;
|
|||
|
previousID = bendID;
|
|||
|
|
|||
|
|
|||
|
GenerateShaderPropertyIDs();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void GenerateShaderPropertyIDs()
|
|||
|
{
|
|||
|
materialPropertyID_PivotPoint = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_PivotPoint", bendType, bendID));
|
|||
|
materialPropertyID_RotationCenter = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_RotationCenter", bendType, bendID));
|
|||
|
materialPropertyID_RotationCenter2 = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_RotationCenter2", bendType, bendID));
|
|||
|
materialPropertyID_RotationAxis = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_RotationAxis", bendType, bendID));
|
|||
|
materialPropertyID_BendSize = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_BendSize", bendType, bendID));
|
|||
|
materialPropertyID_BendOffset = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_BendOffset", bendType, bendID));
|
|||
|
materialPropertyID_BendAngle = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_BendAngle", bendType, bendID));
|
|||
|
materialPropertyID_BendMinimumRadius = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_BendMinimumRadius", bendType, bendID));
|
|||
|
materialPropertyID_BendRolloff = Shader.PropertyToID(string.Format("CurvedWorld_{0}_ID{1}_BendRolloff", bendType, bendID));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public Vector3 TransformPosition(Vector3 vertex)
|
|||
|
{
|
|||
|
if (enabled == false || gameObject.activeSelf == false)
|
|||
|
return vertex;
|
|||
|
else
|
|||
|
return CurvedWorldUtilities.TransformPosition(vertex, this);
|
|||
|
}
|
|||
|
|
|||
|
public Quaternion TransformRotation(Vector3 vertex, Vector3 forwardVector, Vector3 rightVector)
|
|||
|
{
|
|||
|
Vector3 p0 = TransformPosition(vertex);
|
|||
|
Vector3 p1 = TransformPosition(vertex + forwardVector);
|
|||
|
Vector3 p2 = TransformPosition(vertex + rightVector);
|
|||
|
|
|||
|
|
|||
|
Vector3 forward = Vector3.Normalize(p1 - p0);
|
|||
|
Vector3 right = Vector3.Normalize(p2 - p0);
|
|||
|
Vector3 up = Vector3.Cross(forward, right);
|
|||
|
|
|||
|
if (forward.sqrMagnitude < 0.01f && up.sqrMagnitude < 0.01f)
|
|||
|
return Quaternion.identity;
|
|||
|
else
|
|||
|
return Quaternion.LookRotation(forward, up);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void SetBendVerticalSize(float value)
|
|||
|
{
|
|||
|
bendVerticalSize = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendVerticalOffset(float value)
|
|||
|
{
|
|||
|
bendVerticalOffset = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendHorizontalSize(float value)
|
|||
|
{
|
|||
|
bendHorizontalSize = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendHorizontalOffset(float value)
|
|||
|
{
|
|||
|
bendHorizontalOffset = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendCurvatureSize(float value)
|
|||
|
{
|
|||
|
bendCurvatureSize = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendCurvatureOffset(float value)
|
|||
|
{
|
|||
|
bendCurvatureOffset = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendAngle(float value)
|
|||
|
{
|
|||
|
bendAngle = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendAngle2(float value)
|
|||
|
{
|
|||
|
bendAngle2 = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendMinimumRadius(float value)
|
|||
|
{
|
|||
|
bendMinimumRadius = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendMinimumRadius2(float value)
|
|||
|
{
|
|||
|
bendMinimumRadius2 = value;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBendRolloff(float value)
|
|||
|
{
|
|||
|
bendRolloff = value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|