I am trying to make a pool game. What I want to happen is that when the cue ball hits the floor or falls through the holes, it will be "spawned" back to its original position, allowing the player to strike the cue ball again. My problem is that I have another script that dictates that if the cue ball is in motion; the stick will be deactivated.
if (GetComponent<Rigidbody>().velocity.magnitude > 0 && GetComponent<Rigidbody>().angularVelocity.magnitude > 0)
{
Debug.Log("Is Moving");
Stick.gameObject.SetActive(false);
}
else
{
Debug.Log("Is not Moving");
Stick.gameObject.SetActive(true);
}
and after the cue ball is "spawned" back to its first position, even after setting its velocity to zero, it still moves a tiny bit, making the stick unable to appear. The Table is perfectly level, I checked.
This is my code for the "Spawning" of the ball to its original position:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballDetector : MonoBehaviour
{
public GameObject cueBall;
public GameObject poolstick;
public float x;
public float y;
public float z;
public Rigidbody rb;
// Start is called before the first frame update
void Start()
{
x = (float)cueBall.transform.position.x;
y = (float)cueBall.transform.position.y;
z = (float)cueBall.transform.position.z;
rb = cueBall.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter(Collider other)
{
Debug.Log(other.gameObject.name);
if (other.gameObject.name == "Cue Ball")
{
cueBall.transform.position = new Vector3(x, y, z);
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
//poolstick.SetActive(true);
}
}
}
CodePudding user response:
There is not really enough information to tell what is causing your issue.
The rigid body might still have some angular velocity or other momentum left. Try to put rb.Sleep() before spawning and also set rb.angularVelocity and rb.velocity to 0. When done with all other code put rb.WakeUp().
It might also be because you spawn the ball at an altitude. Depending on your bounciness settings it might make the ball bounce almost to infinity.
A general advice to stop things from moving for all eternity is to check if the velocity is smaller than a certain small value, and if so set the velocity and angular velocity to 0.
CodePudding user response:
A scrappy fix for this will be to first check the magnitude of the velocity of the ball after the position is reset with
Debug.Log(GetComponent<Rigidbody>().velocity.magnitude);
Debug.Log(GetComponent<Rigidbody>().angularVelocity.magnitude);
Once you are sure that the ball is in fact moving with a slight magnitude, suppose this gives you a value of 0.01f. Once you get to know the magnitude of that slight movement just change the if statement to
if (GetComponent<Rigidbody>().velocity.magnitude > 0.01f && GetComponent<Rigidbody>().angularVelocity.magnitude > 0.01f)
Rather than checking with zero while working with physics it is always better to check with a value slightly higher than that.