- Home /
Rigidbody moves randomly in a child circle
I wanted a rigidbody to move around randomly around its current transform.position (transform.position changes all the time). The rigidbody will start moving randomly after a certain countdown if there is no user input. And I have a circle child to the rigidbody. I want the rigidbody to move around, within the circle.
Using this, how do I implement Random.insideUnitCircle? Or there is other methods? Thanks in advance.
Answer by Tomer-Barkan · Dec 06, 2013 at 05:08 AM
Here is some code I once used to move an object around the center in 2D:
Edit: Modified code a bit and added comments
public class TargetMove : MonoBehaviour {
public float targetSpeed = 0.2f; // speed of movement within circle
public float changeDirectionChance = 0.05f; // how often the target changes move direction
public float maxTargetDistanceFromCenter = 0.07f; // radius of circle in which the target moves from it's original position
private Vector3 velocity = Vector3.zero; // target's current velocity
private Vector3 startLoc; // original position - the center of the movement
public void Start() {
startLoc = transform.position; // set center of movement to original position
}
public void Update() {
UpdateTargetVelocity(); // update velocity when needed
transform.Translate(velocity * Time.deltaTime); // move target according to velocity
}
// reset movement - start from center of movement
public void ResetLocaiton() {
transform.position = startLoc;
velocity = Vector3.zero;
}
// update target velocity every once in a while, or when velocity is zero.
private void UpdateTargetVelocity() {
if (velocity.magnitude == 0) {
SetNewRandomVelocity(); // if target has no velocity, set velocity in a completely random direction
} else {
// if target already has velocity
float angle = Vector3.Angle(velocity, GetVectorFromCenterFlat(transform)); // angle between velocity and
// change direction in random intervals (if random < changeDirectionChance), or when current velocity is away from center, and the distance from center is over the maximum
float changeDir = Random.Range(0f, 1f);
if (changeDir < changeDirectionChance || (GetVectorFromCenterFlat(transform).magnitude >= maxTargetDistanceFromCenter && angle <= 90)) {
SetNewRandomVelocity(); // randomize new velocity
// if new velocity is away from center, and distance from center is above the maximum, rotate 90 degrees towards the center
float newAngle = Vector3.Angle(velocity, GetVectorFromCenterFlat(transform));
if (newAngle <= 90) {
velocity = Vector3.RotateTowards(velocity, GetVectorFromCenterFlat(transform) * -1, 90 * Mathf.Deg2Rad, 0);
velocity.z = 0; // in case exactly 180 degrees, rotatetowards is unpredictable and may rotate on the Z axis.
}
}
}
}
private void SetNewRandomVelocity() {
float newAngle = Random.Range(0f, 360f); // randomize angle 0 - 360
// rotate Vector3.up around the Z axis according to the random angle.
Vector3 newVelocity = Vector3.up;
Quaternion rotation = Quaternion.AngleAxis(newAngle, Vector3.front);
newVelocity = rotation * newVelocity;
newVelocity *= targetSpeed; // set velocity magnitued according to speed
velocity = newVelocity; // store new velocity
}
// get vector pointing from center of movement to current position
private Vector3 GetVectorFromCenterFlat(Transform transform) {
return transform.position - startLoc;
}
}
Hi tbkn, I don't really understand your code. What is the purpose of SetNewRandomVelocity, GetVectorFromCenterFlat, your ifs?
Sorry, it's pretty old code... I modified it a bit to work on X/Y plane ins$$anonymous$$d of X/Z, and added comments to explain the code.
The idea is you store the velocity of the object. Once every few frames (depending on changeDirectionChance
), the direction of the velocity changes randomly.
Every frame, we move the object according to its velocity, but as soon as it is too far from the center, we make sure the velocity changes again, but that it causes the object to move closer to the center, and not farther.
SetNewRandomVelocity()
does just that, randomizes the direction of the object's movement, while keeping the magnitude targetSpeed
.
GetVectorFromCenterFlat()
simply returns a vector pointing from the center of movement, to the current position of the object.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How to make a gameobject follow the mouse when I click and drag on the object. 1 Answer
Renderer on object disabled after level reload 1 Answer
Moving an animation object 0 Answers