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

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);

Related

How can I move an object bullet towards a target?

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);
}

Unity3D Part Movement

With the help from people here (and the Unity forum) I am almost happy with the build i am making.
This build is showing a Booster Pump, used for boosting waterpressure for industrial cleaning.
So far i can zoom, rotate, Pan and press keys 1-3 to show/hide internal parts.
I would like to make the internal parts MOVE out to position on keypress, instead of just appearing in position (like they do now - 1st. image), so I have this movement script.
But when i rotate/move the Booster Pump, the it does not look right (2nd image).
The moved part is not following the main part of the Booster Pump.
From what I gather it have to do with local or world space, but I dont know which and how to implement it?
enter image description here
enter image description here
{
Vector3 EndPos;
Vector3 StartPos;
private float distPos;
public float MovSpeed;
private float direction = 0f; // The direction of travel
public float maxDistance = 2f; // The maximum move distance
void Start()
{
StartPos = transform.position;
EndPos = StartPos + Vector3.back * maxDistance;
}
void Update()
{
if (Input.GetKey(KeyCode.Space) && distPos == 1f)
direction = -1f;
if (Input.GetKey(KeyCode.Space) && distPos == 0f)
direction = 1f;
distPos = Mathf.Clamp01(distPos + (Time.deltaTime * MovSpeed * direction));
if (distPos == 0f || distPos == 1f) direction = 0f;
transform.position = Vector3.Lerp(StartPos, EndPos, distPos);
}
If the internal parts are child objects of the parent, and you want them to move around independently while also continuing to rotate and move with their parent, you should change their localPositions. By changing local position instead of world, you are telling them to move that distance away from their initial positions, relative to the center of their parent - no matter where the parent is or how it's rotated at the time.
Try changing
StartPos = transform.position;
to
StartPos = transform.localPosition;
and then change
transform.position = Vector3.Lerp(StartPos, EndPos, distPos);
to
transform.localPosition = Vector3.Lerp(StartPos, EndPos, distPos);

Unity, How to make the friction work with movement

I have a 3d world with a simple platform with a cube representing the player. When I rotate the platform the cube glides and perform as you expect when increase and decrease the friction in the physics material.
I want the cube to glide after the input for example forward is terminated. It does not. I tried to update the position with rigidbody.position and update it. I quickly understood that it would not work with the physics engine.
Now I have the following code. It does not work as expected anyway. I would like to have some pointers to solve this.
public class Player1 : MonoBehaviour
{
private float speed = 10f;
private Vector3 direction;
private Vector3 velocity;
private float vertical;
private float horizontal;
Rigidbody playerRigidBody;
// Start is called before the first frame update
void Start()
{
playerRigidBody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
vertical = Input.GetAxisRaw("Vertical");
horizontal = Input.GetAxisRaw("Horizontal");
direction = new Vector3(horizontal, 0, vertical);
}
private void FixedUpdate()
{
velocity = direction.normalized * speed * Time.fixedDeltaTime;
playerRigidBody.MovePosition(transform.position + velocity);
}
}
Use playerRigidBody.AddForce(Vector3 direction, ForceMode forceMode) to move your player.
If you don't want your player to move at a demential speed use playerRigidBody.velocity = Vector3.Clamp(Vector3 vec3, float minValue, float maxValue);
Then play with different variables to get the result you want !

Unity2D - Rigidbody not stopping when it reaches a position

I have this code:
public class MoveCard : MonoBehaviour
{
public float speed = 1f;
public Rigidbody2D rb;
public Vector2 pos = new Vector2(6.8f,0);
public bool move = false;
void FixedUpdate(){
if (move){
//Stops Rigidbody
if (rb.position == pos){
move = false;
}
rb.transform.position += -rb.transform.right * speed * Time.fixedDeltaTime;
}
}
public void CardMovement(){
move = true;
}
}
I have it set as so when a button is pressed, CardMovement() initiates and in FixedUpdate I have a if statement that turns move off when the Rigidbody reaches a certain position. The rb moves but it doesn't stop when it reaches the Vector2. I am new to Unity so I don't know if this is the way to do it.
Well your Rb doesn't pass exactly for each point between the initial position and Vector2.
It's prtty unlikely to have rb.position == pos because one frame it will not enough, and the next one will be too much :)
Try with MoveTowards. Some like this:
rb.position = Vector3.MoveTowards(rb.position, pos, speed * Time.fixedDeltaTime);
You dont need a statement to stop it because it will do it when reaches pos.
PD: You can do this with transform instead of rigidbody if u are not going to use physics and you only want a movement.
Don't compare the 2 vector2D values like this:
if(rb.position == pos)
Rather compare the distance between them with a value that is very small, like this:
if(Vector2.Distance(rb.position,pos) <= 0.01)
Additionally, you can set the position like this rb.postion = pos; if it is close enough so that it snaps to the right location.

Rotate camera based on mouse postitions around a object Unity3D

Okay, So I have come this far:
public class CameraScript : MonoBehaviour {
public void RotateCamera()
{
float x = 5 * Input.GetAxis("Mouse X");
float y = 5 * -Input.GetAxis("Mouse Y");
Camera.mainCamera.transform.parent.transform.Rotate (y,x,0);
}
}
My camera has a parent which I rotate based on my mouse position. The only problem is that I can only swipe with the mouse to rotate the object. How can I rotate the object which is my camera is attached to based on my mouse position if I just click next to the object. Thanks in advance!
The value will be in the range -1...1 for keyboard and joystick input.
If the axis is setup to be delta mouse movement, the mouse delta is
multiplied by the axis sensitivity and the range is not -1...1. Unity Document
Note: This link is usefull please check it.
So you need to change your code like this.
public void RotateCamera()
{
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // Gets mouse position to Unity World coordinate system
Camera.mainCamera.transform.parent.transform.Rotate (mousePosition);
}
if there are problem you can do like this
public void RotateCamera()
{
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y,0);
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(position); // Gets mouse position to Unity World coordinate system
Camera.mainCamera.transform.parent.transform.Rotate (mousePosition);
}
one more option is rotateTowards.
public float speed=10; //any value > 0
public void RotateCamera()
{
Vector3 targetDir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - Camera.mainCamera.transform.parent.transform.position;
float step = speed * Time.deltaTime;
Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
Camera.mainCamera.transform.parent.transform.rotation = Quaternion.LookRotation(newDir);
}
Maybe some syntax errors, i don't check them.