155 lines
4.9 KiB
C#
155 lines
4.9 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
|
||
public class RingManager : MonoBehaviour
|
||
{
|
||
public int initCount = 12;
|
||
public float radius = 3f;
|
||
|
||
[Tooltip("角度间隔")]
|
||
public float splitAngle = 0f;
|
||
[Tooltip("是否一直朝前")]
|
||
public bool isAlwaysForward = true;
|
||
public Transform qiu;
|
||
public float rotationalSpeed = 5f; // 改为角速度(弧度/秒),更直观
|
||
// 旋转力大小(可在Inspector面板调整)
|
||
//public float rotationalForce = 5f;
|
||
|
||
private List<Transform> qiuList = new List<Transform>();
|
||
|
||
|
||
private float beforePositionX = 0;
|
||
private float targetRotationalSpeed = 0;
|
||
private bool isToLeftRotation = false;
|
||
private bool isCanRotation = false;
|
||
void Awake()
|
||
{
|
||
var qiuCollider = qiu.GetComponentInChildren<Collider>();
|
||
float ringLen = 2 * Mathf.PI * radius;
|
||
float qiuRadius = qiuCollider.bounds.extents.magnitude;
|
||
float len = Mathf.FloorToInt(ringLen / (qiuRadius * qiu.localScale.x) / 2);
|
||
|
||
for (int i = 0; i < initCount; i++)
|
||
{
|
||
float angle = Mathf.PI * 2 / initCount * i + splitAngle;
|
||
//if (initCount == 2)
|
||
//{
|
||
// if (i == 1)
|
||
// {
|
||
// angle = Mathf.PI + splitAngle;
|
||
// }
|
||
//}
|
||
//else
|
||
//{
|
||
// angle = 360 - (i / len) * Mathf.PI * 2 + splitAngle; // 角度计算逻辑
|
||
//}
|
||
Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
|
||
pos.x += transform.position.x;
|
||
pos.y += transform.position.y;
|
||
pos.z += transform.position.z;
|
||
|
||
var qiuInst = Instantiate(qiu, pos, Quaternion.identity);
|
||
qiuInst.SetParent(transform, true);
|
||
|
||
// 确保小球有刚体组件并配置参数
|
||
Rigidbody rb = qiuInst.GetComponent<Rigidbody>();
|
||
if (rb == null)
|
||
rb = qiuInst.AddComponent<Rigidbody>();
|
||
|
||
// 配置刚体属性(避免重力影响,冻结不必要的运动)
|
||
rb.useGravity = false;
|
||
rb.constraints = RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezeRotation;
|
||
|
||
qiuList.Add(qiuInst);
|
||
}
|
||
|
||
//targetRotationalSpeed = rotationalSpeed;
|
||
beforePositionX = transform.position.x;
|
||
// 初始施加旋转力
|
||
//ApplyRotationalForce();
|
||
}
|
||
|
||
// 给所有小球施加旋转力的方法
|
||
//void ApplyRotationalForce()
|
||
//{
|
||
// foreach (var ball in qiuList)
|
||
// {
|
||
// Rigidbody rb = ball.GetComponent<Rigidbody>();
|
||
// if (rb == null) continue;
|
||
|
||
// // 1. 计算小球相对于中心的径向向量(从中心指向小球)
|
||
// Vector3 radialDirection = (ball.position - transform.position).normalized;
|
||
|
||
// // 2. 计算切线方向(垂直于径向,绕Y轴旋转的方向)
|
||
// // Vector3.Cross(radialDirection, Vector3.up) = 逆时针旋转方向
|
||
// // Vector3.Cross(Vector3.up, radialDirection) = 顺时针旋转方向
|
||
// Vector3 tangentialDirection = Vector3.Cross(radialDirection, -Vector3.up).normalized;
|
||
|
||
// // 3. 施加切线方向的力(使小球绕中心旋转)
|
||
// //rb.AddForce(tangentialDirection * rotationalForce);
|
||
|
||
// // 可选:如果想保持恒定速度,可直接设置角速度而非持续加力
|
||
// float angularSpeed = rotationalForce / radius;
|
||
// rb.velocity = tangentialDirection * angularSpeed * radius;
|
||
// }
|
||
//}
|
||
|
||
// 可选:在FixedUpdate中持续施加力(会让小球加速旋转)
|
||
void FixedUpdate()
|
||
{
|
||
isCanRotation = true;
|
||
|
||
if (Mathf.Abs(beforePositionX - transform.position.x) < 0.05f)
|
||
{
|
||
isCanRotation = false;
|
||
}
|
||
|
||
if (isCanRotation)
|
||
{
|
||
if (transform.position.x < beforePositionX)
|
||
{
|
||
isToLeftRotation = true;
|
||
}
|
||
else
|
||
{
|
||
isToLeftRotation = false;
|
||
}
|
||
}
|
||
|
||
beforePositionX = transform.position.x;
|
||
if (isCanRotation)
|
||
{
|
||
targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, rotationalSpeed, Time.deltaTime * 5);
|
||
}
|
||
else
|
||
{
|
||
targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, 0, Time.deltaTime * 5);
|
||
}
|
||
// 或逐个旋转小球(如果需要独立控制)
|
||
foreach (var ball in qiuList)
|
||
{
|
||
if (isToLeftRotation)
|
||
{
|
||
ball.RotateAround(transform.position, Vector3.up, -targetRotationalSpeed * Time.deltaTime * Mathf.Rad2Deg);
|
||
}
|
||
else
|
||
{
|
||
ball.RotateAround(transform.position, Vector3.up, targetRotationalSpeed * Time.deltaTime * Mathf.Rad2Deg);
|
||
}
|
||
if (isAlwaysForward)
|
||
{
|
||
ball.eulerAngles = Vector3.zero;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
foreach (var ball in qiuList)
|
||
{
|
||
Destroy(ball.gameObject);
|
||
}
|
||
}
|
||
} |