UMiniGame/Assets/Game1/Scripts/RingManager.cs
2025-12-16 13:48:26 +08:00

155 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}