- Home /
How to make an object slowly move towards the center of the screen? [2d]
I have an enemy that I would like to have slowly move towards the center of the screen whenever it is created.
Answer by VoidPhoenix96 · Feb 23, 2021 at 04:15 AM
You could use NavMesh on your enemy and make it’s destination the middle of the screen. If you have never used NavMesh before I suggest this tutorial: https://youtu.be/CHV1ymlw-P8
But, that’s for 3D games. For 2D you should just lerp its position to the center using for loops. What you could also do if you want to use NavMesh is just make a 3D project and use 2D assets.
Answer by kskjadav007 · Feb 23, 2021 at 06:31 AM
First, you need to find the center point of the screen you can use this and use lerp to move object
private Vector3 m_pos; // Start is called before the first frame update void Start() { Vector3 m_center = new Vector3(Screen.width/2f, Screen.height/2f,Camera.main.nearClipPlane); m_pos= Camera.main.ScreenToWorldPoint(m_center); m_pos.z = 0f; } private void Update() { transform.position = Vector3.Lerp(transform.position, m_pos,0.1f); }
Something really weird is happening, and I don't know if its supposed to happen like this. 0.1 is obviously a very small number, but with that, it travels from the edge of the screen to the center almost instantly. It also seems to be moving exponentially, slowing down as it gets closer.
ok I don't think the 0.1 part is actually an issue; I was able to fix it easily. but the exponential problem persists
Answer by Ermiq · Feb 23, 2021 at 07:11 AM
To get center of the screen:
Vector3 screenCenter;
void Start()
{
screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 0);
}
If your objects are UI elements on a screen space canvas, then that's all you need. But if your objects are located in the world space scene, you need to find the point in world space that is located under the screen center point. You need the Camera
component that has a function ScreenToWorldPoint()
:
Camera cam = FindObjectOfType<Camera>(); //or, if you have multiple cameras, you can make this public and drag&drop your preffered camera in the inspector window in the editor
Vector3 screenCenterWorld = cam.ScreenToWorldPoint(screenCenter);
To move the object to it there are multiple ways, like Vector3.MoveTowards
, Vector3.Lerp
, Vector3.Slerp`, Vector3.SmoothDamp
... The easiest way that gives you ability to set the move speed and only takes one line of code is Vector3.MoveTowards
, You can use its 3rd argument as a speed limit, i.e, how many units you want the object to move every frame:
void Update()
{
// Move the object towards the center at the constant speed 0.1 units per frame:
object.transform.position = Vector3.MoveTowards(object.transform.position, screenCenter, 0.1f);
}
NOTE: If your objects are UI objects on a screen space canvas, this approach will lead to the situation where the object speed will be lower at higher resolution screens, and faster at lower resolutions, because the screenCenter and object position are actually points on screen in pixels. So, in this case, you'll need to scale the 0.1f speed with the screen resolution somehow. There's Screen.dpi
property that could be used for that, but it seem to not work in editor, so here's how I did it. I have a speed modifier, and at the start when I get the screen resolution I scale the speed modifier with the screen's height value:
float speedCoef = 0.5f;
void Start()
{
// Scale sensitivity with the screen resolution to get consistent speed on different resolutions
speedCoef *= Screen.height * 0.5f * 0.1f;
}
void Update()
{
// Move the object towards the center at the constant speed 0.1 units per frame:
object.transform.position = Vector3.MoveTowards(object.transform.position, screenCenter, speedCoef);
}
Had to tinker a bit with the values to get the desired speed, but it works fine so far.
I'm sorry, I have a few follow-up questions. How do I know if my objects are "UI elements on a screen space canvas"? Do I have to change the variable object? ('object' does not contain a definition for 'transform') How do I figure out which of the code-paragraphs I need to use?
If your enemy objects were UI object you would already know that. Because you would have had added the UI element Canvas to the scene and put the enemies at the Canvas as child objects. So, it's not your case.object
is your enemy. I don't know what is your enemy, so I just wrote object
as some game object that represents an enemy unit
.
As for what code parts you actually should use, well, there's no answer. It all depends on your project. I just gave you some examples and not actual ready-to-use project.