英文:
Unity : pool game emulator : The cue ball didn't bounce back as expected; instead, it continued to travel along the table's edge
问题
以下是您提供的内容的中文翻译:
球杆在与桌边碰撞后,没有如预期般反弹;相反,它继续沿着桌边行进,紧紧贴着边缘。
仿真
以下是边缘和球的物理材料:
球的物理材料
边缘的物理材料
我尝试过调整各种系数,但可能会导致过度的弹性或球仍然继续沿着桌子的边缘行进。
以下是提供球杆速度和方向的C#代码:
using System.IO;
using UnityEngine;
using System.Collections;
public class CueBallController : MonoBehaviour
{
private string cueball_position_Path = "D:/Unity Project/testtest/Assets/Resources/cueball_position.json";
private string HitParams_Path = "D:/Unity Project/testtest/Assets/Resources/HitParams.json";
[System.Serializable]
public class HitParams
{
public float HitSpeed;
public Vector3 HitDirection;
}
HitParams LasthitParams;
private Rigidbody rb;
public float stationaryThreshold = 0.01f;
private bool allBallsStationary = false;
// Start is called before the first frame update
void Start()
{
LoadInitialPosition(cueball_position_Path);
rb = GetComponent<Rigidbody>();
LasthitParams = new HitParams();
}
// Update is called once per frame
void Update()
{
allBallsStationary = CheckIfAllBallsAreStationary();
if (allBallsStationary)
{
// 从JSON文件加载初始参数
HitParams newHitParams = LoadHitParams(HitParams_Path);
if (newHitParams != null && (newHitParams.HitSpeed != LasthitParams.HitSpeed || newHitParams.HitDirection != LasthitParams.HitDirection))
{
// 规范化初始方向并应用初始速度
Vector3 hitVelocity = newHitParams.HitDirection.normalized * newHitParams.HitSpeed;
StartCoroutine(MoveWithDelay(2.0f, hitVelocity));
LasthitParams = newHitParams;
}
}
}
private void LoadInitialPosition(string path)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
Vector3 position = JsonUtility.FromJson<Vector3>(json);
transform.position = position;
}
else
{
Debug.LogError("未找到JSON文件:" + path);
}
}
private IEnumerator MoveWithDelay(float delay, Vector3 hitVelocity)
{
yield return new WaitForSeconds(delay);
rb.velocity = hitVelocity;
}
private HitParams LoadHitParams(string path)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
HitParams loadedHitParams = JsonUtility.FromJson<HitParams>(json);
return loadedHitParams;
}
else
{
Debug.LogError("未找到JSON文件:" + path);
return null;
}
}
private bool CheckIfAllBallsAreStationary()
{
GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");
float angularThreshold = 0.01f;
foreach (GameObject ball in balls)
{
Rigidbody ballRigidbody = ball.GetComponent<Rigidbody>();
if (ballRigidbody != null &&
(ballRigidbody.velocity.magnitude > stationaryThreshold ||
ballRigidbody.angularVelocity.magnitude > angularThreshold))
{
return false;
}
}
if (!rb.IsSleeping()) return false;
return true;
}
}
英文:
The cue ball, after colliding with the table edge, didn't bounce back as expected; instead, it continued to travel along the table's rail, closely hugging its edge.
emulation
The following are the physical materials of the edge and the ball:
ball physical material
edge physical material
I have tried adjusting various coefficients, but it may either result in excessive elasticity or the ball still continuing to travel along the table's edge.
The following is the C# code which provide the velocity and direction of cue ball
using System.IO;
using UnityEngine;
using System.Collections;
public class CueBallController : MonoBehaviour
{
private string cueball_position_Path = "D:/Unity Project/testtest/Assets/Resources/cueball_position.json";
private string HitParams_Path = "D:/Unity Project/testtest/Assets/Resources/HitParams.json";
[System.Serializable]
public class HitParams
{
public float HitSpeed;
public Vector3 HitDirection;
}
HitParams LasthitParams;
private Rigidbody rb;
public float stationaryThreshold = 0.01f;
private bool allBallsStationary = false;
// Start is called before the first frame update
void Start()
{
LoadInitialPosition(cueball_position_Path);
rb = GetComponent<Rigidbody>();
LasthitParams = new HitParams();
}
// Update is called once per frame
void Update()
{
allBallsStationary = CheckIfAllBallsAreStationary();
if (allBallsStationary)
{
// Load initial parameters from JSON file
HitParams newHitParams = LoadHitParams(HitParams_Path);
if (newHitParams != null && (newHitParams.HitSpeed != LasthitParams.HitSpeed || newHitParams.HitDirection != LasthitParams.HitDirection))
{
// Normalize the initial direction and apply the initial speed
Vector3 hitVelocity = newHitParams.HitDirection.normalized * newHitParams.HitSpeed;
StartCoroutine(MoveWithDelay(2.0f, hitVelocity));
LasthitParams = newHitParams;
}
}
}
private void LoadInitialPosition(string path)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
Vector3 position = JsonUtility.FromJson<Vector3>(json);
transform.position = position;
}
else
{
Debug.LogError("JSON file not found at: " + path);
}
}
private IEnumerator MoveWithDelay(float delay, Vector3 hitVelocity)
{
yield return new WaitForSeconds(delay);
rb.velocity = hitVelocity;
}
private HitParams LoadHitParams(string path)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
HitParams loadedHitParams = JsonUtility.FromJson<HitParams>(json);
return loadedHitParams;
}
else
{
Debug.LogError("JSON file not found at: " + path);
return null;
}
}
private bool CheckIfAllBallsAreStationary()
{
GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");
float angularThreshold = 0.01f;
foreach (GameObject ball in balls)
{
Rigidbody ballRigidbody = ball.GetComponent<Rigidbody>();
if (ballRigidbody != null &&
(ballRigidbody.velocity.magnitude > stationaryThreshold ||
ballRigidbody.angularVelocity.magnitude > angularThreshold))
{
return false;
}
}
if (!rb.IsSleeping()) return false;
return true;
}
}
答案1
得分: 3
这个问题与默认的物理配置有关。低速度碰撞被视为非弹性碰撞,弹跳被忽略(即使在物理材质中设置了也是如此)。这是为了在有一堆缓慢移动的刚体相互碰撞时平稳物理模拟。
对于3D物理,你需要在Edit->Project Settings->Physics
下降Bounce Threshold
。
对于2D物理,你需要在Edit->Project Settings->Physics 2D
下降velocityThreshold
。
不要将值设置得太低,大约0.1应该足够。
英文:
This issue has to do with the default physics configuration. Low velocity impacts are treated as inelastic collisions and the bounce is ignored (even if you set it up in your physics material). This is done to help calm down the physics simulation when you have a pile of slow moving rigid bodies all colliding with each other.
For 3D physics you need to lower the Bounce Threshold
under Edit->Project Settings->Physics
For 2D physcis you need to lower the velocityThreshold
under Edit->Project Settings->Physics 2D
Don't make the value too low, something like 0.1 should be enough.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论