VR模拟枪支打靶,消灭鬼怪,换弹以及上弦等等硬核枪支操作。 使用HTCVive设备,开启SteamVR进行游玩。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

287 lines
8.5 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class ME_TrailRendererNoise : MonoBehaviour
{
[Range(0.01f, 10)]
public float MinVertexDistance = 0.1f;
public float VertexTime = 1;
public float TotalLifeTime = 3;
public bool SmoothCurves = false;
public bool IsRibbon;
[Range(0.001f, 10)] public float Frequency = 1f;
[Range(0.001f, 10)] public float TimeScale = 0.1f;
[Range(0.001f, 10)] public float Amplitude = 1;
public float Gravity = 1;
public float TurbulenceStrength = 1;
public bool Autodestruct;
LineRenderer lineRenderer;
Transform t;
Vector3 prevPos;
List<Vector3> points = new List<Vector3>(500);
List<float> lifeTimes = new List<float>(500);
List<Vector3> velocities = new List<Vector3>(500);
private float randomOffset;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.useWorldSpace = true;
t = transform;
prevPos = t.position;
points.Insert(0, t.position);
lifeTimes.Insert(0, VertexTime);
velocities.Insert(0, Vector3.zero);
randomOffset = Random.Range(0, 10000000) / 1000000f;
}
private void OnEnable()
{
points.Clear();
lifeTimes.Clear();
velocities.Clear();
if (Autodestruct) Destroy(gameObject, TotalLifeTime);
}
void Update()
{
AddNewPoints();
UpdatetPoints();
if (SmoothCurves && points.Count > 2)
{
UpdateLineRendererBezier();
}
else
{
UpdateLineRenderer();
}
}
void AddNewPoints()
{
if ((t.position - prevPos).magnitude > MinVertexDistance ||
IsRibbon && points.Count == 0 ||
IsRibbon && points.Count > 0 && (t.position - points[0]).magnitude > MinVertexDistance)
{
prevPos = t.position;
points.Insert(0, t.position);
lifeTimes.Insert(0, VertexTime);
velocities.Insert(0, Vector3.zero);
}
}
void UpdatetPoints()
{
for (var i = 0; i < lifeTimes.Count; i++)
{
lifeTimes[i] -= Time.deltaTime;
if (lifeTimes[i] <= 0)
{
var removedRange = lifeTimes.Count - i;
lifeTimes.RemoveRange(i, removedRange);
points.RemoveRange(i, removedRange);
velocities.RemoveRange(i, removedRange);
return;
}
else
{
CalculateTurbuelence(points[i], TimeScale, Frequency, Amplitude, Gravity, i);
}
}
}
void UpdateLineRendererBezier()
{
if (SmoothCurves && points.Count > 2)
{
InterpolateBezier(points, SmoothCurvesScale);
var bezierPositions = GetDrawingPoints();
lineRenderer.positionCount = bezierPositions.Count - 1;
lineRenderer.SetPositions(bezierPositions.ToArray());
}
}
void UpdateLineRenderer()
{
lineRenderer.positionCount = Mathf.Clamp(points.Count - 1, 0, Int32.MaxValue);
lineRenderer.SetPositions(points.ToArray());
}
void CalculateTurbuelence(Vector3 position, float speed, float scale, float height, float gravity, int index)
{
float sTime = Time.timeSinceLevelLoad * speed + randomOffset;
float xCoord = position.x * scale + sTime;
float yCoord = position.y * scale + sTime + 10;
float zCoord = position.z * scale + sTime + 25;
position.x = (Mathf.PerlinNoise(yCoord, zCoord) - 0.5f) * height * Time.deltaTime;
position.y = (Mathf.PerlinNoise(xCoord, zCoord) - 0.5f) * height * Time.deltaTime - gravity * Time.deltaTime;
position.z = (Mathf.PerlinNoise(xCoord, yCoord) - 0.5f) * height * Time.deltaTime;
points[index] += position * TurbulenceStrength;
}
private List<Vector3> controlPoints = new List<Vector3>();
private int curveCount;
private const float MinimumSqrDistance = 0.01f;
private const float DivisionThreshold = -0.99f;
private const float SmoothCurvesScale = 0.5f;
#region Bezier
public void InterpolateBezier(List<Vector3> segmentPoints, float scale)
{
controlPoints.Clear();
if (segmentPoints.Count < 2)
return;
for (int i = 0; i < segmentPoints.Count; i++)
{
if (i == 0) // is first
{
Vector3 p1 = segmentPoints[i];
Vector3 p2 = segmentPoints[i + 1];
Vector3 tangent = (p2 - p1);
Vector3 q1 = p1 + scale * tangent;
controlPoints.Add(p1);
controlPoints.Add(q1);
}
else if (i == segmentPoints.Count - 1) //last
{
Vector3 p0 = segmentPoints[i - 1];
Vector3 p1 = segmentPoints[i];
Vector3 tangent = (p1 - p0);
Vector3 q0 = p1 - scale * tangent;
controlPoints.Add(q0);
controlPoints.Add(p1);
}
else
{
Vector3 p0 = segmentPoints[i - 1];
Vector3 p1 = segmentPoints[i];
Vector3 p2 = segmentPoints[i + 1];
Vector3 tangent = (p2 - p0).normalized;
Vector3 q0 = p1 - scale * tangent * (p1 - p0).magnitude;
Vector3 q1 = p1 + scale * tangent * (p2 - p1).magnitude;
controlPoints.Add(q0);
controlPoints.Add(p1);
controlPoints.Add(q1);
}
}
curveCount = (controlPoints.Count - 1) / 3;
}
public List<Vector3> GetDrawingPoints()
{
List<Vector3> drawingPoints = new List<Vector3>();
for (int curveIndex = 0; curveIndex < curveCount; curveIndex++)
{
List<Vector3> bezierCurveDrawingPoints = FindDrawingPoints(curveIndex);
if (curveIndex != 0)
//remove the fist point, as it coincides with the last point of the previous Bezier curve.
bezierCurveDrawingPoints.RemoveAt(0);
drawingPoints.AddRange(bezierCurveDrawingPoints);
}
return drawingPoints;
}
private List<Vector3> FindDrawingPoints(int curveIndex)
{
List<Vector3> pointList = new List<Vector3>();
Vector3 left = CalculateBezierPoint(curveIndex, 0);
Vector3 right = CalculateBezierPoint(curveIndex, 1);
pointList.Add(left);
pointList.Add(right);
FindDrawingPoints(curveIndex, 0, 1, pointList, 1);
return pointList;
}
private int FindDrawingPoints(int curveIndex, float t0, float t1,
List<Vector3> pointList, int insertionIndex)
{
Vector3 left = CalculateBezierPoint(curveIndex, t0);
Vector3 right = CalculateBezierPoint(curveIndex, t1);
if ((left - right).sqrMagnitude < MinimumSqrDistance)
return 0;
float tMid = (t0 + t1) / 2;
Vector3 mid = CalculateBezierPoint(curveIndex, tMid);
Vector3 leftDirection = (left - mid).normalized;
Vector3 rightDirection = (right - mid).normalized;
if (Vector3.Dot(leftDirection, rightDirection) > DivisionThreshold || Mathf.Abs(tMid - 0.5f) < 0.0001f)
{
int pointsAddedCount = 0;
pointsAddedCount += FindDrawingPoints(curveIndex, t0, tMid, pointList, insertionIndex);
pointList.Insert(insertionIndex + pointsAddedCount, mid);
pointsAddedCount++;
pointsAddedCount += FindDrawingPoints(curveIndex, tMid, t1, pointList, insertionIndex + pointsAddedCount);
return pointsAddedCount;
}
return 0;
}
public Vector3 CalculateBezierPoint(int curveIndex, float t)
{
int nodeIndex = curveIndex * 3;
Vector3 p0 = controlPoints[nodeIndex];
Vector3 p1 = controlPoints[nodeIndex + 1];
Vector3 p2 = controlPoints[nodeIndex + 2];
Vector3 p3 = controlPoints[nodeIndex + 3];
return CalculateBezierPoint(t, p0, p1, p2, p3);
}
private Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float uuu = uu * u;
float ttt = tt * t;
Vector3 p = uuu * p0; //first term
p += 3 * uu * t * p1; //second term
p += 3 * u * tt * p2; //third term
p += ttt * p3; //fourth term
return p;
}
#endregion
}