Skip to content

Instantly share code, notes, and snippets.

@varlamov5264
Created November 11, 2021 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save varlamov5264/e07dc0cb8fd3cb1d0c626aca7aefa688 to your computer and use it in GitHub Desktop.
Save varlamov5264/e07dc0cb8fd3cb1d0c626aca7aefa688 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(SkinnedMeshRenderer))]
public class FishingPole : MonoBehaviour
{
// FishingPole is Singleton
private static FishingPole _instance;
public static FishingPole Instance
{
get
{
return _instance;
}
}
public Vector3 PoleTipPosition
{
get
{
return tip.position;
}
}
public float length
{
get
{
return (bones[0].position - tip.position).magnitude;
}
}
List<Transform> bones = new List<Transform>();
public float m_forceModule = 0;
private Transform lastBone;
public Vector3 m_forceSource;
[SerializeField]
public int m_steps = 20;
public Material material;
public Space space;
private int segments = 5;
private Transform tip;
private void Awake()
{
if (_instance != null)
{
Destroy(this);
return;
}
_instance = this;
if (GetComponent<SkinnedMeshRenderer>().sharedMesh != null)
GetComponent<SkinnedMeshRenderer>().sharedMesh.Clear();
GenerateMesh();
this.gameObject.SetActive(false);
}
public void GenerateMesh()
{
Transform transform = this.transform;
Matrix4x4 toLocal = transform.worldToLocalMatrix;
SkinnedMeshRenderer skinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
List<Vector3> points = new List<Vector3>();
List<BoneWeight> weights = new List<BoneWeight>();
List<Matrix4x4> poses = new List<Matrix4x4>();
int index = 0;
Transform t = new GameObject("joint " + index).transform;
t.parent = this.transform;
t.localRotation = Quaternion.identity;
t.localPosition = new Vector3(0, 0, 0);
Vector3 a = toLocal.MultiplyPoint(transform.position);
points.Add(a);
bones.Add(t);
poses.Add(t.worldToLocalMatrix * transform.localToWorldMatrix);
while (++index < m_steps)
{
a = a + new Vector3(0, 1, 0) / (float)Mathf.Sqrt(index);
t = new GameObject("joint " + index).transform;
t.parent = bones[index - 1];
t.localRotation = Quaternion.identity;
t.localPosition = new Vector3(0, 1, 0) / (float)Mathf.Sqrt(index);
points.Add(a);
bones.Add(t);
poses.Add(t.worldToLocalMatrix * transform.localToWorldMatrix);
}
tip = new GameObject("tip").transform;
tip.parent = bones[index - 1];
tip.localRotation = Quaternion.identity;
tip.localPosition = new Vector3(0, 1, 0) / (float)Mathf.Sqrt(index);
a = a + new Vector3(0, 1, 0) / (float)Mathf.Sqrt(index);
points.Add(a);
List<int> indices = new List<int>();
List<Vector3> vertices = new List<Vector3>();
int counter = 0;
Vector3[] p = new Vector3[segments];
for (int s = 0; s < segments; s++)
{
p[s] = new Vector3(Mathf.Cos((float)s * Mathf.PI * 2 / (float)segments), 0, Mathf.Sin((float)s * Mathf.PI * 2 / (float)segments));
p[s] *= 0.05f;
}
for (int i = 0; i < bones.Count; i++)
{
for (int s = 0; s < segments; s++)
{
vertices.Add(points[i] + p[s] / (float)Mathf.Sqrt(i + 1.0f) );
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = i, weight0 = 1 });
vertices.Add(points[i + 1] + p[s] / (float)Mathf.Sqrt(i + 2.0f));
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = (i < bones.Count - 1) ? i + 1 : bones.Count - 1, weight0 = 1 });
vertices.Add(points[i] + p[(s + 1) % segments] / (float)Mathf.Sqrt(i + 1.0f));
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = i, weight0 = 1 });
vertices.Add(points[i] + p[(s + 1) % segments] / (float)Mathf.Sqrt(i + 1.0f));
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = i, weight0 = 1 });
vertices.Add(points[i + 1] + p[s] / (float)Mathf.Sqrt(i + 2.0f));
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = (i < bones.Count - 1) ? i + 1 : bones.Count - 1, weight0 = 1 });
vertices.Add(points[i + 1] + p[(s + 1) % segments] / (float)Mathf.Sqrt(i + 2.0f));
indices.Add(counter++);
weights.Add(new BoneWeight() { boneIndex0 = (i < bones.Count - 1) ? i + 1 : bones.Count - 1, weight0 = 1 });
}
}
Mesh mesh = new Mesh();
mesh.vertices = vertices.ToArray();
mesh.triangles = indices.ToArray();
mesh.RecalculateNormals();
mesh.boneWeights = weights.ToArray();
mesh.bindposes = poses.ToArray();
skinnedMeshRenderer.bones = bones.ToArray();
skinnedMeshRenderer.sharedMesh = mesh;
skinnedMeshRenderer.sharedMaterial = material;
lastBone = bones[bones.Count - 1];
}
public void UpdateMesh()
{
for (int i = 0; i < bones.Count; i++)
{
Vector3 f = bones[i].parent.worldToLocalMatrix.MultiplyPoint(m_forceSource).normalized;
Vector3 up = bones[i].worldToLocalMatrix.MultiplyVector(bones[i].parent.up).normalized;
Vector3 v = f / ((float)m_steps - i) * m_forceModule;
Vector3 d = (up + v).normalized;
Quaternion rotation = Quaternion.FromToRotation(up, d);
bones[i].localRotation = rotation;
}
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment