Reputation: 13
I tried to make a game similar to a game called pick a lock game. However, I was struggle with spawning randomly a point around the border of circle but not in the circle. For more details, I want to spawn a gameObject at the border of a circle only but not every where in the circle. Please help me :< Thank you very much and have a good day! p/s: I just a beginner to unity engine and syntax. It'll be great if you give me some advice of how to self-learning unity. Thank you so much
Upvotes: 0
Views: 5435
Reputation: 110
First of all, I really like Dot Product. I took a random place around the reference object (which is in this case transform.position
). Then take direction between randomPos
and reference object. Calculated Dot Product with Vector3.Dot()
. Take the angle between randomPos
and our transform.forward
with the result of Dot Product. Calculate the x and z values with Cos and Sin functions. Dot Product Angle always gives 0 to 180 values so I gave randomness to z-axis with multiply dotProductAngle
with (Random.value > 0.5f ? 1f : -1f)
. If you don't do this, the given random position will be always in front of the player.
3D Space
private void SpawnSphereOnEdgeRandomly3D()
{
float radius = 3f;
Vector3 randomPos = Random.insideUnitSphere * radius;
randomPos += transform.position;
randomPos.y = 0f;
Vector3 direction = randomPos - transform.position;
direction.Normalize();
float dotProduct = Vector3.Dot(transform.forward, direction);
float dotProductAngle = Mathf.Acos(dotProduct / transform.forward.magnitude * direction.magnitude);
randomPos.x = Mathf.Cos(dotProductAngle) * radius + transform.position.x;
randomPos.z = Mathf.Sin(dotProductAngle * (Random.value > 0.5f ? 1f : -1f)) * radius + transform.position.z;
GameObject go = Instantiate(_spherePrefab, randomPos, Quaternion.identity);
go.transform.position = randomPos;
}
Example in 3D
2D Space
private void SpawnSphereOnEdgeRandomly2D()
{
float radius = 3f;
Vector3 randomPos = Random.insideUnitSphere * radius;
randomPos += transform.position;
randomPos.y = 0f;
Vector3 direction = randomPos - transform.position;
direction.Normalize();
float dotProduct = Vector3.Dot(transform.forward, direction);
float dotProductAngle = Mathf.Acos(dotProduct / transform.forward.magnitude * direction.magnitude);
randomPos.x = Mathf.Cos(dotProductAngle) * radius + transform.position.x;
randomPos.y = Mathf.Sin(dotProductAngle * (Random.value > 0.5f ? 1f : -1f)) * radius + transform.position.y;
randomPos.z = transform.position.z;
GameObject go = Instantiate(_spherePrefab, randomPos, Quaternion.identity);
go.transform.position = randomPos;
}
Example in 2D
I hope this helps you out 👍
Upvotes: 6
Reputation: 4561
You need to try something out and show were you get stuck. I would start trying to understand point rotation with a raw language to understand what is happening, for example, point rotation in plain c#:
// Rotate B around A by angle theta clockwise
private static (double x, double y) Rotate(
(double x, double y) A,
(double x, double y) B,
double theta)
{
double s = Math.Sin(theta);
double c = Math.Cos(theta);
// translate point back to origin:
B.x -= A.x;
B.y -= A.y;
// rotate point clockwise
double xnew = B.x * c - B.y * s;
double ynew = B.x * s + B.y * c;
// translate point back:
B.x = xnew + A.x;
B.y = ynew + A.y;
return B;
}
Then you can check some basic vectorial operations and their math background which is not that hard and give a look to what can be done with the unity API: Vector3.Reflect and Vector3.RotateRowards
Sure you can figure something out.
Upvotes: 0