·
This commit is contained in:
parent
f9dbe4765d
commit
07e5633102
@ -283,6 +283,7 @@ MonoBehaviour:
|
||||
radius: 1.8
|
||||
splitAngle: 0
|
||||
isAlwaysForward: 1
|
||||
maxRotationAngle: 170
|
||||
qiu: {fileID: 1083892317890881295, guid: 83c0dc6728f2e3a4ab110648310fc920, type: 3}
|
||||
rotationalSpeed: 5
|
||||
--- !u!1 &49123918
|
||||
@ -3116,6 +3117,7 @@ MonoBehaviour:
|
||||
radius: 1.8
|
||||
splitAngle: 0
|
||||
isAlwaysForward: 1
|
||||
maxRotationAngle: 60
|
||||
qiu: {fileID: 1083892317890881295, guid: 83c0dc6728f2e3a4ab110648310fc920, type: 3}
|
||||
rotationalSpeed: 2.8
|
||||
--- !u!1 &1581003589
|
||||
|
||||
@ -12,95 +12,55 @@ public class RingManager : MonoBehaviour
|
||||
public float splitAngle = 0f;
|
||||
[Tooltip("ÊÇ·ñÒ»Ö±³¯Ç°")]
|
||||
public bool isAlwaysForward = true;
|
||||
[Tooltip("最大左右旋转角度绝对值")]
|
||||
public float maxRotationAngle = 90; // 限制角度
|
||||
public Transform qiu;
|
||||
public float rotationalSpeed = 5f; // 改为角速度(弧度/秒),更直观
|
||||
// 旋转力大小(可在Inspector面板调整)
|
||||
//public float rotationalForce = 5f;
|
||||
public float rotationalSpeed = 5f;
|
||||
|
||||
private List<Transform> qiuList = new List<Transform>();
|
||||
|
||||
|
||||
private float beforePositionX = 0;
|
||||
private float targetRotationalSpeed = 0;
|
||||
private bool isToLeftRotation = false;
|
||||
private bool isCanRotation = false;
|
||||
|
||||
// 【新增】用于记录当前整体偏离初始位置的角度
|
||||
private float currentRingAngle = 0f;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// ... (Awake中的初始化代码保持不变) ...
|
||||
var qiuCollider = qiu.GetComponentInChildren<Collider>();
|
||||
// 注意:如果 qiuCollider 为空这里会报错,建议加个判空
|
||||
float ringLen = 2 * Mathf.PI * radius;
|
||||
float qiuRadius = qiuCollider.bounds.extents.magnitude;
|
||||
// 简单防错
|
||||
float qiuRadius = qiuCollider != null ? qiuCollider.bounds.extents.magnitude : 0.5f;
|
||||
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;
|
||||
pos += transform.position;
|
||||
|
||||
var qiuInst = Instantiate(qiu, pos, Quaternion.identity);
|
||||
qiuInst.SetParent(transform, true);
|
||||
|
||||
// 确保小球有刚体组件并配置参数
|
||||
Rigidbody rb = qiuInst.GetComponent<Rigidbody>();
|
||||
if (rb == null)
|
||||
rb = qiuInst.AddComponent<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()
|
||||
{
|
||||
// 1. 运动状态检测
|
||||
isCanRotation = true;
|
||||
|
||||
if (Mathf.Abs(beforePositionX - transform.position.x) < 0.03f)
|
||||
{
|
||||
isCanRotation = false;
|
||||
@ -109,16 +69,14 @@ public class RingManager : MonoBehaviour
|
||||
if (isCanRotation)
|
||||
{
|
||||
if (transform.position.x < beforePositionX)
|
||||
{
|
||||
isToLeftRotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isToLeftRotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
beforePositionX = transform.position.x;
|
||||
|
||||
// 2. 计算目标速度(平滑插值)
|
||||
if (isCanRotation)
|
||||
{
|
||||
targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, rotationalSpeed, Time.deltaTime * 5);
|
||||
@ -127,20 +85,54 @@ public class RingManager : MonoBehaviour
|
||||
{
|
||||
targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, 0, Time.deltaTime * 5);
|
||||
}
|
||||
// 或逐个旋转小球(如果需要独立控制)
|
||||
foreach (var ball in qiuList)
|
||||
|
||||
// 如果速度非常小,就不进行旋转计算了,节省性能
|
||||
if (targetRotationalSpeed < 0.01f) return;
|
||||
|
||||
// 3. 计算本帧【原本想要】旋转的角度量
|
||||
float rotationStep = targetRotationalSpeed * Time.deltaTime * Mathf.Rad2Deg;
|
||||
|
||||
// 确定方向符号 (左移往负方向转,右移往正方向转,根据你的需求调整正负)
|
||||
// 假设:向左移动(isToLeftRotation=true)对应负角度(-),向右对应正角度(+)
|
||||
float direction = isToLeftRotation ? -1f : 1f;
|
||||
float finalStep = rotationStep * direction;
|
||||
|
||||
// 4. 【核心逻辑】限制角度
|
||||
// 预测下一帧的角度
|
||||
float nextAngle = currentRingAngle + finalStep;
|
||||
|
||||
// 如果预测角度超出了范围,需要进行截断
|
||||
if (nextAngle > maxRotationAngle)
|
||||
{
|
||||
if (isToLeftRotation)
|
||||
// 如果超出了最大值,本帧只转到最大值剩下的那一丢丢
|
||||
finalStep = maxRotationAngle - currentRingAngle;
|
||||
currentRingAngle = maxRotationAngle;
|
||||
}
|
||||
else if (nextAngle < -maxRotationAngle)
|
||||
{
|
||||
// 如果超出了最小值
|
||||
finalStep = -maxRotationAngle - currentRingAngle;
|
||||
currentRingAngle = -maxRotationAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没超出,直接累加
|
||||
currentRingAngle = nextAngle;
|
||||
}
|
||||
|
||||
// 5. 应用旋转
|
||||
// 只有当 finalStep 不接近0时才执行,避免浮点数抖动
|
||||
if (Mathf.Abs(finalStep) > 0.0001f)
|
||||
{
|
||||
foreach (var ball in qiuList)
|
||||
{
|
||||
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;
|
||||
// 使用计算好的 finalStep 进行旋转
|
||||
ball.RotateAround(transform.position, Vector3.up, finalStep);
|
||||
|
||||
if (isAlwaysForward)
|
||||
{
|
||||
ball.eulerAngles = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,7 +141,7 @@ public class RingManager : MonoBehaviour
|
||||
{
|
||||
foreach (var ball in qiuList)
|
||||
{
|
||||
Destroy(ball.gameObject);
|
||||
if (ball != null) Destroy(ball.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user