Instantiate in circle objects look to center - c#

A little bit confused - math is really not my strong point, so I'm not sure how to achieve.
Currently the objects instantiate, but I have no control over the distance from center or the rotation of each spawned object
public void instantiateInCircle()
{
for (int i = 0; i < amount; i++)
{
float radius = spawnDistance;
float angle = i * Mathf.PI * 2f / radius;
Vector3 newPos = transform.position + (new Vector3(Mathf.Cos(angle) * radius, spawnHeight, Mathf.Sin(angle) * radius ));
//Rotate objects to look at the center
GameObject instantiatedObject = Instantiate(itemToSpawn, newPos, Quaternion.Euler(0, 0, 0));
instantiatedObject.transform.LookAt(spawnAroundThis.transform);
//How to adjust the width of the radius, how far away from the center?
//Parent instantiated objects to disk
instantiatedObject.transform.parent = spawnAroundThis.transform;
instantiatedObject.transform.localScale = new Vector3(scale, scale, scale);
}
}
How to make the distance adjustable, move cubes in closer to center...?

Currently, you do not access the instantiated object, but the prefab instead. Cache the object and call the LookAt on them.
Since I do not know what type itemToSpawn is, I assumed it is a GameObject. You may want to use your type instead.
GameObject instantiatedObject = Instantiate(itemToSpawn, newPos, Quaternion.Euler(0, 0, 0));
instantiatedObject.transform.LookAt(spawnAroundThis.transform);

If you want to control the distance from center of the rotation:
for (int i = 0; i < amount; i++)
{
float radius = spawnDistance;
float angle = i * Mathf.PI * 2f / (float)amount; // divide by amount, NOT radius
// manipulate radius here as you want
Vector3 newPos = transform.position + (new Vector3(Mathf.Cos(angle) * radius, spawnHeight, Mathf.Sin(angle) * radius ));
...
}

Related

Rotate object in Unity 2D

Help to understand the management of objects. At the moment, there is a rotation of the object. I want the arrow to rotate, and the angle of rotation depends on the current X and Y coordinates. Unity2D.
Now it is left (does not rotate), but it needs to be right (it always rotates and looks in one direction), but I don’t know how to calculate the degrees for rotation.
`
public float angle = 0; // угол
public float radius = 0.5f; // радиус
public bool isCircle = false; // условие движения по кругу
public float speed = 5f;
// Update is called once per frame
void Update()
{
angle += Time.deltaTime; // меняется значение угла
var x = Mathf.Cos(angle * speed) * radius + parent.position.x;
var y = Mathf.Sin(angle * speed) * radius + parent.position.y;
transform.position = new Vector3(x, y,0);
//transform.Rotate(0, 0, a);
}
`
Help me, how to calculate angle?
You need Mathf.Atan2, it will return a radian, then you need to multiply a Mathf.Rad2Deg to get the Euler angle.

How to rotate around an object without using unity's built-in functions?

i want to rotate a cube around a 1x1 pipe with arrow keys. (left and right).
The problem is i cannot use built-in functions which sets transform's position and location directly. (Such as transform.lookAt, transform.Rotate or transform.RotateAround). Because I need the vector values of rotation's euler and position for multiple stuff before i modify the value of the transform i want to rotate.
I tried different techniques but no luck so far.
I tried using sin-cos for rotating but could not figure out how to make it work for both rotation and position.
_timer += Time.deltaTime * _larvaSpeed;
float x = -Mathf.Cos(_timer) * distanceBetweenCenter;
float y = Mathf.Sin(_timer) * distanceBetweenCenter;
Here is what i want to achieve. By pressing right or left, move and rotate the object around the pipe.
The result i want. (If i pressed right arrow key a litte bit).
I would appreciate any help. Thank you!
here is the solution using circle mathematics and I strongly recommended not use it, it's just to understand the circular move using circle equation as #FaTaLL ask in the comments
Circle equation...
(x1 - x2)^2 + (y1 - y2)^2 = r^2
x1, y1 is the cube position
x2, y2 is the pipe position
r is the distance between cube and pipe;
using UnityEngine;
public class Rotating : MonoBehaviour
{
public GameObject pipe;
public float Delta;
Vector3 nextpos;
bool compareY;
bool next;
int switchx;
float storeVarAxis;
float x, y, r;
private void Start()
{
next = true;
switchx = 1;
compareY = true;
x = transform.position.x - pipe.transform.position.x;
y = transform.position.y - pipe.transform.position.y;
storeVarAxis = y;
r = Mathf.Sqrt(x * x + y * y);
}
private void Update()
{
if (next)
{
if (compareY == true)
{
y -= Delta * Time.deltaTime;
if (y <= -storeVarAxis)
{
y = -storeVarAxis;
compareY = false;
switchx = -1;
}
}
else
{
y += Delta * Time.deltaTime;
if (y >= storeVarAxis)
{
y = storeVarAxis;
compareY = true;
switchx = 1;
}
}
float v = r * r - y * y;
x = Mathf.Sqrt(Mathf.Abs(v));
nextpos = new Vector3(pipe.transform.position.x + x * switchx, pipe.transform.position.y + y, transform.position.z);
next = false;
}
transform.position = Vector3.MoveTowards(transform.position, nextpos, 1f * Time.deltaTime);
if(Vector3.Distance(transform.position, nextpos) < .05) transform.position = nextpos;
if (transform.position.x.Equals(nextpos.x) && transform.position.y.Equals(nextpos.y)) next = true;
}
}
well, the recommended way is using this simple script
using UnityEngine;
public class Rotating : MonoBehaviour
{
public float speed;
public GameObject pipe;
float r, angle;
Vector3 startpos;
private void Start()
{
r = Mathf.Abs(transform.position.y - pipe.transform.position.y);
angle = 0;
transform.position = pipe.transform.position;
startpos = transform.position;
}
void Update()
{
angle = angle + speed * Time.deltaTime;
transform.rotation = Quaternion.EulerAngles(0,0, angle);
transform.position = startpos + (transform.rotation * new Vector3(r, 0, 0));
}
}
I think Quaternion * Vector3 is what you are looking for. Luckily the box's rotation in its own local coordinates is the same rotation you need to apply to the box's position.
public float speed; //how fast to rotate
public float radius; //radius of the cylinder
public float angle; //angle around it
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
angle = angle + speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.RightArrow))
{
angle = angle - speed * Time.deltaTime;
}
//figure out the rotation (from euler angles i guess??)
var quat = Quaternion.EulerAngles(new Vector3(0, angle, 0));
//ok uh what is the box position?? lets just multiply
var unrotated_position = new Vector3(radius, 0, 0);
var rotated_position = quat * unrotated_position;
this.transform.position = rotated_position;
//oh yea and also rotate the box in its own local coordinates
this.transform.rotation = quat;
}

Player is not moving toward target without unity built in functions

I am trying to move my target object towards my player using custom codes(without built-in function of unity like MoveTowards)
Vector3 displacment = target.transform.position - player.transform.position;
//you can also get magnitude directly through displacement.magnitude
float xMagnitude = displacment.x * displacment.x;
float yMagnitude = displacment.y * displacment.y;
float zMagnitude = displacment.z * displacment.z;
float customMagnitude =Mathf.Sqrt(xMagnitude + yMagnitude + zMagnitude);
directionToMove = new Vector3(displacment.x / customMagnitude, displacment.y / customMagnitude, displacment.z / customMagnitude);
//directionToMove = displacment.normalized;
Vector3 velocity = directionToMove * speed;
Vector3 moveAmount = velocity * Time.deltaTime;
target.transform.position += moveAmount;
I first got the displacement between two vectors than i get its direction and pass it to my position with speed. but its direction is not towards the player. what i am doing wrong?
If you want to move your target towards the player, the displacment must be :
displacment = player.transform.position - target.transform.position;
To generate a vector given the initial point : A (x1, y1, z1) and final point B (x2, y2, z2) the calculation is the following :
v = B - A = (x2 - x1, y2 - y1, z2 - z1);
So let me get this straight: You want to move the target towards the player, not the player towards the target. Is this correct?
If you want to move the target object towards the player, then the displacement should be player.transform.position - target.transform.position, not the other way around.
If you really don't want to use the Unity functions, then here's how I would do your code:
Vector3 displacment = player.transform.position - target.transform.position;
float xMagnitude = displacment.x * displacment.x;
float yMagnitude = displacment.y * displacment.y;
float zMagnitude = displacment.z * displacment.z;
float customMagnitude =Mathf.Sqrt(xMagnitude + yMagnitude + zMagnitude);
//multiplying vector by scalar works the same,
//and is more readable (possibly faster too)
directionToMove = displacement * 1f/customMagnitude;
Vector3 velocity = directionToMove * speed;
Vector3 moveAmount = velocity * Time.deltaTime;
target.transform.position += moveAmount;

Instantiate gameobjects in a segment of a circle if you have radius of the circle

I want to instantiate gameobjects in a segment of a circle e.g in between 10 degrees and 100 degrees from a known vector3 position. (Imagine a shape of pizza). I found following code that helps me instantiate objects between 0 and 180 degrees. Can someone help me instantiate gameobjects between 10 and 100 degrees as an example.
Vector3 randomCircle ( Vector3 center , float radius )
{
float ang = Random.value * 180;
Vector3 pos;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.y = center.y + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.z = center.z;
return pos;
}
Copying and modifying my answer to different topic would do what you need.
// get the new position
public Vector3 OrbitPosition(Vector3 centerPoint, float radius, float angle)
{
Vector3 tmp;
// calculate position X
tmp.x = Mathf.Sin(angle * (Mathf.PI / 180)) * radius + centerPoint.x;
// calculate position Y
tmp.y = Mathf.Sin(angle * (Mathf.PI / 180)) * radius + centerPoint.y;
tmp.z = centerPoint.z;
return tmp;
}
// instantiate element at random orbit position
public GameObject InstantiateRandom(GameObject toInstantiate, Vector3 centerPoint)
{
// get calculated position
Vector3 newPosition = OrbitPosition(centerPoint, 10.0f, Random.Range(10.0f, 100.0f));
// instantiate a new instance of GameObject
GameObject newInstance = Instantiate(toInstantiate) as GameObject;
// check if instance was created
if ( newInstance )
{
// set position to the newly created orbit position
newInstance.transform.position = newPosition;
}
// return instance of the newly created object on correct position
return newInstance;
}

C# Vector2 How to move an object toward an angle

I want to move an object to the given angle, But it moves only up, and down, only Y axis.
Vector2 unitV = new Vector2((float)Math.Sin(player.angle), (float)Math.Cos(player.angle));
unitV.Normalize();
player.model.Position += Vector2.Multiply(unitV,player.model.Speed) * (float)gameTime.ElapsedGameTime.TotalSeconds;
I just met this problem while practicing, but here is the solution i found. I hope this will work for you. Used XNA 4 C sharp.
Declaration:
Texture2D sprite;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteOriginalPos;
float spriterotation = 0;
float anglecorrection = (Math.PI * 90 / 180.0);
float speed = 1;
Note that the anglecorrection is needed to move the object toward its "up" angle.
Load:
//Load basic texture to make it recognizable :)
sprite= Content.Load<Texture2D>("spritetexture");
//Default position in middle
spritePosition = new Vector2(
(graphics.GraphicsDevice.Viewport.Width / 2) - (sprite.Width / 2),
(graphics.GraphicsDevice.Viewport.Height / 2) - (sprite.Height / 2));
//Sprite centering
spriteOriginalPos.X = sprite.Width / 2;
spriteOriginalPos.Y = sprite.Height / 2;
Update:
if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Up))
{
spritePosition.X += speed * (float)Math.Cos(spriterotation - anglecorrection);
spritePosition.Y += speed * (float)Math.Sin(spriterotation - anglecorrection);
}
Draw:
spriteBatch.Draw(sprite, spritePosition, null, Color.Black, spriterotation, spriteOriginalPos, 1.0f, SpriteEffects.None, 0f);

Categories