1502 lines
51 KiB
C#
1502 lines
51 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace PhysicsTools
|
|
{
|
|
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
|
public class Rope : MonoBehaviour
|
|
{
|
|
public enum RopeGameplayType
|
|
{
|
|
NORMAL = 0,
|
|
ICE = 1,
|
|
FLOAT = 2
|
|
}
|
|
|
|
[Serializable]
|
|
public enum LOGGING
|
|
{
|
|
NONE = 0,
|
|
INFO = 1,
|
|
DEBUG = 2
|
|
}
|
|
|
|
[Serializable]
|
|
public enum RopeType
|
|
{
|
|
Procedural = 0,
|
|
FromBones = 1
|
|
}
|
|
|
|
[Serializable]
|
|
public enum RendererType
|
|
{
|
|
None = 0,
|
|
Continuous = 1,
|
|
Segment = 2
|
|
}
|
|
|
|
public delegate void BrokenHandler(object sender);
|
|
|
|
public delegate void CreateHandler(object sender);
|
|
|
|
public delegate void DeleteHandler(object sender);
|
|
|
|
public RopeGameplayType ropeGameplayType;
|
|
|
|
private List<ControlPoint> prevControlPoints = new List<ControlPoint>();
|
|
|
|
private bool prevKinematic = true;
|
|
|
|
private bool prevHideChildren = true;
|
|
|
|
private RendererType prevRendererType = RendererType.Continuous;
|
|
|
|
public bool startJointSpringy;
|
|
|
|
public SerializedSoftJointLimitSpring startJtSpring;
|
|
|
|
public bool endJointSpringy;
|
|
|
|
public SerializedSoftJointLimitSpring endJtSpring;
|
|
|
|
private string prevStrStaticBones;
|
|
|
|
public string strStaticBones;
|
|
|
|
private HashSet<int> staticBones = new HashSet<int>();
|
|
|
|
public PhysicsMaterial ropeMaterial;
|
|
|
|
private GameObject springHolder;
|
|
|
|
private Joint springJoint;
|
|
|
|
[HideInInspector] public List<UnityEngine.Object> lstComponentsCreated = new List<UnityEngine.Object>();
|
|
|
|
public bool HideChildren = true;
|
|
|
|
public LOGGING loggingType = LOGGING.INFO;
|
|
|
|
public RopeType ropeType;
|
|
|
|
public int numControlPoints = 2;
|
|
|
|
public List<ControlPoint> controlPoints = new List<ControlPoint>();
|
|
|
|
public Transform startPosition;
|
|
|
|
public float rate;
|
|
|
|
[Range(0f, 10f)] public float gravity = 1f;
|
|
|
|
public bool kinematic = true;
|
|
|
|
private GameObject prevFirstBone;
|
|
|
|
private GameObject prevLastBone;
|
|
|
|
public GameObject firstBone;
|
|
|
|
public GameObject lastBone;
|
|
|
|
public bool sendRopeEvents;
|
|
|
|
public RendererType rendererType = RendererType.Continuous;
|
|
|
|
public LinkMesh linkMesh = new LinkMesh();
|
|
|
|
public Material continuousMaterial;
|
|
|
|
public MeshRenderer meshRenderer;
|
|
|
|
public MeshFilter meshFilter;
|
|
|
|
public bool useColliders = true;
|
|
|
|
public float radiusFactor = 1f;
|
|
|
|
public float segmentBordersScaleFactor = 1f;
|
|
|
|
public bool useSegmentBordersOffset;
|
|
|
|
public SegmentProperties.Type segPropertyType;
|
|
|
|
public SegmentPropertiesBox segPropertiesBox = new SegmentPropertiesBox();
|
|
|
|
public SegmentPropertiesCylinder segPropertiesCylinder = new SegmentPropertiesCylinder();
|
|
|
|
public JointProperties jointProp = new JointProperties();
|
|
|
|
private int initialNumSegemnts;
|
|
|
|
public List<Segment> lstSegments = new List<Segment>();
|
|
|
|
private Mesh mesh;
|
|
|
|
private Vector3[] vertexBuffer;
|
|
|
|
private Vector2[] uv;
|
|
|
|
private int[] indexBuffer;
|
|
|
|
private Vector4[] tangents;
|
|
|
|
public float totalLengthGet;
|
|
|
|
public float tensionGet;
|
|
|
|
public float totalLength;
|
|
|
|
public float totalLengthColliders;
|
|
|
|
public float ropeStretchThreshold = -1f;
|
|
|
|
public float textureLength = 0.33f;
|
|
|
|
private int numCirclePt = 3;
|
|
|
|
public event BrokenHandler Broken;
|
|
|
|
public event CreateHandler Created;
|
|
|
|
public event DeleteHandler Deleted;
|
|
|
|
public void setStartJointSpring(SoftJointLimitSpring sp)
|
|
{
|
|
startJtSpring = (SerializedSoftJointLimitSpring)sp;
|
|
if (springJoint != null)
|
|
{
|
|
ConfigurableJoint configurableJoint = (ConfigurableJoint)springJoint.joint;
|
|
if (configurableJoint != null)
|
|
{
|
|
configurableJoint.linearLimitSpring = getStartJtSpring();
|
|
SoftJointLimit linearLimit = default(SoftJointLimit);
|
|
linearLimit.limit = 0.01f;
|
|
configurableJoint.linearLimit = linearLimit;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setEndJointSpring(SoftJointLimitSpring sp)
|
|
{
|
|
endJtSpring = (SerializedSoftJointLimitSpring)sp;
|
|
if (lstSegments.Count != 0)
|
|
{
|
|
ConfigurableJoint configurableJoint = ((lstSegments[lstSegments.Count - 1].next == null)
|
|
? null
|
|
: ((ConfigurableJoint)lstSegments[lstSegments.Count - 1].next.joint));
|
|
if (configurableJoint != null)
|
|
{
|
|
configurableJoint.linearLimitSpring = getEndJtSpring();
|
|
SoftJointLimit linearLimit = default(SoftJointLimit);
|
|
linearLimit.limit = 0.01f;
|
|
configurableJoint.linearLimit = linearLimit;
|
|
}
|
|
}
|
|
}
|
|
|
|
public SegmentPropertiesBase getSegmentProperties()
|
|
{
|
|
switch (segPropertyType)
|
|
{
|
|
case SegmentProperties.Type.BOX:
|
|
return segPropertiesBox;
|
|
case SegmentProperties.Type.CYLINDER:
|
|
return segPropertiesCylinder;
|
|
default:
|
|
return segPropertiesCylinder;
|
|
}
|
|
}
|
|
|
|
public void setPhysicsMaterial(PhysicsMaterial mat)
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
lstSegment.capsuleCollider.sharedMaterial = mat;
|
|
}
|
|
}
|
|
|
|
private void Debug(string msg, LOGGING type)
|
|
{
|
|
if (type <= loggingType)
|
|
{
|
|
UnityEngine.Debug.Log(msg, this);
|
|
}
|
|
}
|
|
|
|
private void OnJointBreak(float breakForce)
|
|
{
|
|
if (sendRopeEvents && this.Broken != null)
|
|
{
|
|
this.Broken(this);
|
|
}
|
|
}
|
|
|
|
public void setContinuousMaterialMapping(float f)
|
|
{
|
|
textureLength = f;
|
|
}
|
|
|
|
public void setFirstBone(GameObject bone)
|
|
{
|
|
firstBone = bone;
|
|
}
|
|
|
|
public void setLastBone(GameObject bone)
|
|
{
|
|
lastBone = bone;
|
|
}
|
|
|
|
public List<Segment> getSegments()
|
|
{
|
|
return lstSegments;
|
|
}
|
|
|
|
public void setStaticBoneList(string str)
|
|
{
|
|
staticBones.Clear();
|
|
str.Trim();
|
|
if (str != string.Empty)
|
|
{
|
|
string[] array = str.Split(',');
|
|
string[] array2 = array;
|
|
foreach (string text in array2)
|
|
{
|
|
string[] array3 = text.Split('-');
|
|
if (array3.Length == 1)
|
|
{
|
|
staticBones.Add(int.Parse(array3[0]));
|
|
}
|
|
else if (array3.Length == 2)
|
|
{
|
|
int num = int.Parse(array3[0]);
|
|
int num2 = int.Parse(array3[1]);
|
|
for (int j = num; j <= num2; j++)
|
|
{
|
|
staticBones.Add(j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
strStaticBones = str;
|
|
prevStrStaticBones = str;
|
|
}
|
|
|
|
public bool setControlPoints(List<ControlPoint> lstControlPoints)
|
|
{
|
|
if (numControlPoints < 2 && ropeType == RopeType.Procedural)
|
|
{
|
|
throw new ArgumentException("Control points should be more than 1");
|
|
}
|
|
|
|
bool flag = false;
|
|
if (numControlPoints != lstControlPoints.Count)
|
|
{
|
|
while (lstControlPoints.Count < numControlPoints)
|
|
{
|
|
lstControlPoints.Add(new ControlPoint());
|
|
}
|
|
|
|
while (lstControlPoints.Count > numControlPoints)
|
|
{
|
|
lstControlPoints.RemoveAt(lstControlPoints.Count - 1);
|
|
}
|
|
|
|
flag = true;
|
|
}
|
|
|
|
for (int i = 0; i < lstControlPoints.Count; i++)
|
|
{
|
|
if (i < prevControlPoints.Count && !lstControlPoints[i].compare(prevControlPoints[i]))
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
prevControlPoints.Clear();
|
|
for (int j = 0; j < lstControlPoints.Count; j++)
|
|
{
|
|
prevControlPoints.Add(lstControlPoints[j].clone());
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
controlPoints.Clear();
|
|
for (int k = 0; k < prevControlPoints.Count; k++)
|
|
{
|
|
controlPoints.Add(prevControlPoints[k].clone());
|
|
}
|
|
}
|
|
|
|
numControlPoints = lstControlPoints.Count;
|
|
return flag;
|
|
}
|
|
|
|
public SoftJointLimitSpring getStartJtSpring()
|
|
{
|
|
SoftJointLimitSpring result = default(SoftJointLimitSpring);
|
|
if (startJointSpringy)
|
|
{
|
|
result.spring = startJtSpring.spring;
|
|
result.damper = startJtSpring.damper;
|
|
}
|
|
else
|
|
{
|
|
float spring = (result.damper = 0f);
|
|
result.spring = spring;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public SoftJointLimitSpring getEndJtSpring()
|
|
{
|
|
SoftJointLimitSpring result = default(SoftJointLimitSpring);
|
|
if (endJointSpringy)
|
|
{
|
|
result.spring = endJtSpring.spring;
|
|
result.damper = endJtSpring.damper;
|
|
}
|
|
else
|
|
{
|
|
float spring = (result.damper = 0f);
|
|
result.spring = spring;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void RefreshJointSpring()
|
|
{
|
|
setStartJointSpring(startJtSpring);
|
|
setEndJointSpring(endJtSpring);
|
|
}
|
|
|
|
public void RefreshProperties(bool bForce)
|
|
{
|
|
Debug("Refreshing Properties Force = " + bForce, LOGGING.INFO);
|
|
bool flag = bForce;
|
|
if (numControlPoints < 2)
|
|
{
|
|
numControlPoints = 2;
|
|
}
|
|
|
|
bool flag2 = setControlPoints(controlPoints);
|
|
flag = flag || flag2;
|
|
if (prevStrStaticBones != strStaticBones)
|
|
{
|
|
setStaticBoneList(strStaticBones);
|
|
flag = true;
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
regenerateRope(true);
|
|
}
|
|
|
|
if (prevHideChildren != HideChildren)
|
|
{
|
|
HideChildrenObjects(HideChildren);
|
|
}
|
|
|
|
if (prevKinematic != kinematic)
|
|
{
|
|
changeToKinematic(kinematic);
|
|
}
|
|
|
|
if (prevRendererType != rendererType)
|
|
{
|
|
setRendererType(rendererType);
|
|
}
|
|
|
|
linkMesh.update();
|
|
setLinkMesh(linkMesh);
|
|
if (rendererType == RendererType.Continuous)
|
|
{
|
|
generateOverallMesh();
|
|
}
|
|
|
|
Debug("Refreshing Properties Done", LOGGING.INFO);
|
|
}
|
|
|
|
public void setBreakingForce(float force)
|
|
{
|
|
Debug("Setting breaking force to " + force, LOGGING.INFO);
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (lstSegment.next != null)
|
|
{
|
|
if (force != 0f)
|
|
{
|
|
lstSegment.next.joint.breakForce = force;
|
|
}
|
|
else
|
|
{
|
|
lstSegment.next.joint.breakForce = 1E+10f;
|
|
}
|
|
}
|
|
}
|
|
|
|
jointProp.breakingForce = force;
|
|
Debug("Setting breaking force done", LOGGING.INFO);
|
|
}
|
|
|
|
public void setRendererType(RendererType rType)
|
|
{
|
|
Debug("Setting Renderer Type to " + rType, LOGGING.INFO);
|
|
switch (rType)
|
|
{
|
|
case RendererType.Continuous:
|
|
enableRendering(true);
|
|
enableSegmentRendering(false);
|
|
break;
|
|
case RendererType.Segment:
|
|
enableRendering(false);
|
|
enableSegmentRendering(true);
|
|
break;
|
|
case RendererType.None:
|
|
enableRendering(false);
|
|
enableSegmentRendering(false);
|
|
break;
|
|
}
|
|
|
|
rendererType = rType;
|
|
prevRendererType = rType;
|
|
}
|
|
|
|
public void setLinkMesh(LinkMesh lMesh)
|
|
{
|
|
if (lMesh != null && lMesh.getMesh() != null)
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
lstSegment.meshFilter.sharedMesh = lMesh.getMesh();
|
|
lstSegment.meshRenderer.sharedMaterial = lMesh.meshMaterial;
|
|
}
|
|
}
|
|
|
|
linkMesh = lMesh;
|
|
}
|
|
|
|
public void applyGravity(float f)
|
|
{
|
|
if (f == -1f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
lstSegment.body.AddForce((0f - (1f - f)) * lstSegment.body.mass * Physics.gravity);
|
|
}
|
|
}
|
|
|
|
public void updateMass(float m)
|
|
{
|
|
getSegmentProperties().massPerUnitLength = m;
|
|
float mass = getSegmentProperties().massPerUnitLength * getSegmentProperties().length;
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
lstSegment.body.mass = mass;
|
|
}
|
|
}
|
|
|
|
private void HideChildrenObjects(bool bHide)
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (bHide)
|
|
{
|
|
lstSegment.seg.hideFlags = HideFlags.HideInHierarchy;
|
|
}
|
|
else
|
|
{
|
|
lstSegment.seg.hideFlags = HideFlags.None;
|
|
}
|
|
}
|
|
|
|
prevHideChildren = bHide;
|
|
}
|
|
|
|
public List<List<PosOri>> getTrajectory()
|
|
{
|
|
List<List<PosOri>> list = new List<List<PosOri>>();
|
|
float num = segmentBordersScaleFactor;
|
|
float num2 = ((!useSegmentBordersOffset || lstSegments.Count <= 0)
|
|
? 0f
|
|
: lstSegments[0].capsuleCollider.radius);
|
|
num2 *= num;
|
|
float num3 = 1f;
|
|
int num4 = lstSegments.Count;
|
|
// if (num4 > 30 && GameController.Instance.useFastRopeDraw)
|
|
// {
|
|
// num4 = 30;
|
|
// }
|
|
|
|
List<PosOri> list2 = new List<PosOri>();
|
|
int num5 = 0;
|
|
if (lstSegments.Count > 0)
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (list2.Count == 0)
|
|
{
|
|
PosOri posOri =
|
|
new PosOri(
|
|
lstSegment.seg.transform.TransformPoint(new Vector3(0f,
|
|
0f - getSegmentProperties().length - num2, 0f)), lstSegment.seg.transform.rotation);
|
|
posOri.pos = startPosition.position;
|
|
list2.Add(posOri);
|
|
}
|
|
|
|
PosOri item = new PosOri(lstSegment.seg.transform.position, lstSegment.seg.transform.rotation);
|
|
list2.Add(item);
|
|
if (lstSegment.next == null && num5 < num4 - 1)
|
|
{
|
|
PosOri item2 =
|
|
new PosOri(
|
|
lstSegment.seg.transform.TransformPoint(new Vector3(0f,
|
|
getSegmentProperties().length * num3, 0f)), lstSegment.seg.transform.rotation);
|
|
list2.Add(item2);
|
|
list.Add(list2);
|
|
list2 = new List<PosOri>();
|
|
}
|
|
|
|
num5++;
|
|
if (num5 > num4)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
PosOri item3 =
|
|
new PosOri(
|
|
lstSegments[Mathf.Min(num4, lstSegments.Count) - 1].seg.transform
|
|
.TransformPoint(new Vector3(0f, getSegmentProperties().length + num2, 0f)),
|
|
lstSegments[0].seg.transform.rotation);
|
|
list2.Add(item3);
|
|
}
|
|
|
|
list.Add(list2);
|
|
return list;
|
|
}
|
|
|
|
private void generateMeshForTrajectory(List<PosOri> trajectory, Bezier interpolator, float totalLen,
|
|
ref float lengthCovered, ref int lastVertId, ref int lastIndexID)
|
|
{
|
|
float num = ((segPropertyType != 0) ? segPropertiesBox.width : segPropertiesCylinder.radius);
|
|
num *= radiusFactor;
|
|
float num2 = 6.28318f / (float)numCirclePt;
|
|
Vector3[] array = new Vector3[numCirclePt];
|
|
Vector3[] array2 = new Vector3[numCirclePt];
|
|
for (int i = 0; i < numCirclePt; i++)
|
|
{
|
|
array[i] = new Vector3((float)((double)num * Math.Cos((float)i * num2)), 0f,
|
|
(float)((double)num * Math.Sin((float)i * num2)));
|
|
array2[i] = new Vector3((float)((double)(0f - num) * Math.Sin((float)i * num2)), 0f,
|
|
(float)((double)num * Math.Cos((float)i * num2)));
|
|
array2[i].Normalize();
|
|
}
|
|
|
|
int num3 = lastVertId;
|
|
Vector3 v = new Vector3(0f, 0f, 1f);
|
|
Vector3 vector = new Vector3(1f, 1f, 1f);
|
|
Vector3 vector2 = new Vector3(0.3f, 1f, 0.3f);
|
|
Vector3 s = new Vector3(0.2f, 1f, 0.2f);
|
|
float num4 = 0f;
|
|
Vector3 vector3 = trajectory[0].pos;
|
|
int num5 = trajectory.Count * 4;
|
|
float deltaLen = totalLen / (float)(num5 - 1);
|
|
for (int j = 0; j < num5; j++)
|
|
{
|
|
Vector3 vector4 = ((j != 0) ? interpolator.getNext(deltaLen).pos : trajectory[0].pos);
|
|
if (j != 0)
|
|
{
|
|
v = vector4 - vector3;
|
|
v.Normalize();
|
|
}
|
|
else if (j == 0 && trajectory.Count > 1)
|
|
{
|
|
v = trajectory[1].pos - vector4;
|
|
v.Normalize();
|
|
}
|
|
|
|
Vector3 vector5 = vector4 - vector3;
|
|
vector3 = vector4;
|
|
Matrix4x4 matrix4x = default(Matrix4x4);
|
|
for (int k = 0; k < numCirclePt; k++)
|
|
{
|
|
Quaternion q = Utility.createOrientation(v);
|
|
// if (GameController.Instance.fishingPlayer.currentHands.fishingLine.lineType ==
|
|
// FishingLine.LineType.FLY && j >= num5 - 8)
|
|
// {
|
|
// matrix4x.SetTRS(vector4, q, s);
|
|
// }
|
|
// else
|
|
{
|
|
matrix4x.SetTRS(vector4, q, (!(vector4.y < 0f)) ? vector : vector2);
|
|
}
|
|
|
|
vertexBuffer[num3] = base.transform.InverseTransformPoint(matrix4x.MultiplyPoint(array[k]));
|
|
if (j == 0)
|
|
{
|
|
}
|
|
|
|
Vector3 vector6 = base.transform.InverseTransformDirection(matrix4x.MultiplyVector(array2[k]));
|
|
tangents[num3] = new Vector4(vector6.x, vector6.y, vector6.z, -1f);
|
|
if (j == 1)
|
|
{
|
|
}
|
|
|
|
uv[num3] = new Vector2((float)k * 1f / (float)numCirclePt, (totalLen - num4) / textureLength);
|
|
num3++;
|
|
}
|
|
|
|
num4 += vector5.magnitude;
|
|
}
|
|
|
|
if (true)
|
|
{
|
|
int num6 = lastIndexID;
|
|
for (int l = 0; l < num5 - 1; l++)
|
|
{
|
|
for (int m = 0; m < numCirclePt; m++)
|
|
{
|
|
int num7 = l + lastVertId / numCirclePt;
|
|
indexBuffer[num6++] = num7 * numCirclePt + m;
|
|
indexBuffer[num6++] = (num7 + 1) * numCirclePt + m;
|
|
indexBuffer[num6++] = num7 * numCirclePt + (m + 1) % numCirclePt;
|
|
indexBuffer[num6++] = num7 * numCirclePt + (m + 1) % numCirclePt;
|
|
indexBuffer[num6++] = (num7 + 1) * numCirclePt + m;
|
|
indexBuffer[num6++] = (num7 + 1) * numCirclePt + (m + 1) % numCirclePt;
|
|
}
|
|
}
|
|
|
|
lastIndexID = num6;
|
|
}
|
|
|
|
lengthCovered += num4;
|
|
lastVertId = num3;
|
|
}
|
|
|
|
public void generateOverallMesh()
|
|
{
|
|
// if ((bool)GameController.Instance.fishingPlayer && GameController.Instance.optimalRopeGenerator &&
|
|
// ((GameController.Instance.fishingPlayer.currentHands.fakeStraightLine.enabled &&
|
|
// ropeGameplayType != RopeGameplayType.FLOAT) ||
|
|
// GameController.Instance.fishingPlayer.underwaterCamera.isTurnedOn))
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
List<List<PosOri>> trajectory = getTrajectory();
|
|
if (trajectory[0].Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int num = 0;
|
|
int num2 = 0;
|
|
bool flag = false;
|
|
foreach (List<PosOri> item in trajectory)
|
|
{
|
|
int num3 = item.Count * 4;
|
|
num += num3;
|
|
num2 += (num3 - 1) * (numCirclePt * 2);
|
|
}
|
|
|
|
int num4 = numCirclePt * num;
|
|
if (vertexBuffer == null || num4 != vertexBuffer.Length)
|
|
{
|
|
flag = vertexBuffer == null || num4 > vertexBuffer.Length;
|
|
vertexBuffer = new Vector3[num4];
|
|
tangents = new Vector4[num4];
|
|
uv = new Vector2[num4];
|
|
}
|
|
|
|
if (indexBuffer == null || num2 * 3 != indexBuffer.Length)
|
|
{
|
|
indexBuffer = new int[num2 * 3];
|
|
}
|
|
|
|
int lastVertId = 0;
|
|
int lastIndexID = 0;
|
|
List<Bezier> list = new List<Bezier>();
|
|
float num5 = 0f;
|
|
foreach (List<PosOri> item2 in trajectory)
|
|
{
|
|
list.Add(new Bezier(item2));
|
|
num5 += list[list.Count - 1].TotalLength();
|
|
}
|
|
|
|
float lengthCovered = 0f;
|
|
for (int i = 0; i < trajectory.Count; i++)
|
|
{
|
|
generateMeshForTrajectory(trajectory[i], list[i], num5, ref lengthCovered, ref lastVertId,
|
|
ref lastIndexID);
|
|
}
|
|
|
|
if (mesh == null)
|
|
{
|
|
mesh = new Mesh();
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
mesh.vertices = vertexBuffer;
|
|
mesh.triangles = indexBuffer;
|
|
}
|
|
else
|
|
{
|
|
mesh.triangles = indexBuffer;
|
|
mesh.vertices = vertexBuffer;
|
|
}
|
|
|
|
mesh.uv = uv;
|
|
mesh.RecalculateNormals();
|
|
mesh.tangents = tangents;
|
|
meshFilter.sharedMesh = mesh;
|
|
meshRenderer.sharedMaterial = continuousMaterial;
|
|
mesh.bounds = new Bounds(base.transform.position, new Vector3(10000f, 10000f, 10000f));
|
|
}
|
|
|
|
public void regenerateRope(bool bDestroyImmediate)
|
|
{
|
|
deleteRope(bDestroyImmediate);
|
|
generateCatnaryRope(controlPoints.ToArray());
|
|
setLinkMesh(linkMesh);
|
|
initialNumSegemnts = lstSegments.Count;
|
|
}
|
|
|
|
public void generateRope(ControlPoint[] arrPoints)
|
|
{
|
|
bool flag = false;
|
|
List<Vector3> list = new List<Vector3>(arrPoints.Length);
|
|
for (int i = 0; i < arrPoints.Length; i++)
|
|
{
|
|
list.Add(arrPoints[i].localPos);
|
|
if (arrPoints[i].obj != null)
|
|
{
|
|
list[i] = arrPoints[i].obj.transform.TransformPoint(arrPoints[i].localPos);
|
|
}
|
|
else
|
|
{
|
|
list[i] = ((!flag)
|
|
? base.gameObject.transform.TransformPoint(arrPoints[i].localPos)
|
|
: arrPoints[i].localPos);
|
|
}
|
|
}
|
|
|
|
SCapsulePos sCapsulePos = new SCapsulePos();
|
|
bool flag2 = false;
|
|
int last = 0;
|
|
bool flag3 = false;
|
|
Segment segment = null;
|
|
Quaternion quaternion = Quaternion.identity;
|
|
Quaternion quaternion2 = Quaternion.AngleAxis(jointProp.twistOffsetDeg, new Vector3(0f, 1f, 0f));
|
|
totalLength = 0f;
|
|
Vector3 vector = list[0];
|
|
int num = 0;
|
|
while (!flag2)
|
|
{
|
|
int num2 = last;
|
|
flag2 = getNextCapsulePos(sCapsulePos, list, ref last, getSegmentProperties(), jointProp, false);
|
|
Segment segment2 = null;
|
|
if (sCapsulePos.fLen > 0f)
|
|
{
|
|
segment2 = createSegment(sCapsulePos.fLen, sCapsulePos.vPos, sCapsulePos.vDir);
|
|
if (useColliders && num >= 0)
|
|
{
|
|
if ((bool)segment2.capsuleCollider)
|
|
{
|
|
segment2.capsuleCollider.enabled = true;
|
|
}
|
|
|
|
num = 0;
|
|
}
|
|
else
|
|
{
|
|
if ((bool)segment2.capsuleCollider)
|
|
{
|
|
segment2.capsuleCollider.enabled = false;
|
|
}
|
|
|
|
num++;
|
|
}
|
|
|
|
lstSegments.Add(segment2);
|
|
if (segment != null)
|
|
{
|
|
totalLength += (sCapsulePos.vPos - vector).magnitude;
|
|
vector = sCapsulePos.vPos;
|
|
segment.next = createSegmentJoint(segment, segment2, quaternion);
|
|
segment2.prev = segment.next;
|
|
}
|
|
|
|
GameObject gameObject = null;
|
|
Vector3 vector2 = new Vector3(0f, 0f, 0f);
|
|
bool flag4 = false;
|
|
if (!flag3 && num2 == 0)
|
|
{
|
|
if (arrPoints[num2].attached)
|
|
{
|
|
gameObject = arrPoints[num2].obj;
|
|
vector2 = arrPoints[num2].localPos;
|
|
flag4 = true;
|
|
}
|
|
}
|
|
else if (num2 != last && last < arrPoints.Length && arrPoints[last].attached)
|
|
{
|
|
gameObject = arrPoints[last].obj;
|
|
vector2 = arrPoints[last].localPos;
|
|
flag4 = true;
|
|
}
|
|
|
|
if (flag4)
|
|
{
|
|
vector2 = ((gameObject != null)
|
|
? gameObject.transform.TransformPoint(vector2)
|
|
: ((!flag) ? base.gameObject.transform.TransformPoint(vector2) : vector2));
|
|
int jtPos = -1;
|
|
Joint prev = new Joint(segment2.seg, gameObject, vector2,
|
|
segment2.seg.transform.TransformDirection(0f, 1f, 0f), jointProp, this, jtPos);
|
|
if (num2 == 0)
|
|
{
|
|
segment2.prev = prev;
|
|
}
|
|
|
|
flag3 = true;
|
|
}
|
|
|
|
segment = segment2;
|
|
quaternion = quaternion2 * quaternion;
|
|
}
|
|
else
|
|
{
|
|
flag2 = true;
|
|
}
|
|
}
|
|
|
|
if (lstSegments.Count == 1)
|
|
{
|
|
GameObject obj = arrPoints[last].obj;
|
|
Vector3 localPos = arrPoints[last].localPos;
|
|
int jtPos2 = -1;
|
|
Segment segment3 = lstSegments[0];
|
|
Joint prev2 = new Joint(segment3.seg, obj, localPos,
|
|
segment3.seg.transform.TransformDirection(0f, 1f, 0f), jointProp, this, jtPos2);
|
|
segment3.prev = prev2;
|
|
}
|
|
|
|
if (lstSegments.Count > 0 && !lstSegments[lstSegments.Count - 1].seg.GetComponent<ConfigurableJoint>())
|
|
{
|
|
GameObject obj2 = arrPoints[last].obj;
|
|
Vector3 localPos2 = arrPoints[last].localPos;
|
|
int jtPos3 = -1;
|
|
Segment segment4 = lstSegments[lstSegments.Count - 1];
|
|
Joint joint = new Joint(segment4.seg, obj2, localPos2,
|
|
segment4.seg.transform.TransformDirection(0f, 1f, 0f), jointProp, this, jtPos3);
|
|
}
|
|
|
|
if (sendRopeEvents && this.Created != null)
|
|
{
|
|
this.Created(this);
|
|
}
|
|
}
|
|
|
|
public void generateCatnaryRope(ControlPoint[] arrPoints)
|
|
{
|
|
Debug("Generating Catenary Rope " + arrPoints.ToString(), LOGGING.INFO);
|
|
if (arrPoints.Length < 2)
|
|
{
|
|
return;
|
|
}
|
|
|
|
List<ControlPoint> list = new List<ControlPoint>();
|
|
Vector3 vector = ((!(arrPoints[0].obj != null))
|
|
? arrPoints[0].localPos
|
|
: arrPoints[0].obj.transform.TransformPoint(arrPoints[0].localPos));
|
|
list.Add(arrPoints[0]);
|
|
for (int i = 1; i < arrPoints.Length; i++)
|
|
{
|
|
Vector3 vector2 = ((!(arrPoints[i].obj != null))
|
|
? arrPoints[i].localPos
|
|
: arrPoints[i].obj.transform.TransformPoint(arrPoints[i].localPos));
|
|
ControlPoint controlPoint = arrPoints[i - 1];
|
|
if (controlPoint.slackFraction > 1f)
|
|
{
|
|
float magnitude = (vector2 - vector).magnitude;
|
|
SegmentPropertiesBase segmentProperties = getSegmentProperties();
|
|
List<Vector3> catenaryPts = Utility.getCatenaryPts(vector, vector2,
|
|
magnitude * controlPoint.slackFraction, (int)(magnitude / segmentProperties.length));
|
|
for (int j = 1; j < catenaryPts.Count; j++)
|
|
{
|
|
ControlPoint controlPoint2 = new ControlPoint();
|
|
controlPoint2.attached = false;
|
|
controlPoint2.obj = null;
|
|
controlPoint2.localPos = catenaryPts[j];
|
|
if (j == catenaryPts.Count - 1)
|
|
{
|
|
controlPoint2.attached = arrPoints[i].attached;
|
|
controlPoint2.obj = arrPoints[i].obj;
|
|
controlPoint2.localPos = ((!(controlPoint2.obj != null))
|
|
? controlPoint2.localPos
|
|
: controlPoint2.obj.transform.InverseTransformPoint(controlPoint2.localPos));
|
|
}
|
|
|
|
list.Add(controlPoint2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list.Add(arrPoints[i]);
|
|
}
|
|
|
|
vector = vector2;
|
|
}
|
|
|
|
generateRope(list.ToArray());
|
|
Debug("Generating Catenary Rope done", LOGGING.INFO);
|
|
}
|
|
|
|
public void deleteRope(bool bDestroyImmediate)
|
|
{
|
|
if (lstSegments != null)
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (bDestroyImmediate)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(lstSegment.seg);
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Object.Destroy(lstSegment.seg);
|
|
}
|
|
}
|
|
|
|
lstSegments.Clear();
|
|
}
|
|
|
|
if (springJoint != null)
|
|
{
|
|
UnityEngine.Object.Destroy(springJoint.joint);
|
|
}
|
|
|
|
if (springHolder != null)
|
|
{
|
|
UnityEngine.Object.Destroy(springHolder);
|
|
}
|
|
|
|
if (bDestroyImmediate)
|
|
{
|
|
clearOrphan();
|
|
}
|
|
|
|
if (sendRopeEvents && this.Deleted != null)
|
|
{
|
|
this.Deleted(this);
|
|
}
|
|
}
|
|
|
|
public float getLength()
|
|
{
|
|
return totalLength;
|
|
}
|
|
|
|
public float getLengthColliders()
|
|
{
|
|
return totalLengthColliders;
|
|
}
|
|
|
|
public float getTension()
|
|
{
|
|
if (springJoint != null && springJoint.joint != null)
|
|
{
|
|
ConfigurableJoint configurableJoint = (ConfigurableJoint)springJoint.joint;
|
|
Vector3 vector = configurableJoint.connectedAnchor;
|
|
Rigidbody connectedBody = configurableJoint.connectedBody;
|
|
Vector3 vector2 = configurableJoint.anchor;
|
|
Rigidbody body = lstSegments[0].body;
|
|
if (connectedBody != null)
|
|
{
|
|
vector = connectedBody.transform.TransformPoint(vector);
|
|
}
|
|
|
|
if (body != null)
|
|
{
|
|
vector2 = body.transform.TransformPoint(vector2);
|
|
}
|
|
|
|
float num = (vector - vector2).magnitude - 0.01f;
|
|
return num * configurableJoint.linearLimitSpring.spring;
|
|
}
|
|
|
|
if (lstSegments.Count > 0 && lstSegments[0].prev != null)
|
|
{
|
|
UnityEngine.Joint joint = lstSegments[0].prev.joint;
|
|
Vector3 vector3 = joint.connectedAnchor;
|
|
Rigidbody connectedBody2 = joint.connectedBody;
|
|
Vector3 vector4 = joint.anchor;
|
|
Rigidbody body2 = lstSegments[0].body;
|
|
if (connectedBody2 != null)
|
|
{
|
|
vector3 = connectedBody2.transform.TransformPoint(vector3);
|
|
}
|
|
|
|
if (body2 != null)
|
|
{
|
|
vector4 = body2.transform.TransformPoint(vector4);
|
|
}
|
|
|
|
float num2 = (vector3 - vector4).magnitude - 0.01f;
|
|
return num2 * ((ConfigurableJoint)joint).linearLimitSpring.spring;
|
|
}
|
|
|
|
return 0f;
|
|
}
|
|
|
|
public void breakRope(float fraction)
|
|
{
|
|
Debug("Breaking Rope from Fraction: " + fraction, LOGGING.INFO);
|
|
int num = (int)((float)lstSegments.Count * fraction);
|
|
if (num < lstSegments.Count - 1 && num >= 0)
|
|
{
|
|
Debug("Breaking Rope from segment: " + num, LOGGING.DEBUG);
|
|
if (lstSegments[num].next != null)
|
|
{
|
|
UnityEngine.Object.Destroy(lstSegments[num].next.joint);
|
|
lstSegments[num].next = null;
|
|
lstSegments[num + 1].prev = null;
|
|
}
|
|
}
|
|
|
|
Debug("Breaking Rope done", LOGGING.INFO);
|
|
}
|
|
|
|
public void setLength(float newLength)
|
|
{
|
|
newLength -= getLength();
|
|
changeLength(newLength);
|
|
}
|
|
|
|
public void changeLength(float deltaLen)
|
|
{
|
|
if (lstSegments.Count < 1 || deltaLen == 0f)
|
|
{
|
|
CalculateTotalLength();
|
|
return;
|
|
}
|
|
|
|
deltaLen *= 0.5f;
|
|
int num = 0;
|
|
Segment segment = lstSegments[num];
|
|
SegmentPropertiesBase segmentProperties = getSegmentProperties();
|
|
Vector3 localScale = segment.seg.transform.localScale;
|
|
if (localScale.y > 0f)
|
|
{
|
|
localScale.y += deltaLen;
|
|
}
|
|
|
|
if (localScale.y < 0.01f)
|
|
{
|
|
localScale.y = 0.01f;
|
|
}
|
|
|
|
float num2 = 0.5f;
|
|
float num3 = 1f;
|
|
float num4 = 0f;
|
|
float num5 = 0f;
|
|
float num6 = segmentProperties.length * num2;
|
|
num5 = ((SegmentPropertiesCylinder)segmentProperties).radius * 2f;
|
|
if (localScale.y > (segmentProperties.length + num5) * num2)
|
|
{
|
|
Vector3 localScale2 = segment.seg.transform.localScale;
|
|
localScale2.y = num6;
|
|
segment.seg.transform.localScale = localScale2;
|
|
float num7 = 0f;
|
|
for (deltaLen = 0f - segmentProperties.length + localScale.y / num2; deltaLen > 0f; deltaLen -= num7)
|
|
{
|
|
num7 = Mathf.Clamp(deltaLen, 0.01f, num6);
|
|
segment.seg.transform.position += segment.seg.transform.TransformDirection(0f, 1f, 0f) * num7;
|
|
if (segment.next != null)
|
|
{
|
|
if (segment.next.joint.connectedBody != segment.body)
|
|
{
|
|
segment.next.joint.anchor = new Vector3(0f, (1f - jointProp.offsetScale) * num3, 0f);
|
|
}
|
|
else
|
|
{
|
|
segment.next.joint.connectedAnchor =
|
|
new Vector3(0f, (1f - jointProp.offsetScale) * num3, 0f);
|
|
}
|
|
}
|
|
|
|
Vector3 pos = segment.seg.transform.position -
|
|
segment.seg.transform.TransformDirection(0f, 1f, 0f) *
|
|
(num7 + segmentProperties.length / 2f);
|
|
Segment segment2 = createSegment(num7 * 2f, pos,
|
|
segment.seg.transform.TransformDirection(0f, 1f, 0f));
|
|
float num8 = jointProp.twistOffsetDeg * (float)(-1 + (initialNumSegemnts - lstSegments.Count));
|
|
num8 = (num8 + 36000f) % 360f;
|
|
Quaternion quaternion = Quaternion.AngleAxis(num8, new Vector3(0f, 1f, 0f));
|
|
segment2.seg.transform.rotation = segment2.seg.transform.rotation * quaternion;
|
|
Rigidbody connectedBody = segment.prev.joint.connectedBody;
|
|
Vector3 connectedAnchor = segment.prev.joint.connectedAnchor;
|
|
Vector3 vGlobalAnchor = ((!connectedBody)
|
|
? connectedAnchor
|
|
: connectedBody.transform.TransformPoint(connectedAnchor));
|
|
Joint prev = new Joint(segment2.seg, (!connectedBody) ? null : connectedBody.gameObject,
|
|
vGlobalAnchor, segment2.seg.transform.TransformDirection(0f, 1f, 0f), jointProp, this, -1);
|
|
segment2.prev = prev;
|
|
Joint prev2 = (segment2.next = new Joint(segment2, segment, jointProp, getSegmentProperties(),
|
|
Quaternion.identity));
|
|
Joint prev3 = segment.prev;
|
|
segment.prev = prev2;
|
|
lstSegments.Insert(0, segment2);
|
|
UnityEngine.Object.Destroy(prev3.joint);
|
|
FixAnchors(segment2, num3);
|
|
segment = segment2;
|
|
}
|
|
|
|
CalculateTotalLength();
|
|
}
|
|
else if (localScale.y < num5 * num2)
|
|
{
|
|
while (deltaLen < 0f)
|
|
{
|
|
if (lstSegments.Count < num + 1 + 1)
|
|
{
|
|
UnityEngine.Debug.LogError("!!! changeLength lstSegments size error index !!!: " + num);
|
|
// if (GameController.Instance.fishingPlayer.currentState == FishingPlayer.PlayerState.FISHING ||
|
|
// GameController.Instance.fishingPlayer.currentState == FishingPlayer.PlayerState.ICE_FISHING)
|
|
// {
|
|
// GameController.Instance.fishingPlayer.LineBreak(
|
|
// Utilities.GetTranslation("HUD_MESSAGE/LINE_BROKE_TENSION"), 0f);
|
|
// }
|
|
|
|
return;
|
|
}
|
|
|
|
Segment segment3 = lstSegments[num + 1];
|
|
Vector3 localScale3 = segment3.seg.transform.localScale;
|
|
localScale3.y = num6;
|
|
segment3.seg.transform.localScale = localScale3;
|
|
segment.seg.transform.position +=
|
|
segment.seg.transform.TransformDirection(0f, -1f, 0f) * localScale.y / num2;
|
|
Vector3 connectedAnchor2 = segment.prev.joint.connectedAnchor;
|
|
Rigidbody connectedBody2 = segment.prev.joint.connectedBody;
|
|
Vector3 vGlobalAnchor2 = ((!connectedBody2)
|
|
? connectedAnchor2
|
|
: connectedBody2.transform.TransformPoint(connectedAnchor2));
|
|
Joint prev4 = new Joint(segment3.seg, (!connectedBody2) ? null : connectedBody2.gameObject,
|
|
vGlobalAnchor2, segment3.seg.transform.TransformDirection(0f, 1f, 0f), jointProp, this, -1);
|
|
segment3.prev = prev4;
|
|
deltaLen += segment.seg.transform.localScale.y;
|
|
lstSegments.Remove(segment);
|
|
UnityEngine.Object.Destroy(segment.seg);
|
|
FixAnchors(segment3, num3);
|
|
segment = segment3;
|
|
if (!(deltaLen < 0f))
|
|
{
|
|
}
|
|
}
|
|
|
|
CalculateTotalLength();
|
|
}
|
|
else
|
|
{
|
|
segment.seg.transform.localScale = localScale;
|
|
FixAnchors(segment, num3);
|
|
CalculateTotalLength();
|
|
}
|
|
}
|
|
|
|
public void FixAnchors(Segment seg, float anchorMult)
|
|
{
|
|
Joint prev = seg.prev;
|
|
Joint next = seg.next;
|
|
if (prev != null)
|
|
{
|
|
if (prev.joint.connectedBody != seg.body)
|
|
{
|
|
prev.joint.anchor = new Vector3(0f, (-1f + jointProp.offsetScale) * anchorMult, 0f);
|
|
}
|
|
else
|
|
{
|
|
prev.joint.connectedAnchor = new Vector3(0f, (-1f + jointProp.offsetScale) * anchorMult, 0f);
|
|
}
|
|
}
|
|
|
|
if (next != null)
|
|
{
|
|
if (next.joint.connectedBody != seg.body)
|
|
{
|
|
next.joint.anchor = new Vector3(0f, (1f - jointProp.offsetScale) * anchorMult, 0f);
|
|
}
|
|
else
|
|
{
|
|
next.joint.connectedAnchor = new Vector3(0f, (1f - jointProp.offsetScale) * anchorMult, 0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void clearOrphan()
|
|
{
|
|
Debug("Clear Orphan", LOGGING.INFO);
|
|
if (lstComponentsCreated != null)
|
|
{
|
|
foreach (UnityEngine.Object item in lstComponentsCreated)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(item);
|
|
}
|
|
|
|
lstComponentsCreated.Clear();
|
|
}
|
|
|
|
Debug("Clear Orphan done", LOGGING.INFO);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
meshRenderer = GetComponent<MeshRenderer>();
|
|
meshFilter = GetComponent<MeshFilter>();
|
|
if (startPosition == null && (bool)controlPoints[0].obj)
|
|
{
|
|
startPosition = controlPoints[0].obj.transform;
|
|
}
|
|
|
|
List<GameObject> list = new List<GameObject>();
|
|
for (int i = 0; i < base.transform.childCount; i++)
|
|
{
|
|
if (base.transform.GetChild(i).name.Contains("__rope__"))
|
|
{
|
|
list.Add(base.transform.GetChild(i).gameObject);
|
|
}
|
|
}
|
|
|
|
foreach (GameObject item in list)
|
|
{
|
|
UnityEngine.Object.Destroy(item);
|
|
}
|
|
|
|
lstSegments = new List<Segment>();
|
|
if (ropeType == RopeType.FromBones)
|
|
{
|
|
rendererType = RendererType.None;
|
|
}
|
|
|
|
regenerateRope(true);
|
|
setRendererType(rendererType);
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
changeLength(rate);
|
|
if (gravity != -1f)
|
|
{
|
|
applyGravity(gravity);
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
generateOverallMesh();
|
|
}
|
|
|
|
private void checkBrokenJoints()
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (lstSegment.prev != null && lstSegment.prev.joint == null)
|
|
{
|
|
lstSegment.prev = null;
|
|
}
|
|
|
|
if (lstSegment.next != null && lstSegment.next.joint == null)
|
|
{
|
|
lstSegment.next = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void checkStabilization()
|
|
{
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
float num = lstSegment.body.linearVelocity.sqrMagnitude * lstSegment.body.mass +
|
|
lstSegment.body.inertiaTensor.magnitude * lstSegment.body.angularVelocity.sqrMagnitude;
|
|
if (num > lstSegment.body.mass * 25f)
|
|
{
|
|
lstSegment.body.linearVelocity = new Vector3(0f, 0f, 0f);
|
|
lstSegment.body.angularVelocity = new Vector3(0f, 0f, 0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void changeToKinematic(bool b)
|
|
{
|
|
int num = 0;
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
if (ropeType == RopeType.Procedural || (ropeType == RopeType.FromBones && !staticBones.Contains(num)))
|
|
{
|
|
lstSegment.body.isKinematic = b;
|
|
}
|
|
|
|
num++;
|
|
}
|
|
|
|
kinematic = b;
|
|
prevKinematic = b;
|
|
}
|
|
|
|
private void enableRendering(bool b)
|
|
{
|
|
Debug("Enable Rendering " + b, LOGGING.INFO);
|
|
meshRenderer.enabled = b;
|
|
Debug("Enable Rendering done", LOGGING.INFO);
|
|
}
|
|
|
|
private void enableSegmentRendering(bool b)
|
|
{
|
|
Debug("Enable Segment Rendering " + b, LOGGING.INFO);
|
|
foreach (Segment lstSegment in lstSegments)
|
|
{
|
|
lstSegment.meshRenderer.enabled = b;
|
|
}
|
|
|
|
Debug("Enable Segment Rendering done", LOGGING.INFO);
|
|
}
|
|
|
|
private bool getNextCapsulePos(SCapsulePos capPose, List<Vector3> vecPts, ref int last,
|
|
SegmentPropertiesBase segProp, JointProperties jointProp, bool bExtraSegPosAtStart)
|
|
{
|
|
capPose.vPrevPos = capPose.vPos;
|
|
capPose.vPrevDir = capPose.vDir;
|
|
if (bExtraSegPosAtStart)
|
|
{
|
|
capPose.vPos += capPose.vDir * capPose.fLen * (1f - jointProp.offsetScale);
|
|
capPose.vDir *= -1f;
|
|
}
|
|
|
|
bool result = false;
|
|
if (capPose.vDir.magnitude != 0f)
|
|
{
|
|
Vector3 vDir = capPose.vDir;
|
|
capPose.vPos += vDir * capPose.fLen * (1f - jointProp.offsetScale);
|
|
}
|
|
else
|
|
{
|
|
capPose.vPos = vecPts[last];
|
|
}
|
|
|
|
int num = last + 1;
|
|
if (num < vecPts.Count && num >= 0)
|
|
{
|
|
Vector3 vDir2 = vecPts[num] - capPose.vPos;
|
|
float magnitude = vDir2.magnitude;
|
|
vDir2.Normalize();
|
|
float length = segProp.length;
|
|
capPose.fLen = length;
|
|
capPose.vDir = vDir2;
|
|
if (magnitude < segProp.length)
|
|
{
|
|
last = num;
|
|
num = last + 1;
|
|
if (last == 0 || last == vecPts.Count - 1)
|
|
{
|
|
capPose.fLen = magnitude;
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bExtraSegPosAtStart)
|
|
{
|
|
capPose.vPos += capPose.vDir * capPose.fLen;
|
|
capPose.vDir *= -1f;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Segment createSegment(float len, Vector3 pos, Vector3 dir)
|
|
{
|
|
Quaternion q = Utility.createOrientation(dir);
|
|
Segment segment = new Segment("segment-" + lstSegments.Count + "__rope__", len, pos + dir * len / 2f, q,
|
|
getSegmentProperties(), this);
|
|
segment.seg.transform.parent = base.gameObject.transform;
|
|
// if ((bool)GameController.Instance)
|
|
{
|
|
segment.meshRenderer.enabled = true;
|
|
// segment.meshRenderer.material = GameController.Instance.waterInteractiveMaterial;
|
|
segment.meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
|
|
}
|
|
// else
|
|
// {
|
|
// segment.meshRenderer.enabled = false;
|
|
// }
|
|
if (totalLength <= 105f)
|
|
{
|
|
// segment.waterInteractive = segment.seg.AddComponent<WaterInteractive>();
|
|
// segment.waterInteractive.Multiplier = 1.5f;
|
|
}
|
|
|
|
return segment;
|
|
}
|
|
|
|
private Joint createSegmentJoint(Segment seg1, Segment seg2, Quaternion twistOffset)
|
|
{
|
|
return new Joint(seg1, seg2, jointProp, getSegmentProperties(), twistOffset);
|
|
}
|
|
|
|
public void CalculateTotalLength()
|
|
{
|
|
totalLength = 0f;
|
|
totalLengthColliders = 0f;
|
|
for (int i = 0; i < lstSegments.Count; i++)
|
|
{
|
|
totalLengthColliders +=
|
|
lstSegments[i].seg.transform.localScale.y * lstSegments[i].capsuleCollider.height;
|
|
if (i == 0)
|
|
{
|
|
totalLength += (lstSegments[i].seg.transform.position - controlPoints[0].obj.transform.position)
|
|
.magnitude;
|
|
}
|
|
|
|
if (i == lstSegments.Count - 1)
|
|
{
|
|
totalLength += (lstSegments[i].seg.transform.position - controlPoints[1].obj.transform.position)
|
|
.magnitude;
|
|
}
|
|
|
|
if (i > 0)
|
|
{
|
|
totalLength += (lstSegments[i].seg.transform.position - lstSegments[i - 1].seg.transform.position)
|
|
.magnitude;
|
|
}
|
|
}
|
|
|
|
|
|
if (ropeStretchThreshold > 0f && totalLength - totalLengthColliders > ropeStretchThreshold)
|
|
{
|
|
regenerateRope(true);
|
|
UnityEngine.Debug.LogError("Rope stretch regenerate");
|
|
}
|
|
}
|
|
}
|
|
} |