using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class Bei_sai_er : MonoBehaviour
{
public Transform startTrans;
public Transform endTrans;
[Header("高度")]
public float height;
[Header("顶点移动偏移")]
public float forward_distance=0.5f;
[Header("路径点数量")]
public int resolution;
[Header("目标点偏移")]
public Vector3 offset;
[Header("line_render")]
public LineRenderer _lineRender;
[Header("投掷的物品")]
public Transform grenade;
//路径点arr
private Vector3[] _path;
private Vector3 startPoint;
private Vector3 endPoint;
private Vector3 bezierControlPoint;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
Line_show();
}
if (Input.GetMouseButtonUp(0))
{
_lineRender.gameObject.SetActive(false);
if (_path!=null)
{
grenade.DOPath(_path, 0.8f).SetLookAt(0).SetEase(Ease.Linear);
}
}
}
/// <param name="t">0到1的值,0获取曲线的起点,1获得曲线的终点</param>
/// <param name="start">曲线的起始位置</param>
/// <param name="center">决定曲线形状的控制点</param>
/// <param name="end">曲线的终点</param>
public static Vector3 GetBezierPoint(float t, Vector3 start, Vector3 center, Vector3 end)
{
return (1 - t) * (1 - t) * start + 2 * t * (1 - t) * center + t * t * end;
}
private void Line_show()
{
startPoint = startTrans.position;
Ray ray_demo = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray_demo,out hit, Mathf.Infinity))
{
if (hit.transform .name== "Plane")
{
_lineRender.startColor=Color.yellow;
_lineRender.endColor = Color.green;
}
else
{
_lineRender.startColor = Color.red;
_lineRender.endColor = Color.red;
}
endPoint = hit.point + offset;
_lineRender.gameObject.SetActive(true);
bezierControlPoint = (startPoint + endPoint) * forward_distance + (Vector3.up * height);
_path = new Vector3[resolution];//resolution为int类型,表示要取得路径点数量,值越大,取得的路径点越多,曲线最后越平滑
for (int i = 0; i < resolution; i++)
{
var t = (i + 1) / (float)resolution;//归化到0~1范围
_path[i] = GetBezierPoint(t, startPoint, bezierControlPoint, endPoint);//使用贝塞尔曲线的公式取得t时的路径点
}
_lineRender.positionCount = _path.Length;
_lineRender.SetPositions(_path);
}
else
{
Vector3 mousePosInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
endPoint = mousePosInWorld;
_path = new Vector3[resolution];//resolution为int类型,表示要取得路径点数量,值越大,取得的路径点越多,曲线最后越平滑
for (int i = 0; i < resolution; i++)
{
var t = (i + 1) / (float)resolution;//归化到0~1范围
_path[i] = GetBezierPoint(t, startPoint, bezierControlPoint, endPoint);//使用贝塞尔曲线的公式取得t时的路径点
}
_lineRender.positionCount = _path.Length;
_lineRender.SetPositions(_path);
}
}
}
以下为模拟电线连接线
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bezier : MonoBehaviour
{
public static Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t)
{
t = Mathf.Clamp01(t);
float oneMinusT = 1f - t;
return
oneMinusT * oneMinusT * p0 +
2f * oneMinusT * t * p1 +
t * t * p2;
}
}
using UnityEngine;
using System.Collections.Generic;
using RTEditor;
public struct BezierLineSegment
{
public Vector3 fromPoint;
public Vector3 toPoint;
public Vector3 controlPoint;
public Quaternion fromDir;
public Quaternion toDir;
public void CalculateDir()
{
fromDir = Quaternion.FromToRotation(Vector3.forward, controlPoint - fromPoint);
toDir = Quaternion.FromToRotation(Vector3.forward, toPoint - controlPoint);
}
public bool IsStraight()
{
return fromDir == toDir;
}
}
[ExecuteInEditMode]
public class BezierPipe : MonoBehaviour
{
public float cornerScale = 1f;
[Range(1, 100)]
public int cornerStep = 10;
[Range(2, 100)]
public int circleStep = 10;
public float r = 0.1f;
public Transform point1;
public Vector3 point1Dir = Vector3.up;
public Transform point2;
public Vector3 point2Dir = Vector3.up;
public bool update = false;
public Mesh mesh;
List<Vector3> verts = new List<Vector3>();
List<int> triangles = new List<int>();
private MeshCollider mc;
[Header("控制弯曲下垂度")]
public Vector3 center_control;
// Use this for initialization
void Start()
{
mesh = new Mesh();
mesh.name = "Pipe";
MeshFilter mf = GetComponent<MeshFilter>();
if (mf != null)
{
mf.sharedMesh = mesh;
}
mc = GetComponent<MeshCollider>();
if (mc != null)
{
mc.sharedMesh = mesh;
}
BuildMesh();
}
// Update is called once per frame
void Update()
{
if (update)
{
BuildMesh();
}
}
void GetCirclePoint(Vector3 pos, Quaternion dir, bool draw)
{
for (int a = 0; a <= circleStep; a++)
{
float p = 2 * Mathf.PI * a / circleStep;
Vector3 cp = new Vector3(r * Mathf.Cos(p), r * Mathf.Sin(p), 0);
cp = dir * cp + pos;
//if(draw)
// Gizmos.DrawSphere(cp, 0.0005f);
cp = transform.worldToLocalMatrix.MultiplyPoint(cp);
//cp += transform.position;
verts.Add(cp);
}
}
void SetTriangles()
{
triangles.Clear();
for (int i = 0; i < verts.Count - circleStep - 2; i++)
{
triangles.Add(i);
triangles.Add(i + 1);
triangles.Add(i + circleStep + 1);
triangles.Add(i + circleStep + 1);
triangles.Add(i + 1);
triangles.Add(i + circleStep + 2);
}
mesh.triangles = triangles.ToArray();
}
public void BuildMesh()
{
if (point1 != null && point2 != null)
{
verts.Clear();
float scale = cornerScale;
float length = (point1.position - point2.position).magnitude / 4;
if (scale > length)
{
scale = length;
}
BezierLineSegment[] segments = new BezierLineSegment[3];
segments[0].fromPoint = point1.position;
point1Dir.Normalize();
segments[0].controlPoint = point1.position + point1.rotation * point1Dir * scale;
segments[2].toPoint = point2.position;
point2Dir.Normalize();
segments[2].controlPoint = point2.position + point2.rotation * point2Dir * scale;
segments[1].controlPoint = (segments[0].controlPoint + segments[2].controlPoint) / 2+ center_control;
segments[0].toPoint = segments[1].fromPoint = segments[0].controlPoint + (segments[1].controlPoint - segments[0].controlPoint).normalized * scale;
segments[1].toPoint = segments[2].fromPoint = segments[2].controlPoint + (segments[1].controlPoint - segments[2].controlPoint).normalized * scale;
transform.position = segments[1].controlPoint;
segments[1].CalculateDir();
transform.rotation = segments[1].fromDir;
// Debug.Log (transform.eulerAngles);
foreach (var segment in segments)
{
segment.CalculateDir();
if (segment.IsStraight())
{
GetCirclePoint(segment.fromPoint, segment.fromDir, true);
GetCirclePoint(segment.controlPoint, segment.fromDir, false);
GetCirclePoint(segment.toPoint, segment.toDir, true);
//Gizmos.DrawLine(segment.fromPoint, segment.controlPoint);
//Gizmos.DrawLine(segment.controlPoint, segment.toPoint);
}
else
{
GetCirclePoint(segment.fromPoint, segment.fromDir, true);
Vector3 p1 = segment.fromPoint;
for (int s = 1; s < cornerStep; s++)
{
float t = (float)s / cornerStep;
Vector3 p2 = Bezier.GetPoint(segment.fromPoint, segment.controlPoint, segment.toPoint, t);
//Quaternion dir = Quaternion.FromToRotation(Vector3.forward, p2 - p1);
Quaternion dir = Quaternion.Lerp(segment.fromDir, segment.toDir, t);
GetCirclePoint(p2, dir, false);
//Gizmos.DrawLine(p1, p2);
p1 = p2;
}
GetCirclePoint(segment.toPoint, segment.toDir, true);
//Gizmos.DrawLine(p1,segment.toPoint);
}
}
mesh.Clear();
mesh.vertices = verts.ToArray();
SetTriangles();
mesh.RecalculateNormals();
if (mc != null)
{
mc.sharedMesh = mesh;
}
}
}
}