Gameobjects position change with resolution - unity3d

I have a scene with multiple GameObjects with x-y-z position. I'm in 2D so the z is not used.
For now, I worked with the resolution 1024/768 and when I add a GameObject like :
GameObject star = GameObject.CreatePrimitive(PrimitiveType.Sphere);
Vector3 position = new Vector3 (x, y, z);
star.transform.localPosition = position;
It's ok, the GameObject is in the right position on my scene.
But nox, I'm trying to change the resolution (1920/1080) and all my GameObjects are moved far on the top right, out of my camera.
What's the problem ? How can I fix this ?
For me, when I change the resolution, the 0-0-0 change for my GameObjects....and something weird, If my GameObject has a LineRenderer with positions, they are good on all resolutions...
Edit : This is the function I use for generate my GameObjects, it's a galaxy generator :
for(int i = 0; i < numberOfStars; i++) {
bool checkPosition = false;
while (!checkPosition) {
// Choose a distance from the center of the galaxy.
float distance = Random.Range(5.0f, (float) galaxySize / 2 - 5);
// Choose an angle between 0 and 2 * PI.
float angle = Random.Range(0.0f, 100.0f) * 2 * Mathf.PI;
Vector3 position = new Vector3 (Mathf.Cos (angle) * distance, Mathf.Sin(angle) * distance, 9);
if (! Physics.CheckSphere(position, 1)) {
GameObject star = GameObject.CreatePrimitive(PrimitiveType.Sphere);
star.AddComponent<SolarSystem>();
star.name = i + "_" + PlanetNameGenerator.GenerateName();
star.GetComponent<SolarSystem>().name = i + "_" + PlanetNameGenerator.GenerateName();
star.transform.parent = GameObject.Find ("Targets").transform;
// On change le scale en random
float randomScale = Random.Range (0f, 0.5f);
star.transform.localScale += new Vector3(randomScale,randomScale,randomScale);
star.transform.localPosition = position;
star.tag = "SolarSystem";
checkPosition = true;
}
}
}
This is the scene I see in 1024/768, with my Sphere GameObjects and in pink LineRenderer between them :
This is what I see in 1920/1080, LineRenderer are always in the same position, but GameObjects move away :

The problem was this line :
star.transform.parent = GameObject.Find ("Targets").transform;
I moved the parent out from Canvas, chnage x-y-z positions of "Targets" to 0 et it's ok.

Related

Get closest point between GameObject (inside the cube collider) and 3D cube collider

How do I calculate the distance of a game object (inside a cube collider) from the cube collider surface? The existing calculations were made from the cube surface outwards so I got 0 when I used the collider.closestpoint or collider.closestpointonbounds.
The simplest (but computationally not the cheapest) would be to not rely on your current collider for the distance, but to add a set of small colliders around the edge of the object (so 6 colliders, one per face of the cube). Using Collider.ClosestPoint() on all 6 faces and calculating the distance like that would give you the results you need.
First convert a point to local space.
var localPoint = transform.InverseTransformPoint(worldPoint);
var extents = collider.size * 0.5f;
var closestPoint = localPoint;
Compute the distance to each face.
var disx = extents.x - Mathf.Abs(localPoint.x);
var disy = extents.y - Mathf.Abs(localPoint.y);
var disz = extents.z - Mathf.Abs(localPoint.z);
Find the closest face (smallest distance) and move the closest point along this axis.
if(disx < disy)
{
if (disx < disz)
closestPoint.x = extents.x * Mathf.Sign(localPoint.x); //disx
else
closestPoint.z = extents.z * Mathf.Sign(localPoint.z); //disz
}
else
{
//......
}
Plus the offset of the collider, convert to world space.
closestPoint += collider.center;
transform.TransformPoint(closestPoint);
I don't know how efficient this is, but here is how I solved it:
public static Vector3 ClosetPointOnBounds(Vector3 point, Bounds bounds)
{
Plane top = new Plane(Vector3.up, bounds.max);
Plane bottom = new Plane(Vector3.down, bounds.min);
Plane front = new Plane(Vector3.forward, bounds.max);
Plane back = new Plane(Vector3.back, bounds.min);
Plane right = new Plane(Vector3.right, bounds.max);
Plane left = new Plane(Vector3.left, bounds.min);
Vector3 topclose = top.ClosestPointOnPlane(point);
Vector3 botclose = bottom.ClosestPointOnPlane(point);
Vector3 frontclose = front.ClosestPointOnPlane(point);
Vector3 backclose = back.ClosestPointOnPlane(point);
Vector3 rightclose = right.ClosestPointOnPlane(point);
Vector3 leftclose = left.ClosestPointOnPlane(point);
Vector3 closest = point;
float bestdist = float.MaxValue;
foreach (Vector3 p in new Vector3[] {
topclose, botclose, frontclose, backclose, leftclose, rightclose
})
{
float dist = Vector3.Distance(p, point);
if (dist < bestdist)
{
bestdist = dist;
closest = p;
}
}
return closest;
}
(note: this assumes and axis-aligned box, which is all I needed at the time. If you want to rotate it you will have to do more work to transform the point.)
You can Calculate by Vector3.Distance
some example
float minDistance =2;
float Distance = Vector3.Distance(other.position, transform.position);
if(Distance < minDistance)
{
//some code stuffs
}
else if(Distance > minDistance){
//some code stuffs
}
Useful information about Vector3.Distance and getting Distance from object
source: https://docs.unity3d.com/ScriptReference/30_search.html?q=Distance

2D car control with mouse position in unity 2D

i am new in unity. I want to car game with mouse control to Unity 2D. I was trying this code but not working. Car vibrates when i move mouse over car. I want it to work perfectly when the mouse hovers over the car. how can i do this? my code is as follows:
private void OnMouseOver()
{
// Distance from camera to object. We need this to get the proper calculation.
float camDis = cam.transform.position.y - my.position.y;
// Get the mouse position in world space. Using camDis for the Z axis.
Vector3 mouse = cam.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, camDis));
float AngleRad = Mathf.Atan2 (mouse.y - my.position.y, mouse.x - my.position.x);
float angle = (180 / Mathf.PI) * AngleRad;
body.rotation = angle;
Vector3 temp = Input.mousePosition;
temp.z = 10f; // Set this to be the distance you want the object to be placed in front of the camera.
this.transform.position = Camera.main.ScreenToWorldPoint(temp);
}
I'm not too clear on the effect you want to achieve, but if you just want the object to move and turn gradually instead of instantly changing, that can be achieved using Vector3.MoveTowards and Quaternion.RotateTowards, e.g.:
private void OnMouseOver()
{
// Distance from camera to object. We need this to get the proper calculation.
float camDis = cam.transform.position.y - my.position.y;
// Get the mouse position in world space. Using camDis for the Z axis.
Vector3 mouse = cam.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, camDis));
float AngleRad = Mathf.Atan2 (mouse.y - my.position.y, mouse.x - my.position.x);
float angle = (180 / Mathf.PI) * AngleRad;
//body.rotation = angle; //??
float turnSpeed = 200f;
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, angle), turnSpeed * Time.deltaTime);
Vector3 temp = Input.mousePosition;
temp.z = 10f; // Set this to be the distance you want the object to be placed in front of the camera.
float moveSpeed = 10f;
transform.position = Vector3.MoveTowards(transform.position, Camera.main.ScreenToWorldPoint(temp), moveSpeed * Time.deltaTime);
}
Edit in response to comment: If you want it to move only when the player begins the drag on the car, then yes, putting it in OnMouseDrag() would work. If you want it to move when the player drags from anywhere on the screen, you'd want to put the movement code in Update() and check whether the left mouse button is being held down using Input.GetMouseButton(0).
If you wanted it to keep moving towards the last mouse position (e.g. player can click on the screen and it will move there while the mouse button is not being held down), you'd need to keep the last mouse location in a class variable and move towards that in Update().
Incidentally if you want it to move a bit more like a car, you could always move it forwards while it turns towards the mouse, rather than moving it directly towards the mouse even if it's facing a different direction.
Here's an example but be aware that I've changed a few things that didn't seem necessary to me, like using my.position rather than transform.position. If you use it you may need to adapt it to suit the rest of your code.
public float maxTurnSpeed = 250f;
public float maxSpeed = 8f;
public float stopDistance = 0.5f;
public float slowDistance = 2.5f;
private void Update()
{
if( !Input.GetMouseButton(0) ) // If the mouse button is NOT being held down this frame
return; // Don't move. (Ideally you would decelerate the car rather than stopping it immediately though.)
// Remove the above two lines and move all of this to OnMouseDrag if you want to require the drag to begin on this object to move it.
// Also note: this code now assumes the object begins in the desired z position and doesn't change it, rather than forcing a z position.
// Distance from camera to object. We need this to get the proper calculation.
float camDis = transform.position.z - Camera.main.transform.position.z; // Changed this to use z instead of y as it appeared to be a mistake(?)
// Get the mouse position in world space. Using camDis for the Z axis.
Vector3 mouse = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, camDis));
float distanceFromMouse = Vector3.Distance(transform.position, mouse);
// If we're further away from the mouse than stopDistance, move.
if( distanceFromMouse > stopDistance )
{
float speedMultiplier = 1.0f;
float rotationMultiplier = 1.0f;
// If we're closer to the mouse than slowdistance, slow down proportionately to the remaining distance from stopDistance
if( distanceFromMouse < slowDistance )
{
speedMultiplier = (distanceFromMouse - stopDistance) / (slowDistance - stopDistance);
}
// Reduce turning speed as we approach stopDistance, but not by as much as speed is reduced
if( speedMultiplier < 0.5f )
rotationMultiplier = speedMultiplier * 2f;
float AngleRad = Mathf.Atan2(mouse.y - transform.position.y, mouse.x - transform.position.x);
float angle = (180 / Mathf.PI) * AngleRad;
// Turn the car towards facing the mouse position
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, angle), maxTurnSpeed * rotationMultiplier * Time.deltaTime);
// Move the car towards its transform.right vector.
transform.position += transform.right * (maxSpeed * speedMultiplier * Time.deltaTime);
}
}

find the heading angle between 2 objects taking into account the forward angle of the initial object

Ok, so, i've been stuck on this for ages. Im working on an AI that will navigate a tank to a waypoint, defined as a Vector3. the position of the tank is also defines as a Vector3, both these have their Y position set to 0, as to ignore terrain elevation, the current rotation of the tank is also a Vector3, though only the Y rotation is needed, as i'm effectively projecting the 3d position onto a 2d navigational grid.
The AI passes anywhere between -1 and 1 into the control for the tank, which then handles the physics operations. so, i need to somehow calculate the angle, positive or negative in relation to the current heading angle of the tank to the position of the waypoint, then send the rotation value to the controls. At the moment I simply cant get it working, I feel like iv'e pretty much tried everything.
This is my code currently, it doesn't work, at all, and is about the 20th revision:
void driveToTarget()
{
Vector3 target0 = driveTarget;
target0.y = 0;
GameObject current0Obj = new GameObject();
Vector3 current0 = this.transform.position;
current0.y = 0;
print(current0);
print(target0);
Vector3 current0Angle = this.transform.eulerAngles;
print(current0Angle.y);
current0Angle.x = 0;
current0Angle.z = 0;
Vector3 heading = target0 - current0;
Quaternion headingAngle = Quaternion.LookRotation(heading);
print("headingAngle" + headingAngle);
print("heading direction, allegidly: " + Quaternion.Euler(heading).ToEulerAngles());
Quaternion distanceToGo = Quaternion.Lerp(Quaternion.Euler(current0Angle), headingAngle, 0.01f);
float angle = Vector3.SignedAngle(current0, target0, Vector3.up);
float difference = Mathf.Abs(angle - current0Angle.y);
print("heading angle " + angle);
if (current0 != driveTarget)
{
steeringVal = Mathf.Abs(1.5f-(1f/Mathf.Abs(distanceToGo.y))) * -Mathf.Sign(distanceToGo.y); ;
throttleVal = 0f;
} else
{
throttleVal = 0;
}
}
--EDIT--
So, I've partially solved it, and now encountered another problem, I've managded to get the tank to detect the angle between itself and the waypoint, BUT, rather than orienting forward towards the waypoint, the right side of the tank orients towards it, so it orbits the waypoint. I actually know why this is, becasue the forward vector of the tank is technically the right vector because of unity's stupid axis ruining my blender import, anyway, heres the updated code:
void driveToTarget()
{
Vector3 target0 = driveTarget;
target0.y = 0;
Vector3 current0 = this.transform.position;
current0.y = 0;
print("Current: " + current0);
print("Target: " + target0);
Vector3 current0Angle = this.transform.rotation.eulerAngles;
print("Curret rotation:" + current0Angle.y);
current0Angle.x = 0;
current0Angle.z = 0;
Vector3 heading = target0 - current0;
Quaternion headingAngle = Quaternion.LookRotation(heading);
print("heading angle: " + headingAngle.ToEuler());
float distanceToGo = (current0Angle.y) - headingAngle.eulerAngles.y;
print("DistanceToGo: " + distanceToGo);
if (current0 != driveTarget)
{
steeringVal = 1 * -Mathf.Sign(distanceToGo);
throttleVal = 0f;
} else
{
throttleVal = 0;
}
Debug.DrawRay(current0, heading, Color.red, 1);
Debug.DrawRay(current0, this.transform.up, Color.red, 1);
}
I'm not sure exactly how your code is setup or how the steering works. You may want to look into using the Unity NavMeshAgent to simplify this.
Regardless here is some code I wrote up that takes a destination and rotates an object towards it. All you'd have to do from there is move the object forwards.
Vector3 nextDestination = //destination;
Vector3 direction = nextDestination - transform.position;
direction = new Vector3(direction.x, 0, direction.z);
var newRotation = Quaternion.LookRotation(direction);
var finalRotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime); //smoothes out rotation
transform.rotation = finalRotation;
Sorry if this isn't what you needed. Have you been able to figure out which part of the code is behaving unexpectedly from your print statements?

Unity: Faux Gravity - inner Capsule/ Cylinder

I'm struggling with false Gravity in a Cylinder or Capsule. Basically I thought I could take the same Code as for spherical gravity, which does not work. So I changed some lines to get a better result.
[SerializeField] float gravity = 10;
public void Attract ( Transform target )
{
Vector3 gravityUp = (target.position - new Vector3(transform.position.x, transform.position.y,target.position.z)).normalized;
Vector3 bodyDown = -target.up;
Rigidbody rb = target.GetComponent<Rigidbody>();
rb.AddForce(gravityUp * gravity);
Quaternion targetRotation = Quaternion.FromToRotation(bodyDown, gravityUp) * target.rotation;
targetRotation.x = 0;
target.rotation = Quaternion.Slerp(target.rotation, targetRotation, 30.0f * Time.deltaTime);
}
This worked OK on the first try. But the Player(target) can't rotate one the Y-Axis. Does anyone have any ideas?
OK, I tried the following.
Quaternion targetRotation = Quaternion.FromToRotation(bodyDown, gravityUp) * target.rotation;
targetRotation.x = 0;
target.rotation = Quaternion.Slerp(target.rotation, targetRotation, 30.0f * Time.deltaTime);
Now I use the Surface normal to rotate the Player.
if (Physics.Raycast(attractedBody.transform.position + attractedBody.transform.forward, -attractedBody.transform.up, out hit, distance))
{
surfaceNorm = hit.normal;
}
But without Rigidbody Contrains the Player starts rotating without any Input. So I have to use:
rb.constraints = RigidbodyConstraints.FreezeRotation;
This works.

How can I draw a circle in Unity3D?

How to draw circle in Unity 3d?
I want to draw a circle around different objects.
The radiuses of the circles are different and the circles have textures - squares.
I found a big error with this code. The number of points (Size) shouldn't be "(2 * pi / theta_scale) + 1" because this causes the circle to draw 6.28 times. The size should be "1 / theta_scale + 1". So for a theta_scale of 0.01 it needs to draw 100 points, and for a theta_scale of 0.1 it needs to draw 10 points. Otherwise it would draw 62 times and 628 times respectively.
Here is the code I used.
using UnityEngine;
using System.Collections;
public class DrawRadar: MonoBehaviour {
public float ThetaScale = 0.01f;
public float radius = 3f;
private int Size;
private LineRenderer LineDrawer;
private float Theta = 0f;
void Start() {
LineDrawer = GetComponent<LineRenderer>();
}
void Update() {
Theta = 0f;
Size = (int)((1f / ThetaScale) + 1f);
LineDrawer.SetVertexCount(Size);
for (int i = 0; i < Size; i++) {
Theta += (2.0f * Mathf.PI * ThetaScale);
float x = radius * Mathf.Cos(Theta);
float y = radius * Mathf.Sin(Theta);
LineDrawer.SetPosition(i, new Vector3(x, y, 0));
}
}
}
If you modify the number in "Size" that is divided by ThetaScale, you can make a sweeping gauge/pie chart type graphic.
See Unity Answers for a similar question.
Alternatively:
float theta_scale = 0.1; // Circle resolution
LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
lineRenderer.SetColors(c1, c2);
lineRenderer.SetWidth(0.2F, 0.2F);
lineRenderer.SetVertexCount(size);
int i = 0;
for(float theta = 0; theta < 2 * PI; theta += theta_scale) {
x = r*cos(theta);
y = r*sin(theta);
Vector3 pos = new Vector3(x, y, 0);
lineRenderer.SetPosition(i, pos);
i+=1;
}
The LineRenderer requires continuous points. You can modify this code slightly to use cylinder game objects instead of a line renderer. I find the LineRenderer to be a bit hideous.
Lastly, similar to the first link, you could attach a circle texture to a unit plane. Make any part of the texture that isn't part of the circle transparent. Then just scale and align the plane to fit your object. Unfortunately this method isn't great if someone is looking almost parallel to the plane.
Jerdak's solution is good, but the code is messy so I had to tweak a little. Here's the code for a class, where I use i in the loop to avoid a bug.
It also updates the circle's position with its gameObject position.
using UnityEngine;
using System.Collections;
public class CircleDraw : MonoBehaviour {
float theta_scale = 0.01f; //Set lower to add more points
int size; //Total number of points in circle
float radius = 3f;
LineRenderer lineRenderer;
void Awake () {
float sizeValue = (2.0f * Mathf.PI) / theta_scale;
size = (int)sizeValue;
size++;
lineRenderer = gameObject.AddComponent<LineRenderer>();
lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
lineRenderer.SetWidth(0.02f, 0.02f); //thickness of line
lineRenderer.SetVertexCount(size);
}
void Update () {
Vector3 pos;
float theta = 0f;
for(int i = 0; i < size; i++){
theta += (2.0f * Mathf.PI * theta_scale);
float x = radius * Mathf.Cos(theta);
float y = radius * Mathf.Sin(theta);
x += gameObject.transform.position.x;
y += gameObject.transform.position.y;
pos = new Vector3(x, y, 0);
lineRenderer.SetPosition(i, pos);
}
}
}
Using Shader Graph we can now draw pixel perfect circle.
Once you created this graph, create a new material based on this shader.
Then create a new gameobject with a sprite renderer and set the material you just created.
You can scale the circle using the "scale" parameter of the material.
The linerenderer method in the top answers is really simple and exactly what I was looking for. I updated it for newer versions of Unity and some small tweaks to make it a bit more beginner/user friendly.
Specifically:
LineRenderer.SetVertexCount() is deprecated in newer versions of Unity, replaced with positionCount
Replaced theta scale with an actual segment count to remove guesswork
Added loop setting - not sure if this was in older versions of Unity, it can be set in the LineRenderer's inspector
Removed unnecessary Update function - the rendered line is a persistent gameobject
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class DrawRing : MonoBehaviour
{
public LineRenderer lineRenderer;
[Range(6,60)] //creates a slider - more than 60 is hard to notice
public int lineCount; //more lines = smoother ring
public float radius;
public float width;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.loop = true;
Draw();
}
void Draw() //Only need to draw when something changes
{
lineRenderer.positionCount = lineCount;
lineRenderer.startWidth = width;
float theta = (2f * Mathf.PI) / lineCount; //find radians per segment
float angle = 0;
for (int i = 0; i < lineCount; i++)
{
float x = radius * Mathf.Cos(angle);
float y = radius * Mathf.Sin(angle);
lineRenderer.SetPosition(i, new Vector3(x, 0, y));
//switch 0 and y for 2D games
angle += theta;
}
}
}
Note this is assumed to be attached to the gameobject you want the ring around. So the Use World Space option in LineRenderer should be unchecked. Also remember that the scale of the gameobject will affect the position of the points and the width of the line.
To put this on the ground (as in a unit selection circle):
Put the script on a separate gameobject
Rotate the gameobject X to 90
Check use world space on the linerenderer
Set the linerenderer Alignment to Transform Z
Add the position of the thing you want to circle to x and y in SetPosition. Possibly along with replacing 0 with 0.1f or a yOffset variable to avoid z-fighting with terrain.
Circle can draw using shader - draw pixel if it on radius from center.
Did the following with a Sprite. Chan is flying in the scene, so she's slightly above the plane. I had her flying so I could get a good screenshot, not because it wouldn't play well with the plane.
I used a low-resolution circle sprite.
X rotation 90
Scale X 15, Y 15, Z 1
Then I set the Sorting Layer, so it will render above the Default Layer. I was testing this out when I came across this post. It doesn't handle shadows well. I'd have to figure out what layer shadows are drawn on to make sure they get rendered onto the sprite.
I have a shader from which I usually start making effects like lens flares, and it makes a circle. Using shader is the best choice because you will get perfectly smooth and round circle.
Also it's easy to experiment with and tune the shader since shader changes don't require recompile and re-entering of play mode.
I recommend ti create extension method to GameObject. Worked good to me.
public static class GameObjectExtension
{
const int numberOfSegments = 360;
public static void DrawCircle(this GameObject go, float radius,
float lineWidth, Color startColor, Color endColor, bool lineRendererExists=true)
{
LineRenderer circle = lineRendererExists ? go.GetComponent<LineRenderer>() : go.AddComponent<LineRenderer>();
circle.useWorldSpace = false;
circle.startWidth = lineWidth;
circle.endWidth = lineWidth;
circle.endColor = endColor;
circle.startColor = startColor;
circle.positionCount = numberOfSegments + 1;
Vector3 [] points = new Vector3[numberOfSegments + 1];
for (int i = 0; i < numberOfSegments + 1; i++)
{
float rad = Mathf.Deg2Rad * i;
points[i] = new Vector3(Mathf.Sin(rad) * radius, 0, Mathf.Cos(rad) * radius);
}
circle.SetPositions(points);
}
}
One More thing to note: If LineRenderer component is not applied last parameter has to be false
create a static class to reuse the code for different game objects. player, enemies... when the class is static, you cannot create the instance of it
public static class CircleGameObject
{
// in static class methods have to be static as well
// "this" refers to the context that we are calling DrawCircle
public static async void DrawCircle(this GameObject container,float radius,float lineWidth)
{
// I provide 360 points because circle is 360 degrees and we will connect them with line
var segments=360;
// LineRenderer is used to draw line
var lineRenderer=container.AddComponent<LineRenderer>();
// now you can use position system relative to the parent game object.
lineRenderer.useWorldSpace=false;
lineRenderer.startWidth=lineWidth;
lineRenderer.endWidth=lineWidth;
lineRenderer.positionCount=segments+1;
// reserve empty array in memory with a size of lineRenderer.positionCount
var points=new Vector3[lineRenderer.positionCount];
// draw all of those points
for(int i=0;i<points.Length;i++)
{
// converting degree to radian because Mathf.Cos and Mathf.Sin expects radian
var radian=Mathf.Deg2Rad*i;
// y direction needs to be 0
// Mathf.Cos(radiant) will give the x position on the circle if the angle size is "radian"
// Mathf.Sin(radiant) will give the y position on the circle if the angle size is "radian"
// after for loop completes we would be getting 360 points
points[i]=new Vector3(Mathf.Cos(radian)*radius,0,Mathf.Sin(radian)*radius);
}
lineRenderer.SetPositions(points);
}
}
then call it in Awake of the context
public class PlayerController : MonoBehaviour
{
private void Awake()
{
GameObject go=new GameObject{
name="Circle"
};
Vector3 circlePosition=Vector3.zero;
go.transform.parent=transform;
// localPosition is relative to the parent
go.transform.localPosition=circlePosition;
go.DrawCircle(2.0f,0.03f);
....
}
}