How do I make my GameObject move towards another GameObject using Vector3.MoveTowards method?
Heres my current code:
void update()
{
TargetObject.transform.position = Vector3.MoveTowards (TargetObject.transform.position, Cube.transform.position , MaxDistanceDelta);
}
void Update() {
myGameObject.transform.position = Vector3.MoveTowards(myGameObject.transform.position, targetObject.transform.position, Time.deltaTime * speed);
}
myGameObject - object you want to move
targetObject - object you are moving to
speed - float value to set the speed
First, let's see the details and parameters of the method:
MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta);
Understanding the parameters
Vector3 current: 3D vector of the object position (example: new Vector(0,0,1))
Vector3 target: 3D vector of the target position (example: new Vector(3,4,5))
maxDistanceDelta: maximum distance that the object will move when the method is called. (Example: if maxDistanceDelta is 1, the object will move 1 unit every time it's called. In case we are not using Time.deltaTime it would move 50 units a second if the frame rate is 50)
Note: If the actual distance remaining is less than maxDistanceDelta, it will be placed on target position. Meaning the object will no longer move unless the target position changes.
Example:
Declaring the variables:
public float speed;
public Transform target;
Using the method:
transform.position = Vector3.MoveTowards(
transform.position,
target.position,
speed * Time.deltaTime
);
Related
how to make constant movement on z axis via character controller. I need my character to constantly move forward at the same speed
The forward axis of your character: transform.forward
Basic Solution with Transform:
public float speed = 2f;
public void Update()
{
transform.position += transform.forward * (speed * Time.deltaTime);
}
Relative movement with Transform.Translate;
transform.Translate(Vector3.forward * (speed * Time.deltaTime));
Basic Rigidbody velocity Setter:
private Rigidbody rigidbody;
public void Start()
{
rigidbody = GetComponent<Rigidbody>();
}
public void Update()
{
rigidbody.velocity = transform.forward * speed;
}
There are a couple ways of doing this. One is to simply move the object along the z axis via code with no care for physics. this will hold a constant velocity in that direction. You can hopefully see how this type of approach could e expanded for all directions by swapping out the zPosChange float for a vector representing the direction you want to move in. This is a kinematic position update.
public float speed = 10;
void Update()
{
float zPosUpdate = gameObject.transform.position.z
zPosUpdate += speed * Time.deltaTime;
gameObject.transform.position = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, zPosUpdate );
}
The other way is to use the unity physics system to add force to a rigidbody component. To do this you must first have added a rigidbody and a collider to the object you are controlling. Since we want constant velocity and not acceleration and deceleration I wouldn't recommend that unless you really need the object to be able to be affected physically by collisions. You would do similar to the example I've given here but instead of the transform position you would set the velocity on the rigidbody component.
You can use Add Force to you character.
character_Rigidbody.AddForce(transform.forward * speed* Time.deltaTime);
I'm pretty new to Unity. I tried to create a script that the camera would follow the actor (with a little difference). Is there a way to improve the code? It works just fine. But I wonder if I did it the best way. I want to do it about as I wrote, so if you have any tips. Thank you
Maybe change Update to FixedUpdate ?
public GameObject player;
// Start is called before the first frame update
void Start()
{
player = GameObject.Find("Cube"); // The player
}
// Update is called once per frame
void Update()
{
transform.position = new Vector3(player.transform.position.x, player.transform.position.y + 5, player.transform.position.z - 10);
}
Making the camera following the player is quite straight forward.
Add this script to your main camera.
Drag the reference of the player object to the script and then you are done.
You can change the values in the Vector 3 depending on how far you want the camera to be from the player.
using UnityEngine;
public class Follow_player : MonoBehaviour {
public Transform player;
// Update is called once per frame
void Update () {
transform.position = player.transform.position + new Vector3(0, 1, -5);
}
}
Follows player in the back constantly when the player rotates, no parenting needed, with smoothing.
Piece of Knowledges:
Apparently, Quaternion * Vector3 is going to rotate the point of the Vector3 around the origin of the Vector3 by the angle of the Quaternion
The Lerp method in Vector3 and Quaternion stand for linear interpolation, where the first parameter gets closer to the second parameter by the amount of third parameter each frame.
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 locationOffset;
public Vector3 rotationOffset;
void FixedUpdate()
{
Vector3 desiredPosition = target.position + target.rotation * locationOffset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
Quaternion desiredrotation = target.rotation * Quaternion.Euler(rotationOffset);
Quaternion smoothedrotation = Quaternion.Lerp(transform.rotation, desiredrotation, smoothSpeed);
transform.rotation = smoothedrotation;
}
}
This will always follow the player from the same direction, and if the player rotates it will still stay the same. This may be good for top-down or side-scrolling view, but the camera setup seems to be more fitting for 3rd person, in which case you'd want to rotate the camera when the player turns.
The easiest way to do this is actually not with code alone, simply make the camera a child of the player object, that way its position relative to the player will always stay the same!
If you do want to do it through code, you can change the code to be like this:
void Update()
{
Vector3 back = -player.transform.forward;
back.y = 0.5f; // this determines how high. Increase for higher view angle.
transform.position = player.transform.position - back * distance;
transform.forward = player.transform.position - transform.position;
}
You get the direction of the back of the player (opposite of transform's forward). Then you increase the height a little so the angle will be a bit from above like in your example. Last you set the camera's position to be the player's position and add the back direction multiplied by the distance. That will place the camera behind the player.
You also need to rotate the camera so it points at the player, and that's the last line - setting the camera's forward direction to point at the player.
Here is just another option. I always find it easier to have the variables which are populated in the inspector so you can adjust it and fine tune it as needed.
public GameObject player;
[SerializeField]
private float xAxis, yAxis, zAxis;
private void Update()
{
transform.position = new Vector3(player.transform.position.x + xAxis, player.transform.position.y + yAxis, player.transform.position.z + zAxis);
}
Attempting to create a 2D game where force is added to a RigidBody2D according to the rotation of the object.
The object is a projectile. Objects spawn at their intended rotation but only move right along the X axis instead according to the rotation.
Anyone know where I'm going wrong?
// Start is called before the first frame update
void Start()
{
myRB = gameObject.GetComponent<Rigidbody2D>();
timer = Time.time + lifetime;
}
private void FixedUpdate()
{
myRB.AddRelativeForce(transform.right * thrust);
if(Time.time > timer)
{
Destroy(this.gameObject);
}
}
transform.right is already
The red axis of the transform in world space.
with the orientation applied.
You are passing that in again as a Vector relative to the local space of the object which is not what you want.
Either use in world space
myRB.AddForce(transform.right * thrust);
or in local space
myRB.AddRelativeForce(Vector3.right * thrust);
I tried this code but it doesn't work correctly.
Edit: LookAt makes the GameObject invisible
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyPoint : MonoBehaviour {
public float offset;
public Transform target;
private void Update()
{
Vector2 difference = target.position - transform.position;
float rotZ = Mathf.Atan(difference.y) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
}
}
You can use LookAt.
Rotates the transform so the forward vector points at target's current position.
transform.LookAt(target);
Simply place this on your objectA and in the target field drag&drop any other objectB → objectA's forward vector will always point towards objectB.
An alternative overwrite also takes a world position as Vector3 instead so you can also use
transform.LookAt(target.position);
which will basically do exactly the same thing.
If you need another axis pointing towards the target you can still use LookAt and afterwards Rotate. E.g. in order to not make the forward but rather the up Vector of the object point towards the target you can use
transform.LookAt(target);
transform.Rotate(Vector3.right * 90);
this thread is pretty old, but nonetheless i thought i might just pitch in. In line 13 you're using the wrong trig function. Using Mathf.Atan2(y, x) yields the arctangent y/x in the range of -π to +π, instead, you're using Mathf.Atan(y) which just does calculations based on y only and doesn't take into account the x value as well.
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg //Get arctangential of x and y and turn it into degrees with 180/π
I have been trying this for two days with no success. I cant figure out where I'm missing the point. All the missiles are moving towards the position of the target but not following it. The position remains fixed and all the newly created missiles come to this point instead of following the target.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HomingMissile : MonoBehaviour
{
private GameObject target; //changed to private
private Rigidbody rb;
public float rotationSpeed;
public float speed;
Quaternion rotateToTarget;
Vector3 direction;
private void Start()
{
target = GameObject.FindGameObjectWithTag("Player"); //uncommented this
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
//made some modifications
Vector3 direction = (target.transform.position - transform.position).normalized;
float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;//interchanged x and z
Quaternion rotateToTarget = Quaternion.Euler(0, angle, 0);
transform.rotation = Quaternion.Slerp(transform.rotation, rotateToTarget, Time.deltaTime * rotationSpeed);
Vector3 deltaPosition = speed * direction * Time.deltaTime;
rb.MovePosition(transform.position + deltaPosition);
}
}
I selected the target(transform) using the inspector.
I'm using Unity and C# obviously you know that.
What Im trying to achieve is that the missile should follow the position of the target in real time. And i can add the destroy code for the missile myself.
Note :
Please don't tag this as a duplicate. It is not.
The game is 2D where Y is always constant. Vertical axis is X and Horizontal axis is X. The objects are 3D. That's why I can't use rigidbody2D.
EDIT:
Code edited. The missile follows the target and also points to the direction of motion. How to make the missile make a circular rotation when it needs to rotate?
Firstly, consider:
Not modifying a rigidbody.velocity directly, as it will result in unrealistic behaviour
Using FixedUpdate() instead of Update() when controlling rigidbodies
Use rigidbody.movePosition() and rigidbody.moveRotation() instead. Here's an example:
Vector3 dir = (target.transform.position - transform.position).normalized;
Vector3 deltaPosition = speed * dir * Time.deltaTime;
rb.MovePosition(transform.position + deltaPosition);
Try out rigidbody.MoveRotation() yourself for practice.
Finally, understand that there are many ways to implement homing for missiles. Here's one that is commonly used in real life.
Edit: I will not recommend using rb.addForce() because if u try it out u will realise it is too indeterministic.