How to add more points or position in linerenderer? - c#

I have a LineRenderer with only two points, start, and endpoints. I want to divide the line with a given number that will automatically create or add new points to the LineRenderer. For example, if I divide the line by 2, it will add another point in the center of LineRenderer.
EDITED:
Edited my question the second time now with the working script and image result. I don't know if this is the best solution but its working for me. The only thing that I don't know is how to compute the divisor to use based on the number of line.position. And for the duplicate flag. I think it's not the same as what I wanted.
GameObject stroke = new GameObject();
LineRenderer line = stroke.AddComponent<LineRenderer>();
line.startWidth = 0.1f;
line.endWidth = 0.1f;
line.useWorldSpace = true;
float divisor;
Vector3 start = new Vector3(-6.7399,-0.2475,0);
Vector3 end = new Vector3(-3.742899, -0.2475, 0);
line.positionCount = 4;
if(line.position == 4)
divisor = 0.333f; //get by 1/3
else if(line.position == 3)
divisor = 0.5f; //get by 1/2
Vector3 valuePerPosition = Vector3.Lerp(start, end, divisor);
for (int i = 0; i < line.positionCount; i++)
{
Vector3 newPosition = start - valuePerPosition;
line.SetPosition(i, start - (newPosition * i));
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = start - (newPosition * i);
sphere.transform.localScale = new Vector3(0.125f, 0.125f, 0.125f);
}

Related

How to calculate position of edge circle and rotation to center

i have mathematical formula and i have spawn points. but, i have so differenet object sizes and radiuses. how i can instantiate a objects in the edge of circle and rotate them onto center circle like picture;
i am bad with this stuf and my code is wrong or not i dont know
```
public void GetObstacle(int count, CircleRotator rotator)
{
float TAU = 6.283185307179586f;
for (int i = 0; i < count; i++)
{
Transform cameraTR = mainCamera.transform;
Transform tr = rotator.transform;
var obj = new GameObject();
float t = (float)i / count;
float angle = t * TAU * 0.25f; //
Vector3 itemCenter = new Vector3(Mathf.Cos(angle) * rotator.GetRadius + tr.position.x,
tr.position.y + Mathf.Sin(angle) * rotator.GetRadius);
obj.transform.position = itemCenter;
Vector3 current = tr.position - cameraTR.position;
Vector3 target = obj.transform.position - cameraTR.position;
obj.transform.Rotate(Vector3.forward, Vector3.Dot(current, target));
obj.transform.SetParent(tr);
}
}
```
where 0.25 in here i dont understand. But without 0.25 all will broke. angle = t * TAU * 0.25f;
help pls or give some adwice. https://ibb.co/qNhZCh3 what i would like but what i have https://ibb.co/NFSRmSn
so many formulas and watched videos. but i can't understand how
Thanks #Ruzihm with help rotations.
spawn outside edge I got this way, where I'm not sure if this is the right way, where Size is the size of y collider. If someone show another good way i will be gratitude!
Vector3 direction = (tr.position - obj.transform.position);
obj.transform.rotation = Quaternion.LookRotation(Vector3.forward, direction);
obj.transform.position -= direction.normalized * obj.Size()/2f;

Instantiate as many gameObjects as possible from one position and end at another

How do I instantiate as many gameObjects as possible that start at one position and end at another position. For example, instantiate gameObject at x=0 and end at x=5 axis. Between these two values, there should be as many gameObjects as possible, preferably 10-12 small scaled ones.
public GameObject prefab;
void Awake()
{
GameObject ref = (GameObject)Instantiate(prefab, Vector3.zero, Quaternion.identity);
}
when you say as many GameObjects as possible I guess you mean without overlapping?
This solution works assuming the prefab uses Colliders.
I would instantiate the first object allways and simply get it's bounding box so we know how big it is
var first = Instantiate(prefab, Vector3.zero + Vector3.right * MinX, Quaternion.identity);
var bounds = new Bounds(Vector3.zero, Vector3.zero);
foreach (var col in first.GetComponentsInChildren<Collider>(true))
{
bounds.Encapsulate(col.bounds);
}
// now you can get the size in X direction
var width = bounds.size.x;
I suspect the pivot point of your prefab would probably be in the center so first move it to the right by half of its width
first.transform.position += Vector3.right * width / 2f;
Now you can check how many objects will fit in your given range. Lets say e.g. the width was 1 then in a range from 0 to 5 there would fit in total 4 objects. There will be some redundancies in the calculation (adding 1 then decreasing 1 etc ) but I'll leave it sfor better understanding
var minPosition = MinX;
var maxPosition = MaxX;
var actualMinPosition = minPosition + width / 2;
var actualMaxPosition = maxPosition - width / 2;
// +1 here since before we reduced actualMinPosition and actualMaxPosition by
// exactly 1 * width
var possibleAmount = (int)Mathf.Floor((actualMaxPosition - actualMinPosition) / width) + 1;
So now instantiate the missing objects
// since I guess you also want them evenly spread between the start and end position
var distanceBetween = (actualMaxPosition - actualMinPosition) / (possibleAmount - 1);
// since we already instantiated the first one
// we spawn only possibleAmount - 1 more
for (var i = 0; i < possibleAmount - 1; i++)
{
// +1 here since we started the loop with i=0 but the first
// object here is actually the second to be spawned in total
// so we want it to be moved already
var x = actualMinPosition + distanceBetween * (i + 1);
var obj = Instantiate(prefab, Vector3.zero + Vector3.right * x, Quaternion.identity);
}
So all together
public void Spawn()
{
var first = Instantiate(prefab, Vector3.zero, Quaternion.identity);
var bounds = new Bounds(Vector3.zero, Vector3.zero);
foreach (var col in first.GetComponentsInChildren<Collider>(true))
{
bounds.Encapsulate(col.bounds);
}
// now you can get the size in X direction
var width = bounds.size.x;
first.transform.position += Vector3.right * width / 2f;
var minPosition = MinX;
var maxPosition = MaxX;
var actualMinPosition = minPosition + width / 2;
var actualMaxPosition = maxPosition - width / 2;
// +1 here since before we reduced actualMinPosition and actualMaxPosition by
// exactly 1 * width
var possibleAmount = (int)Mathf.Floor((actualMaxPosition - actualMinPosition) / width) + 1;
// since I guess you also want them evenly spread between the start and end position
var distanceBetween = (actualMaxPosition - actualMinPosition) / (possibleAmount - 1);
// since we already instantiated the first one
// we spawn only possibleAmount - 1 more
for (var i = 0; i < possibleAmount - 1; i++)
{
// +1 here since we started the loop with i=0 but the first
// object here is actually the second to be spawned in total
// so we want it to be moved already
var x = actualMinPosition + distanceBetween * (i + 1);
var obj = Instantiate(prefab, Vector3.zero + Vector3.right * x, Quaternion.identity);
}
}
I simply destroyed and respawned everything in Update for this demo
You could loop the amount of enemys that you want to be spawned(12 for example) and increase the position at every loop iteration.
public GameObject prefab;
public Vector3 pos;
void Awake()
{
for (int i = 0; i < 12; i++)
{
Instantiate(prefab, pos, Quaternion.identity);
pos.x += 0.5f;
}
}
This should create 10 GameObject between 0 and 5.
void Awake() {
for(float x = 0; x < 5; x+=0.5f){
Vector3 loc = new Vector3(x, 0, 0);
GameObject gameObject = (GameObject)Instantiate(prefab, loc, Quaternion.identity);
}
}
Thank you for all your answers, I did something like this:
(a) Create two gameObjects in the scene separated by some distance
(b) In the script, give reference to these two gameObjects
(c) Give number of segments (spheres) that should be generated between these two points
public Transform PointA; public Transform PointB; public float NumberOfSegments = 3; public float AlongThePath = .25f;
// Update is called once per frame
void Start()
{
Create();
}
void Create()
{
StartCoroutine(StartSpheringOut());
}
IEnumerator StartSpheringOut()
{
NumberOfSegments += 1;// since we are skipping 1st placement since its the same as starting point we increase the number by 1
AlongThePath = 1 / (NumberOfSegments);//% along the path
for (int i = 1; i < NumberOfSegments; i++)
{
yield return new WaitForSeconds(0.05f);
Vector3 CreatPosition = PointA.position + (PointB.position - PointA.position) * (AlongThePath * i);
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = CreatPosition;
sphere.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f);
}

Random points with radius

I have a dilemma on an algorithm. I'm trying to generate 6 random positions that have a distance between them. My algorithm works, only to check the distance between the current point and the previous point. What I need is for the algorithm to verify the distance between all points and if the distance is less than the indicated value, it will generate a new position.
private void Generate()
{
for (int i = 0; i <= 5; i++)
{
Vector3 pos = PointsGenerator();
Instantiate(point, pos, Quaternion.identity); // just to highlight the points on the screen
}
}
private List<Vector3> Dist = new List<Vector3>();
private bool isOver = false;
private Vector3 PointsGenerator()
{
Vector3 currentPosition = Vector3.zero;
Vector3 oldPosition = Vector3.zero;
float distance = 0f;
do
{
currentPosition = new Vector3(UnityEngine.Random.Range(minX, maxX), UnityEngine.Random.Range(minY, maxY), 0f);
for (int i = 0; i < Dist.Count; i++)
{
distance = Vector2.Distance(currentPosition, Dist[i]);
if (distance <= 4f)
{
isOver = true;
break;
}
else
isOver = false;
}
} while (isOver == true);
Dist.Add(currentPosition);
return currentPosition;
}
Thanks to all who will give advice.
what is the question?
"I need these 6 points and not only have a distance between them, but also the distance from center + radius to be of value"
To achieve that, you will HAVE TO generate points that are on a sphere. For that, generate a (random if needed) center point of your sphere and define the radius.
Then, you need to use random spherical coordinates (radius, randomAngle1, randomAngle2). To convert those into cartesian coordinates, use
x = radius * cos(randomAngle1) * sin(randomAngle2)
y = radius * sin(randomAngle1) * sin(randomAngle2)
z = radius * cos(randomAngle1)
after that you can make the same algorithm as you already have to regenerate new points until they are far away from each other as well

How to change Sprite Image when it reaches 90 degrees?

I say that I am a beginner.
I have a question during the project.
I'm currently implementing a card-matching game.
When I start the game, The image is loaded from the external path (D: / ..).
My question is in the code below.
public void createCardList()
{
int count_x = 0;
int count_y = 0;
GameObject parent_area = GameObject.Find("GameMain");
List<int> num = createRandomIndex(createArrayIndex());
for (int i = 0; i < card_list.Count; ++i)
{
if ((i % CARD_ROWS) == 0 && i > 0)
{
count_y += 1;
count_x = 0;
}
GameObject card_prefab_load = Resources.Load("Prefabs/card") as GameObject;
GameObject card_prefab_instantiate = Instantiate(card_prefab_load, card_prefab_load.transform.position, Quaternion.identity);
float card_position_x = (CARD_WIDTH + CARD_SPACE) * (i % CARD_ROWS) - 290f;
//Debug.Log("card_position_x" + card_position_x);
float card_position_y = count_y * (CARD_HEIGHT + CARD_SPACE) - 280f;
//Debug.Log("card_position_y" + card_position_y);
card_prefab_instantiate.transform.SetParent(parent_area.transform);
card_prefab_instantiate.transform.name = "card_" + num[i];
card_prefab_instantiate.transform.localScale = new Vector3(1f, 1f, 1f);
card_prefab_instantiate.transform.localPosition = new Vector3(card_position_x, card_position_y, 1f);
StartCoroutine(firstRotateOriginalImage());
}
}
// Rotate image
private IEnumerator firstRotateOriginalImage()
{
yield return new WaitForSeconds(2f);
GameObject findCardList = GameObject.Find("GameMain");
for (int i = 0; i < findCardList.transform.childCount; ++i)
{
// I don't know what code to put in this part.
}
}
What I want to implement is below.
When the card rotation value reaches 90 degrees,How to change an externally imported image to a Sprite Image of a child GameObject?
How to rotate the child objects 360 degrees after the first task is completed?
For example, the picture below.
Arrows indicate the order in which cards are flipped.
also, Of the 12 GameObjects, Six GameObjects try to implement a common image.
I don't know much. I need your help.
There are many ways to do that...
transform.Rotate(...)
transform.RotateAround(...)
transform.localEulerAngles = transform.localEulerAngles.X|Y|Z +
amount
transform.localRotation = transform.localRotation*relativeRotation
/*= a Quaternion*/
Something else entirely...
I'm a doubtful regarding how well I understand your question...
But it seems like you want to simply flip the cards over don't you?
The approach I'd take is to have each card as the combination of the face (rotated 180 degrees in Y) and the back, both being children of an empty GameObject.
That way you could simply rotate the Card object using transform.Rotate(0, 180, 0)
To use it in a coroutine you could do
//Speed of animation (here 0.55 seconds)
float degreesPerSecond = 200f;
//The amount you want to rotate
float maxDegrees = 180f;
//Animate
for (float f = maxDegrees; f < 0;)
{
//How much to rotate
float rot = degreesPerSecond * Time.deltaTime;
//Rotate children
foreach(var child in transform)
child.Rotate(0, rot, 0);
//Record rotation
f -= rot;
//Wait next frame
yield return null;
}
//Round to desired rotation
foreach(var child in transform)
child.position = new Vector3(child.position.x, maxDegrees, child.position.z);

Spawning items at sides of a spline

I have just done the Curves and Splines Tutorials from the catlikecoding.com website (http://catlikecoding.com/unity/tutorials/curves-and-splines/) and after finishing it I came up with an idea. I would like to spawn the items from the SplineDecorator at the same distance from the spline at both sides of the spline. I have tried duplicating the for loop and instantiating the newItem twice but at different position but it doenst work as I want to. Here's the Spline Decorator script that takes a spline and then Instantiate some items along the its path
using UnityEngine;
public class SplineDecorator : MonoBehaviour
{
public BezierSpline spline;
public int frequency;
public float distanceBetweenItems;
public bool lookForward;
public Transform[] items;
private void Awake()
{
if (frequency <= 0 || items == null || items.Length == 0)
{
return;
}
float stepSize = 1f / (frequency * items.Length);
for (int p = 0, f = 0; f < frequency; f++)
{
for (int i = 0; i < items.Length; i++, p++)
{
Transform item = Instantiate(items[i]) as Transform;
Vector3 position = spline.GetPoint(p * stepSize);
item.transform.localPosition = new Vector3(position.x + distanceBetweenItems, position.y, position.z);
if (lookForward)
{
item.transform.LookAt(position + spline.GetDirection(p * stepSize));
}
item.transform.parent = transform;
}
}
}
}
You don't define exactly what "at both sides" means to you, so I'm not sure if this is what you're looking for, but maybe this will get you on the right track.
I replaced the inner loop with the following and got a sort of "race track" feel with distanceBetweenItems = 2:
Transform item = Instantiate(items[i]) as Transform;
Transform item2 = Instantiate(items[i]) as Transform;
Vector3 position = spline.GetPoint(p * stepSize);
Vector3 direction = spline.GetDirection(p * stepSize);
Vector3 cross = Vector3.Cross(direction, Vector3.up);
Vector3 delta = cross.normalized * (distanceBetweenItems/2);
item.transform.localPosition = new Vector3(position.x + delta.x, position.y + delta.y, position.z + delta.z);
item2.transform.localPosition = new Vector3(position.x - delta.x, position.y - delta.y, position.z - delta.z);
if (lookForward)
{
item.transform.LookAt( position + spline.GetDirection(p * stepSize));
item2.transform.LookAt(position + spline.GetDirection(p * stepSize));
}
item.transform.parent = transform;
item2.transform.parent = transform;
What I've done here is use Vector3.Cross() (Unity Documentation) to find the line perpendicular to both the spline and Vector3.up. Then I calculate how far along that line to go by normalizing it and multiplying it by half of distanceBetweenItems. (So that, combined, they're distanceBetweenItems apart.)
If you instead wanted something like tracing the wingtips of a plane flying that spline, you'll need to replace the Vector.up above. The simplest way is to replace it with the 'binormal vector', though there are issues with that. This pdf I just found talks a little about it, and might get you on the right path.
(Goofing around, I was able to get a reasonable approximation by replacing the Vector3 cross = ... line with Vector3 cross = Vector3.Cross(direction, direction - spline.GetDirection(p * stepSize + 0.01f));, though it's screwy on sharp bends, non-mirrored vertices, and at the start/end loop.)

Categories