How can I move an object bullet towards a target? - unity3d

I want to shoot a bullet prefab towards a target. I want it to just go towards the target current location. If the target changes position the bullets should still go to the old target position, instead of the current position the target is at.
Vector2 pos;
pos.x = tracker.transform.position.x;
pos.y = tracker.transform.position.y;
transform.position = Vector2.MoveTowards(transform.position, pos, bulletSpeed * Time.deltaTime);
The above code just makes the bullet prefab track the object even though the object moves. If an object is at 0,0 then the bullet should go towards it but if the player changes its position to 1,1 the bullet should still go to 0,0

Simply cache the previous position that the object was at and MoveTowards that instead of the player as that will go to the current position. Instead of continually updating the pos.x and pos.y, set them initially when the bullet is fired and not again.
private Vector2 targetPos;
private bool bulletInited = false;
private float bulletSpeed;
public void InitBulletTarget(Vector2 target)
{
bulletInited = true;
targetPos = target;
}
private void Update()
{
if(bulletInited)
{
transform.position = Vector2.MoveTowards(transform.position, targetPos, bulletSpeed * Time.deltaTime);
}
}
When you Instantiate your bullet prefab, you will want to call the InitBulletPosition and send in the proper position which would be the tracker.transform.position.
An example would be
private void SpawnBullet()
{
// spawn the two bullets
YourBulletScript bullet1 = Instantiate(bullet, firePoint.position, firePoint.rotation).GetComponent<YourBulletScript>();
YourBulletScript bullet2 = Instantiate(bullet, firePoint2.position, firePoint2.rotation).GetComponent<YourBulletScript>();
// set their target position to move towards
bullet1.InitBulletTarget(tracker.transform.position);
bullet2.InitBulletTarget(tracker.transform.position);
}

Related

Unity 2D instantiate prefabs order

I'm instantiating enemy prefabs in waves, but when I do, the sprites are not consistent on the Z axis. Sometimes the second enemy is on top of the first one, and sometimes behind.
I want the new instance always behind the other.
Keep the instance position and instantiate the gameobject behind.
GameObject myGo1 = GameObject.Instantiate(prefabRef, Vector3.Zero,
Quaternion.Identity);
float distance = 1.0f;
Vector3 myGo2Pos = myGo1.position - myGo1.transform.forward * distance;
GameObject myGo2 = GameObject.Instantiate(prefabRef, myGo2Pos, Quaternion.Identity);
For the 1st GO instatiation, where Vector3.Zero you can choose the position of your choice. For whatever pos and rot you instantiate myGo1 with, the code Vector3 myGo2Pos = myGo1.position - myGo1.forward * distance; should instantiate the 2nd one distance meters behind.
Not debugged code, just for your inspiration.
Probably you might need the 2nd GO to look to the first one, in that case you can do:
GameObject myGo2 = GameObject.Instantiate(prefabRef, myGo2Pos, myGo1.transform.rotation);
Alright i figured it out. had to add a sprite renderer component like so:
SpriteRenderer spriteRenderer;
and where i instantiate:
void FollowPath()
{
if (!isAttacking)
{
if (waypointIndex < waypoints.Count)
{
**spriteRenderer = GetComponent<SpriteRenderer>();
spriteRenderer.sortingOrder++;**
Vector3 targetPosition = waypoints[waypointIndex].position;
float delta = waveconfig.GetMoveSpeed() * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, targetPosition, delta);
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
}
}

Vector2.MoveTowards -- Move To Target Position and Some More

I almost created game but there is one thing which is hard for me. I want to move player to target and some more.
The red dot is the goal, but I want to move the player to the goal and a little further.
P.S
If the player goes to the right then I want him to reach the goal and a little further to the right
same to the left, top, bottom
Look Attachment: https://imgur.com/a/RF0xIQq
Red dot is a target but i want player move to target and else more on the facing side (green dot)
i tried something like move forward but i dont have any idea.
void Start()
{
}
void Update()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
transform.position = Vector2.MoveTowards(transform.position, target.position, (speed * Time.deltaTime));
}
//Mob have "Player" TAG (Player is not a player) |Targeting is fine|
You could add an offset value
// ajdust this in the inspector
public float offset = 0.1f;
and than add it to the position in the direction from the player to the target. As Foggzie mentioned this might not be a copy-past-able code yet since there might occure some hickups. To atleast prevent that the player turn around after overshooting the target and move back and forth you could use a setter method to get the direction only once:
public float offset;
public float threshold = 0.0001f;
public float speed;
private GameObject target;
private Vector3 direction;
private Vector3 targetPosition;
public void SetTarget(GameObject newTarget)
{
target = newTarget;
// adding the offset in that direction
targetPosition = target.transform.position + direction * offset;
// direction from the player to the target
direction = (target.transform.position - transform.position).normalized;
}
private void Update()
{
if (!target) return;
// make Player overshoot the target by offset
transform.position = Vector2.MoveTowards(transform.position, targetPosition, (speed * Time.deltaTime));
// stop if target is reached
if (Vector3.Distance(transform.position, targetPosition) <= threshold)
{
target = null;
}
}
I don't know when and how you change the target so currently it doesn't limit the player movement to only X and Y like in your pictures ... but you would than do e.g.
// Note that 'transform' is a built-in property of 'GameObject' and you shouldn't use `GetComponent` for it
SetTarget(GameObject.FindGameObjectWithTag("Player").transform);

Updated position Unity3d

I have a bullet that has to hit a constantly moving enemy.
So, in BulletScript, I have declared a Transform
public Transform enemy; //and assigned enemy object to it that is continuously moving and changing its position
Now, when I try to use enemy.position in bullet script so as to hit it, enemy.positiongives the position at which the enemy strted and not the position at which it was when bulletprefab was shot.
How can I get the updated position of enemy object every time bulletprefab is instantiated.
This is how I am changing the enemy's position:
void Update () {
float amttomove = currentSpeed * Time.deltaTime;
transform.Translate (Vector3.left * amttomove);
if (transform.position.x < 0f)
setposandspeed();
}
void setposandspeed()
{
x = 11.5f;
z = 0.0f;
currentSpeed = Random.Range (MinSpeed, MaxSpeed);
y = Random.Range (0f, 2.5f);
transform.position = new Vector3(x, y, z);
}
This is where tried to use enemy's position in bulletscript:
float target_Distance = Vector3.Distance(Projectile.position, Target.transform.position );
It is called inside Start() of bulletscript
This is where I instantiated the bullet in Player class:
Inside Updated method:
if (Input.GetKeyDown ("space")) {
Vector3 position = new Vector3 (transform.position.x, transform.position.y + collider.bounds.size.y / 2);
Instantiate (bulletprefab, position, Quaternion.identity);
}
enemy.position in bullet script so as to hit it, enemy.positiongives
the position at which the enemy strted and not the position at which
it was when bulletprefab was shot.
No, enemy.position will return the current position of the enemy, suitable if you want your projectile follow the enemy.
If you are instantiating dynamically your projectiles (BullerScript) and want to shoot them toward the position the enemy is during the shoot frame, record it just after bullet is instantiated for example:
class BulletScript : MonoBehavior
{
public Vector3 targetPos;
void Update()
{
//move toward targetPos
}
}
BulletScript bullet = GameObject.Instantiate(bulletPrefab,shootPosition) as BulletScript;
bullet.targetPos = enemyPosition;

Moving object from one postion to another in unity

I have this code here ,i am trying to move an object from one position to another ,on mouse click ,but everytime i run it it justs instantiate the projectile object in a specific position while it had to instantiate it in a the ffor object position
using UnityEngine;
using System.Collections;
public class Shoot : MonoBehaviour
{
public GameObject projectile;
public GameObject foot;
public GameObject mouse;
void Start()
{
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector2 Target = Input.mousePosition;
Vector2 pos1 = Camera.main.ScreenToWorldPoint(Target);
GameObject newObj = (GameObject)GameObject.Instantiate(projectile);
Vector2 pos2 = foot.transform.position;
transform.position=Vector2.Lerp(pos2,pos1,Time.deltaTime);
}
}
There are several issues here, I'll address them one at a time. First, the code for moving the projectile is wired up wrong:
transform.position=Vector2.Lerp(pos2,pos1,Time.deltaTime);
You are moving the object that "Shoot" is attached to, not the new game object (newObj, as you have named it.)
Second, it's important to understand the Update pattern and how to properly use it. Update is run every frame. Time.deltaTime is how much time has passed between the last frame render and this one. This number is usually very small. Lastly, Input.GetMouseButtonDown is true only on the first frame that the mouse is pressed.
The current code you have only attempts to (but fails, due to other code problems) move the projectile the one frame the mouse is clicked. What we want is the mouse click to spawn a projectile, and the projectile to move forward EVERY update.
This will be best accomplished with two classes. I will call them Gun and SeekerBullet. The Gun class will be responsible for creating a bullet every time the mouse button is pressed. The SeekerBullet class will be responsible for moving the bullet to it's target.
Gun
public SeekerBullet ProjectilePrefab;
void Update()
{
if (Input.GetMouseButton(0))
{
Vector2 target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
FireBullet(target);
}
}
void FireBullet(Vector2 target)
{
GameObject projectile = (GameObject)GameObject.Instantiate(ProjectilePrefab, transform.position, Quaternion.Identity);
projectile.GetComponent<SeekerBullet>().Target = target;
}
SeekerBullet
public float MoveSpeed = 5;
public Vector2 Target { get; set; }
public void Update()
{
transform.position = Vector3.MoveTowards(transform.position, Target, MoveSpeed * Time.deltaTime);
if (transform.position == Target)
OnReachTarget();
}
void OnReachTarget()
{
// Do whatever you want here
Destroy(gameObject); // delete this seekerbullet
}
The main Idea I'm trying to stress is isolating your code to perform it's one function well. The gun shouldn't be responsible for moving the projectile, just creating it and telling it where to go.
Also, note that the projectile is starting wherever the Gun is. See this line
GameObject projectile = (GameObject)GameObject.Instantiate(ProjectilePrefab, transform.position, Quaternion.Identity);
The transform.position is the position of the gun object. If you want it to start at the foot, like you have in your code, you can re-implement that just like you have in your example.
Why don't you use Raycast. It's pretty simple. Here's an example (Moves the object (transform) in the direction and distance of translation.):
var obj:Transform;
var hit:RaycastHit;
var move: boolean = false;
var moveSpeed:float;
var moveTime:float;
private var startTime:float;
function Update ()
{
if (Input.GetButtonDown ("Fire1"))
{
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, hit, 10000)){
move = true;
startTime = Time.time;
}
}
if(move){
var curTime = Time.time;
var elapsedTime = curTime - startTime;
var amountToMove = elapsedTime / moveTime;
print(amountToMove);
obj.transform.position = Vector3.Lerp(obj.transform.position, hit.point, amountToMove);
if(obj.transform.position == hit.point){
move = false;
}
This code creates a plane, and a cube. Assign the above code to the plane, assign the cube to the obj var in the inspector. Click on the plane, and watch the fun.
This is pretty simple. You can use the Vector3.Lerp function to achieve this. Use raycasting to get the mouse click position or the touch position. Then use the initial and the final position in the lerp function. The initial position being the position that the gameobject is at now and the final position being the click / touch position.
You can find the article by The Game Contriver on the same here
Move to Touch / Click Position - The Game Contriver

how to move Camera smoothly in unity3D?

When I want to move Camera from origin position to destination position,it looks so stiff.So if it can set move speed accordding to offset,how to do ?
There is a nice tutorial on this problem, it is normally described at the beginning of all tutorials on the unity website. Inside the Survival Shooter Tutorial there is a explanation how to make the movement of the camera to the destination position smooth while moving.
Here is the code for moving the camera. Create a script, add it to the camera and add the GameObject you want to move to, into the scripts placeholder. It will automatically save the Transform component like setup in the script. (In my case its the player of the survival shooter tutorial ):
public class CameraFollow : MonoBehaviour
{
// The position that that camera will be following.
public Transform target;
// The speed with which the camera will be following.
public float smoothing = 5f;
// The initial offset from the target.
Vector3 offset;
void Start ()
{
// Calculate the initial offset.
offset = transform.position - target.position;
}
void FixedUpdate ()
{
// Create a postion the camera is aiming for based on
// the offset from the target.
Vector3 targetCamPos = target.position + offset;
// Smoothly interpolate between the camera's current
// position and it's target position.
transform.position = Vector3.Lerp (transform.position,
targetCamPos,
smoothing * Time.deltaTime);
}
}
You can use iTween plugins. And if you want your camera to move with your object ie to follow it smoothly. You can use smoothFollow script.
Have you tried using Vector3.MoveTowards? You can specify the step size to use, which should be smooth enough.
http://docs.unity3d.com/Documentation/ScriptReference/Vector3.MoveTowards.html
public Vector3 target; //The player
public float smoothTime= 0.3f; //Smooth Time
private Vector2 velocity; //Velocity
Vector3 firstPosition;
Vector3 secondPosition;
Vector3 delta;
Vector3 ca;
tk2dCamera UICa;
bool click=false;
void Start(){
ca=transform.position;
UICa=GameObject.FindGameObjectWithTag("UI").GetComponent<tk2dCamera>();
}
void FixedUpdate ()
{
if(Input.GetMouseButtonDown(0)){
firstPosition=UICa.camera.ScreenToWorldPoint(Input.mousePosition);
ca=transform.position;
}
if(Input.GetMouseButton(0)){
secondPosition=UICa.camera.ScreenToWorldPoint(Input.mousePosition);
delta=secondPosition-firstPosition;
target=ca+delta;
}
//Set the position
if(delta!=Vector3.zero){
transform.position = new Vector3(Mathf.SmoothDamp(transform.position.x, target.x, ref velocity.x, smoothTime),Mathf.SmoothDamp( transform.position.y, target.y, ref velocity.y, smoothTime),transform.position.z);
}
}