Files
2026-03-04 10:03:45 +08:00

197 lines
5.6 KiB
C#

using System;
using UnityEngine;
namespace Artngame.TEM
{
public class Tornado : MonoBehaviour
{
public GameObject skeletonCylinder;
public GameObject tornadoPSObj;
public GameObject groundPSObj;
public GameObject tornadoTopPSObj;
public GameObject junkPSObj;
public GameObject chaseObj;
public GameObject chaseRotateObj;
public GameObject targetObj;
public GameObject debugSphere;
public bool isDebug;
[Header("Tornado data")]
public AnimationCurve tornadoShape;
public float tornadoSpeed = 10f;
public float tornadoRotSpeed = 1f;
public float tornadoSpinSpeed = 1f;
public float tornadoHeight = 50f;
public float topRadius = 20f;
public int pieces = 10;
public float m;
public float k;
public float c;
public float aboveFactor = 1f;
public float belowFactor = 1f;
public float chaseFactor = 1f;
[NonSerialized]
public Transform[] skeletonPiecesArray;
private Vector3[] posNew;
private Vector3[] posOld;
private Vector3[] velArray;
private Vector3 oldChasePos;
private void Start()
{
BuildTornado();
posNew = new Vector3[pieces];
posOld = new Vector3[pieces];
velArray = new Vector3[pieces];
for (int i = 0; i < pieces; i++)
{
posNew[i] = Vector3.zero;
posOld[i] = skeletonPiecesArray[i].position;
velArray[i] = Vector3.zero;
}
chaseObj.transform.position = base.transform.position;
TornadoDust component = tornadoPSObj.GetComponent<TornadoDust>();
component.skeletonPiecesArray = skeletonPiecesArray;
component.tornadoShape = tornadoShape;
component.tornadoHeight = tornadoHeight;
component.topRadius = topRadius;
component.tornadoTrans = base.transform;
component.rotationSpeed = tornadoSpinSpeed;
TornadoDust component2 = junkPSObj.GetComponent<TornadoDust>();
component2.skeletonPiecesArray = skeletonPiecesArray;
component2.tornadoShape = tornadoShape;
component2.tornadoHeight = tornadoHeight;
component2.topRadius = topRadius;
component2.tornadoTrans = base.transform;
component2.rotationSpeed = tornadoSpinSpeed;
TornadoDustTop component3 = tornadoTopPSObj.GetComponent<TornadoDustTop>();
component3.bottomRadius = topRadius;
component3.rotationSpeed = tornadoSpinSpeed;
component3.tornadoHeight = tornadoHeight;
}
private void Update()
{
groundPSObj.GetComponent<GroundDust>().rotationSpeed = tornadoSpinSpeed;
tornadoPSObj.GetComponent<TornadoDust>().rotationSpeed = tornadoSpinSpeed;
MoveTornado();
}
private void FixedUpdate()
{
TornadoDynamics();
}
private void BuildTornado()
{
AddSkeletonPieces();
}
private void AddSkeletonPieces()
{
skeletonPiecesArray = new Transform[pieces];
float num = tornadoHeight / (float)pieces;
float num2 = 0f;
for (int i = 0; i < pieces; i++)
{
GameObject gameObject = UnityEngine.Object.Instantiate(skeletonCylinder);
Vector3 localScale = skeletonCylinder.transform.localScale;
localScale.z = num / 2f;
gameObject.transform.localScale = localScale;
Vector3 position = base.transform.position;
position.y = num2;
gameObject.transform.position = position;
gameObject.transform.parent = base.transform;
skeletonPiecesArray[i] = gameObject.transform;
num2 += num;
}
}
private void MoveTornado()
{
Vector3 target = targetObj.transform.position - chaseObj.transform.position;
Vector3 forward = Vector3.RotateTowards(chaseObj.transform.forward, target, tornadoRotSpeed * Time.deltaTime, 0f);
chaseObj.transform.rotation = Quaternion.LookRotation(forward);
chaseObj.transform.Translate(Vector3.forward * tornadoSpeed * Time.deltaTime);
float num = 40f;
float num2 = 300f;
Vector3 position = chaseObj.transform.position;
Vector3 position2 = chaseRotateObj.transform.position;
chaseRotateObj.transform.position += position - oldChasePos;
float magnitude = (position2 - position).magnitude;
Vector3 normalized = (position2 - position).normalized;
chaseRotateObj.transform.position += (num2 - magnitude) * normalized;
chaseRotateObj.transform.RotateAround(position, base.transform.up, num * Time.deltaTime);
oldChasePos = position;
}
private void TornadoDynamics()
{
Vector3 position = chaseObj.transform.position;
Vector3 position2 = chaseRotateObj.transform.position;
position.y = 0f;
float num = 0.02f;
for (int i = 0; i < pieces; i++)
{
Vector3 vector = posOld[i];
Vector3 zero = Vector3.zero;
zero = ((i != 0) ? ((i != pieces - 1) ? (((0f - this.k) * (vector - posOld[i - 1]) * belowFactor + this.k * (posOld[i + 1] - vector) * aboveFactor) / m) : (((0f - this.k) * (vector - position) + this.k * (posOld[i - 1] - vector) * belowFactor) / m)) : (((0f - this.k) * (vector - posOld[i + 1]) * aboveFactor - this.k * (vector - position2) * chaseFactor) / m));
zero -= c * velArray[i] / m;
posNew[i] = vector + num * velArray[i];
posNew[i].y = posOld[i].y;
velArray[i] += num * zero;
}
for (int j = 0; j < pieces; j++)
{
Vector3 position3 = posNew[j];
position3.y = skeletonPiecesArray[j].position.y;
skeletonPiecesArray[j].position = position3;
posOld[j] = posNew[j];
}
for (int k = 0; k < pieces; k++)
{
if (k > 0)
{
skeletonPiecesArray[k].LookAt(skeletonPiecesArray[k - 1].position);
}
else
{
skeletonPiecesArray[k].LookAt(skeletonPiecesArray[k].position + -Vector3.up);
}
}
Vector3 position4 = posNew[0];
position4.y = 0f;
groundPSObj.transform.position = position4;
Vector3 position5 = posNew[posNew.Length - 1];
position5.y = tornadoHeight;
tornadoTopPSObj.transform.position = position5;
}
}
}