Files
Fishing2/Assets/Scripts/ThirdParty/PhysicsTools/Rope.cs
2025-08-28 00:20:12 +08:00

1511 lines
51 KiB
C#

using System;
using System.Collections.Generic;
// using UltimateWater;
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 createBoneSegment(float len, Vector3 pos, Vector3 dir, GameObject bone)
{
Quaternion q = Utility.createOrientation(dir);
BoneSegment boneSegment = new BoneSegment("segment-" + lstSegments.Count + "__rope__", len,
pos + dir * len / 2f, q, getSegmentProperties(), this, bone);
boneSegment.seg.transform.parent = base.gameObject.transform;
return boneSegment;
}
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");
}
}
}
}