I'm really new to coding and English isn't my main language, so forgive any dumb errors and my English.
I'm working on a movement system that moves the player to click point, everything on the script seems to work, but in the game tab the player doesn't move at all. I already read a lot of information about Vector3.MoveTowards(), but nothing worked for me.
Vector3 currentpos;
Vector3 targetpos;
bool ismoving = false;
public float speed = 10f;
void Update()
{
currentpos = transform.position;
move();
if (Input.GetMouseButtonDown(0))
{
click();
}
}
void click() //get the position of the click using a raycast//
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
targetpos = hit.point;
targetpos.y = 0f; //only whants to move the player in the x and z axis//
ismoving = true;
move();
}
}
void move()
{
if (ismoving==true)
{
if (Vector3.Distance(currentpos,targetpos)>0.1f) //if distance between current position and target position is greater than 0.1f player should move//
{
currentpos = Vector3.MoveTowards(currentpos, targetpos, speed * Time.deltaTime);
Debug.Log("Current Position is:" + currentpos + " and target position is" + targetpos);
}
if(Vector3.Distance(currentpos,targetpos)<0.1f)
{
ismoving = false;
}
}
}
In the console the current position and the target position are right but the player doesn't move.
Well, you are chaning the value of currentpos but never asign it back to transform.position e.g. here
currentpos = Vector3.MoveTowards(currentpos, targetpos, speed * Time.deltaTime);
transform.position = currentpos;
Related
so I have an issue about movement click on unity it's about when I click of course the player will be moving to the position I clicked but, I don't want if I clicked on the wall and another button the player will be on the last mouse I clicked, I already add some collider but the player just bypass the collider so collider doesn't have any effect
the explanation
and this the script
[Header("Tweak")]
[SerializeField] Transform target;
Vector2 targetPos;
public float speed = 5f;
// Start is called before the first frame update
void Start()
{
targetPos = transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
public void Move()
{
if (Input.GetMouseButtonDown(0))
{
targetPos = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition);
if ((targetPos.x >= transform.position.x))
{
transform.localScale = new Vector2(.5f, .5f);
}
else
{
transform.localScale = new Vector2(-.5f, .5f);
}
target.position = targetPos;
}
if ((Vector2)transform.position != targetPos)
{
transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
}
}
You can do this using Raycast
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.collider.gameObject.tag == "Wall")
{
Debug.Log("tag");
//You can do what ever you want here.
}
}
}
I am trying to move my camera to a clicked Gameobjects position with a specified offset. So the script should calculate the resulting position by the clicked gameobjects position, the actual camera position and a offset.
I have tried it with this code:
Vector3 distanceVector = transform.position - target.transform.position;
Vector3 distanceVectorNormalized = distanceVector.normalized;
targetPosition = (distanceVectorNormalized * preferredDistance);
But I am getting some really weird values. Here is the code I made for this:
public float moveSpeed = 0.1f;
private bool moving = false;
private GameObject target;
// The distance between the camera and the targets position
private float preferredDistance = 3;
// The position the camera will move to
private Vector3 targetPosition;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit, 100) == false) return;
Debug.Log(hit.transform.gameObject.name);
target = hit.transform.gameObject;
... Here should be the calculations
moving = true;
}
if (moving)
{
transform.position = Vector3.Lerp(transform.position, targetPosition, moveSpeed);
transform.LookAt(target.transform.position);
var offsetX = Math.Abs(transform.position.x - targetPosition.x);
var offsetZ = Math.Abs(transform.position.z - targetPosition.z);
if (offsetX < .01
&& offsetZ < .01) moving = false;
}
}
Your normalized distanceVector acts as the direction of the camera to the object.
This direction should be normalized, which you do, so it can be multiplied by your preferredDistance. It then becomes the offset of the camera from the target.
The part where it goes wrong is that you set this normalized offset as the new camera position, while it should be added to it:
Vector3 distanceVector = transform.position - target.transform.position;
Vector3 distanceVectorNormalized = distanceVector.normalized;
targetPosition = target.transform.position + (distanceVectorNormalized * preferredDistance);
Note the difference in the last line.
I have an object moving forward constantly, I want to make it move on the X axis by mouse dragging any part of the screen (swiping), so I tried this code but when first clicking on the screen the object move to the mouse X position (without dragging)! do you have any suggestions on how to make it move only when dragging?
The Script:
private bool dragging = false;
private float distance;
public Rigidbody Ball;
public float Speed = 100;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
Ball.velocity = transform.forward * Speed * Time.deltaTime;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
distance = Vector3.Distance(transform.position, Camera.main.transform.position);
dragging = true;
}
if(Input.GetMouseButtonUp(0))
{
dragging = false;
}
if (dragging)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Vector3 rayPoint = ray.GetPoint(distance);
transform.position = new Vector3(rayPoint.x, transform.position.y, transform.position.z);
}
}
For the continues movement you can use GetMouseButton which is true while the button stays pressed (in contrary to GetMouseButtonDown which is true only the first frame the button is pressed)
You said the script is attached to the same as the RigiBody component. In such a case you should never place an object using
transform.position = ...
but instead use RigidBody.MovePosition like
Ball.MovePosition(new Vector3( ... ));
Finally store the initial position on mouse down and than use it as a reference point:
Vector3 initialPosition;
void Update()
{
// called the first time mouse button is pressed
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
initialPosition = transform.position;
Vector3 rayPoint = ray.GetPoint(0);
// Not sure but this might get you a slightly better value for distance
distance = Vector3.Distance(transform.position, rayPoint );
}
// called while button stays pressed
if (Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Vector3 rayPoint = ray.GetPoint(distance);
Ball.MovePosition(initialPosition + new Vector3(rayPoint.x, 0, 0));
}
}
Also note that I'm not sure that
// Update is called once per frame
void FixedUpdate () {
Ball.velocity = transform.forward * Speed * Time.deltaTime;
}
is what you want to do. The usage of Time.deltaTime makes not much sense here in my eyes. You either want to set the velocity to a certain speed like
Ball.velocity = transform.forward * Speed;
or you want to change a position using Time.deltaTime to have a smooth movement like
Ball.MovePosition(transform.position + transform.forward * Speed * Time.deltaTime);
I have a ball that have a continuous bouncing, and I want to move it left and right in the x Axis with the mouse, so it follow the mouse's X movement.
I made the script bellow, but the ball didn't move with mouse!
Ball Script:
private Vector3 pos;
public Camera cam;
public Rigidbody Ball;
public float Speed;
public static float GlobalGravity = -9.8f;
public float GravityScale = 1.0f;
bool isforce = false;
private void Start(){
Ball = GetComponent<Rigidbody>();
Ball.useGravity = false;
}
private void FixedUpdate(){
Vector3 gravity = GlobalGravity * GravityScale * Vector3.up;
Ball.AddForce(gravity, ForceMode.Acceleration);
}
void force (){
isforce = false;
Ball.AddForce(Vector3.up * Speed, ForceMode.Impulse);
}
private void Update(){
if (isforce == true){
force();
}
if (Input.GetMouseButton(1)){
Vector3 mousePos = Input.mousePosition;
Vector3 wantedPos = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, transform.position.y, 10));
transform.position = wantedPos;
}
}
private void OnCollisionEnter(Collision collision){
isforce = true;
}
try this and let me know what happens. yours was set to right click, but i changed this one to left click, other than that i just sat the balls x to the raw x of the mouse input.
private void Update(){
if (isforce == true){
force();
}
if (Input.GetMouseButton(0)){
Vector3 mousePos = Input.mousePosition;
Vector3 wantedPos = transform.position;
wantedPos.x=Input.mousePosition.x;
transform.position = wantedPos;
}
}
When you use transform.position, the Unity Physics will no apply to the rigidBody. Find your mouse position relative to the ball and add Force in the X direction accordingly.
You have a couple of options depending on what it is you want.
Also as #Hamed answered, when using physics you don't want to update the transform directly but add force using the Rigidbody.
Force Constant relative to where the Mouse is
if (Input.GetMouseButton(0))
{
Vector2 force = Vector2.zero;
//Get the Balls current screenX position
float ballX = Camera.WorldToScreenPoint(Ball.transform.position).x;
//Check if Click was Left or Right of the Ball
if (ballX > Input.mousePosition.x)
{
//Click was Left of the Ball
force = new Vector2(-1f, 0f);
}
else if (ballX < Input.mousePosition.x)
{
//Click was Right of the Ball
force = new Vector2(1f, 0f);
}
//Adjust force amount to your suiting
Ball.Addforce(force * Time.deltaTime);
}
Force relative to the mouse movement
if (Input.GetMouseButton(0))
{
Vector2 force = Vector2.zero;
float mouseDelta = Input.GetAxis("Mouse X");
//Check if the Mouse is going Left or Right
if (mouseDelta < 0f)
{
//Click was Left of the Ball
force = new Vector2(-1f, 0f);
}
else if (mouseDelta > 0f)
{
//Click was Right of the Ball
force = new Vector2(1f, 0f);
}
// Update force relative to mouse movement
force = Mathf.Abs(mouseDelta) * force;
//Adjust force amount to your suiting
Ball.Addforce(force * Time.deltaTime)
}
Hastily written, look then write your own :)
So here's the problem in video form
https://pbs.twimg.com/tweet_video/CPsvjgbWoAACKCp.mp4
When not moving the ship the shield moves around just fine, but when you start moving it can only drag behind you and move a little bit, which is just no good at all. I can't figure out what I've done wrong here!
public class ShieldMovement : MonoBehaviour {
public Transform target; //player shield is attaced to
public float circSpeed = 0.1f; // Speed Shield moves around ship
private Vector3 direction = Vector3.up;
private float distance = 0.8f; // distance from player so it doesn't clip
private float deadzone = 0.15f;
private float separation;
private bool canMove = true;
private Vector3 shipPos;
private Rigidbody2D tRB;
private Rigidbody2D rb;
// Use this for initialization
void Start ()
{
tRB = target.GetComponent<Rigidbody2D>();
rb = GetComponent<Rigidbody2D>();
}
void OnCollisionEnter2D (Collision2D other)
{
canMove = false;
}
void OnCollisionStay2d(Collision2D other)
{
canMove = false;
}
void OnCollisionExit2D (Collision2D other)
{
canMove = true;
}
// Update is called once per frame
void Update () {
float rh = Input.GetAxisRaw("rightH");
float rv = Input.GetAxisRaw("rightV");
shipPos = target.position;
separation = Mathf.Abs((transform.position - shipPos).magnitude);
if(Mathf.Abs(rh) > deadzone || Mathf.Abs(rv) > deadzone)
{
Vector3 targetDir = new Vector3(rh, rv, 0.0f);
direction = Vector3.Slerp(transform.position-shipPos, targetDir, circSpeed);
}
Ray ray = new Ray(shipPos, direction); // cast ray in direction of point on circle shield is to go
if(canMove)
{
transform.position = ray.GetPoint(distance); //move shield to the ray as far as the distance
}
if(separation != distance) //If the shield get torn away from the ship
{
transform.position = ray.GetPoint(distance); //move shield to the ray as far as the distance
}
float angleY = transform.position.y - shipPos.y;
float angleX = -(transform.position.x - shipPos.x);
float angle = Mathf.Atan2 (angleY, angleX) * Mathf.Rad2Deg-90; //Get angle
if(Mathf.Abs(rh) > deadzone || Mathf.Abs(rv) > deadzone)
{
transform.rotation = Quaternion.AngleAxis(angle,Vector3.forward*-1); // keep shield facing outwards in respect to player
}
}
void FixedUpdate ()
{
if(!canMove)
{
tRB.velocity = new Vector2(0.0f, 0.0f);
rb.velocity = new Vector2(0.0f, 0.0f);
}
}
Thanks a million for any help :)
You need to move the shield along with the ship. You can do this by adding the ship velocity to the shield.
Something like:
shipPos = target.position;
transform.position += shipVelocity;
separation = Mathf.Abs((transform.position - shipPos).magnitude);
Or make the shield a child object of the ship.
OK, so all I needed to do was to make the shield a child AND get rid of the conditional statement around the transform.rotation so it wouldn't inherit the parent rotation and ruin the shield. It's the little things!