anaksky2k19
anaksky2k19

Reputation: 51

How do I Instantiate Objects In Unity?

I am making a top down game in Unity, how do I instantiate objects based on the players current position from the top of the camera view in Unity?

So far I have tried:

Instantiate(prefab, player.transform.position * 2 * Space.World)

but this didn't work. This just spawned objects from the center of the camera.

Upvotes: 2

Views: 3882

Answers (1)

derHugo
derHugo

Reputation: 90580

Space is simply an enum and has nothing to do with what you are trying! (Its purpose is to define the relative transform space for e.g. Transform.Rotate or Transform.Translate)

in that enum afaik

  • Space.World simply has the int value 0
  • Space.Self has the int value 1

so what you actually do is

Instantiate(prefab, player.transform.position * 2 * 0);

which equals

Instantiate(prefab, Vector3.zero);

which means the object is instantiated at World position 0,0,0.

Also using

Instantiate(prefab, player.transform.position * 2);

looks a bit strange. Are you sure you want to duplicate the actual position of the player? This would mean the spawned object is always on a line with the player and the World 0,0,0 and always double as far from the center as the player.


To me it sounds more like you rather want to spawn something in front of the player ... depending on the player's view direction (in topdown games usually player.transform.up or player.transform.right) so I guess what you are trying to do instead is something like

Instantiate(prefab, player.transform.position + player.transform.forward * 2);

which would instead spawn the object 2 Unity units in front of the player object


After your comment it sounds like instead you want to spawn the object at the player position on the X-axis but "over it" on the Y-axis so

Instantiate(prefab, player.transform.position + Vector3.Up * 2);

maybe you'll have to tweak the 2 depending how your player can move and how far it has to be to be "off screen". Alternatively you could also use a bit more complex using Camera.ScreenToWorldPoint

// get players position
var playerPos = player.transform.position;

// get camera's position
var cameraPos = Camera.main.transform.position;

// get difference on Z-axis
var cameraDistance = cameraPos.z - playerPos.z;

// Get the world 3d point for the upper camera border
// don't care about the X value
// and as distance we use the z-distance to the player
var cameraTopPoint = Camera.main.ScreenToWorldPoint(new Vector3(0, Camera.main.pixelHeight, cameraDistance);

// use the players X-axis position
cameraTopPoint.x = player.transform.x;

// to spawn it exactly on the Screen border above the player
Instantiate(prefab, cameraTopPoint);

// or to spawn it a bit higher
Instantiate(prefab, cameraTopPoint + Vector3.Up * 1);

Update

you said you want the prefab to be spawned on the "opposide" of the player position on the X axis.

If your Camera is static on world x=0 than this is actually quite simple:

cameraTopPoint.x = -player.transform.x;

If your camera is moving or not on x=0 than we have to calculate it already on the screen position level:

// get players position
var playerPos = player.transform.position;

// additionally convert the player position to screen space
var playerScreenPos = Camera.main.WorldToScreenPoint(playerPos);

var centerX = Camera.main.pixelWidth / 2.0f;

// get the difference between camera an player X (in screen space)
var differenceX = Mathf.Abs(playerScreenPos.x - centerX);

// here calculate the opposide side
var targetX = centerX + differenceX * (playerScreenPos.x < centerX ? 1 : -1);
// or alternatively if you want e.g. that the prefab always
// spawn with a bit of distance to the player even though he is very close
// to the center of the screen you could do something like
//var targetX = centerX + centerX / 2 * (playerScreenPos.x < centerX ? 1 : -1);

// Get the world 3d point for the upper camera border
// with the calculated X value
// and as distance we use the z-distance to the player
var cameraTopPoint = Camera.main.ScreenToWorldPoint(new Vector3(targetX, Camera.main.pixelHeight, playerScreenPos.z);

// to spawn it exactly on the Screen border above the player
Instantiate(prefab, cameraTopPoint);

// or to spawn it a bit higher
Instantiate(prefab, cameraTopPoint + Vector3.Up * 1);

Other Update

Ok so you want the prefab always spawn next to the player in a certain distance. The side depends on which side of the screen the player is so you could actually use the first approach again but just add the desired distance:

// Adjust this is the Inspector (in Unity units)
public float spawnDistanceToPlayer;

...

// get players position
var playerPos = player.transform.position;

// additionally convert the player position to screen space
var playerScreenPos = Camera.main.WorldToScreenPoint(playerPos);

var centerX = Camera.main.pixelWidth / 2.0f;

// Get the world 3d point for the upper camera border
// with the calculated X value
// and as distance we use the z-distance to the player
var cameraTopPoint = Camera.main.ScreenToWorldPoint(new Vector3(playerScreenPos.x, Camera.main.pixelHeight, playerScreenPos.z);

// now add or reduce spawnDistanceToPlayer 
// depending on which side of the screen he is
cameraTopPoint.x += spawnDistanceToPlayer * (playerScreenPos.x < centerX ? 1 : -1);

// OR if your camera sits static on X=0 anyway you also could compare
// the player position directly without calculating in screenspace:
cameraTopPoint.x += spawnDistanceToPlayer * (playerPos.x < 0 ? 1 : -1);

// to spawn it exactly on the Screen border above the player
Instantiate(prefab, cameraTopPoint);

// or to spawn it a bit higher
Instantiate(prefab, cameraTopPoint + Vector3.Up * 1);

Typed on smartphone so might not be "copy-paste-able" ;)

Upvotes: 5

Related Questions