Move object to mouse X - c#

I have code for move object to mouse X, but this code does not count the distance(the object follows straight in the mouse) How could I get their kind of controls? Where the player moves positions between offsets instead of lerping to your finger position? Can you please help me?
private void HorizontalMovement()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
transform.position = Vector3.Lerp(transform.position, new Vector3(hit.point.x, transform.position.y, transform.position.z), speed * Time.deltaTime);
}
}

If I understand you correctly you want the movement stop at a certain distance before reaching the exact finger position.
// adjust that in the inspector
public float distanceOffset = 0.1f;
private void HorizontalMovement()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
// Get the direction from hit object to player
var direction = (new Vector3(transform.position.x - hit.point.x, 0, 0)).normalized;
// Add the offset in the direction to the hit position
var targetPosition = new Vector3(hit.point.x, transform.position.y, transform.position.z) + direction * distanceOffset;
transform.position = Vector3.Lerp(transform.position, targetPosition, speed * Time.deltaTime);
}
}

Related

Camera collision detection

I'm having trouble with my Camera script. The Camera rotates around the player by using a pivot that's assigned as a child of the camera. This works with 2 arrows (I'm developing this game for mobiles, so they're touch arrows) that allow the camera to rotate left and right.
The problem is when the Camera goes behind a wall or a huge object and can't see anything. I looked for a solution and I see that many developers used the RaycastHit or something similar.
Here's my code, the goal is to get the Camera to go closer to the pivot when near a wall in order to avoid blocking the Camera view. Can anyone help me?
public Transform target1;
public Transform pivot;
protected ButtonLeft buttonLeft;
protected ButtonRight buttonRight;
public Vector3 offset;
public bool useOffsetValues;
public float rotateSpeed;
private void Start()
{
buttonLeft = FindObjectOfType<ButtonLeft>();
buttonRight = FindObjectOfType<ButtonRight>();
if (!useOffsetValues)
{
offset = target1.position - transform.position;
}
pivot.transform.position = target1.transform.position;
//pivot.transform.parent = target.transform;
//USE IF U WANT TO DISAPPEAR THE CURSOR
//Cursor.lockState = CursorLockMode.Locked;
//pivot.transform.parent = target.transform;
pivot.transform.parent = null;
// usa questa dopo la costruzione del livello1
//pivot.transform.position = target.transform.position;
}
private void Update()
{
pivot.transform.position = target1.transform.position;
if (buttonLeft.Pressed)
{
pivot.Rotate(0, -90 * Time.deltaTime, 0);
Debug.Log("rotate left");
}
if (buttonRight.Pressed)
{
pivot.Rotate(0, 90 * Time.deltaTime, 0);
Debug.Log("rotate left");
}
Ray ray = new Ray(pivot.transform.position, pivot.transform.position - transform.position);
RaycastHit hit;
/*float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
pivot.Rotate(0, horizontal, 0);
pivot.Rotate(0, horizontal, 0);
Use this to make the camera rotate on Mouse Y axes*/
/*float vertical = Input.GetAxis("Mouse Y") * rotateSpeed;
target.Rotate(vertical, 0, 0); */
//move camera based on the current rotation of the target and the original offset
float desiredYAngle = pivot.eulerAngles.y;
//Use this float to set the x angle of player
float desiredXAngle = pivot.eulerAngles.x;
//Use this rotation only if you want to rotate on Y
//Quaternion rotation = Quaternion.Euler(0, desiredYAngle, 0);
//Use this if u want to rotate up&down on x axes
Quaternion rotation = Quaternion.Euler(desiredXAngle, desiredYAngle, 0);
transform.position = target1.position - (rotation * offset);
//transform.position = target.position - offset;
transform.LookAt(target1);
}
Good approach is when you do raycast from pivot to camera, and, if some obstacle found, put camera on a ray, a bit closer to pivot, than hit point. Like this: (pseudocode, not tested):
Vector3 origin = pivot.transform.position;
Vector3 direction = transform.position - pivot.transform.position;
float maxCameraDistance = 10;
Ray ray = new Ray(origin, direction);
RaycastHit hit;
if (Physics.Raycast(ray, maxCameraDistance))
{
Vector3 offsetFromObstacle = -direction.normalized * 0.1f;
transform.position = hit.point + offsetFromObstacle;
}

Vector3.MoveTowards() isn't working, cant fix it?

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;

Object Follow Mouse Dragging Unity 3D

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

How can i rotate the player according to mouse cursor position clicked?

void Update()
{
MovePlayer();
}
Then the first original MovePlayer i did rotate the player but in the specific angle i set for example:
private void MovePlayer()
{
if (Input.GetMouseButtonDown(0))
{
targetAngles = transform.eulerAngles + 85.0f * Vector3.up;
StartCoroutine(TurnObject(transform, transform.eulerAngles, targetAngles, smooth));
}
}
But i want it to rotate to the angle of the mouse cursor position clicked not to walk there or move there only to rotate and face to the mouse cursor position clicked. So i tried to change the MovePlayer method to this but this is wrong it does nothing:
private void MovePlayer()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
startPositon = hit.point;
targetAngles = transform.eulerAngles + 0 * Vector3.up;
StartCoroutine(TurnObject(transform, transform.eulerAngles, targetAngles, smooth));
}
}
}
And
IEnumerator TurnObject(Transform ship, Vector3 startAngle, Vector3 endAngle, float smooth)
{
float lerpSpeed = 0;
isSpinning = true;
while (lerpSpeed < 1)
{
ship.eulerAngles = Vector3.Lerp(startAngle, endAngle, lerpSpeed);
lerpSpeed += Time.deltaTime * smooth;
yield return null;
}
startPositon = ship.position;
isSpinning = false;
}
This is working but with some problems:
void Update()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100000))
{
transform.LookAt(hit.point);
}
}
The first problem is when i point the mouse cursor to the sky since it's too far the player is not rotating and then when i point back to something in the distance range the player jump to the position. Not sure how to solve it. Maybe to calculate the sky(sky box in my case) distance so it will rotate also when pointing the sky ?
The second problem is when i point the mouse cursor on my self the player body it's making some fast rotations on place. How can i avoid it ? Or solve it ?
I tried to change the line:
if (Physics.Raycast(ray, out hit, 100000))
To
if (Physics.Raycast(ray, out hit))
But it didn't solve it. Maybe the problem is that my sky is a skybox i dragged to the Scene window so it's not an object.
My skybox is material i dragged to the Scene window so maybe this is the problem i can't rotate the player when the mouse cursor is pointing the sky. Any solution?

Rotate object to face mouse direction

I have a method that will rotate my object to the point my mouse just clicked on. However, my object only rotates as long as my mouse button is held down.
My main rotation method is this:
void RotateShip ()
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
Debug.Log (Input.mousePosition.ToString ());
Plane playerPlane = new Plane (Vector3.up, transform.position);
float hitdist = 0.0f;
if (playerPlane.Raycast (ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint (hitdist);
Quaternion targetRotation = Quaternion.LookRotation (targetPoint - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, speed * Time.deltaTime);
}
}
I call this method inside the FixedUpdate method and I've wrapped it inside the following if statement:
void FixedUpdate ()
{
// Generate a plane that intersects the transform's position with an upwards normal.
// Generate a ray from the cursor position
if (Input.GetMouseButton (0))
{
RotateShip ();
}
}
However, the object will still only rotate as long as my mouse button is held down. I want my object to continue to rotate to the point my mouse just clicked until it reaches that point.
How can I amend my code properly?
It's only rotating while your mouse is down because that's the only time you tell it to rotate. In your FixedUpdate (which Imtiaj rightfully pointed out should be Update), you're only calling RotateShip() while Input.GetMouseButton(0) is true. That means that you only rotate your ship while the button is pressed.
What you should do is take that mouse event and use it to set a target, then continuously rotate toward that target. For instance,
void Update() {
if (Input.GetMouseButtonDown (0)) //we only want to begin this process on the initial click, as Imtiaj noted
{
ChangeRotationTarget();
}
Quaternion targetRotation = Quaternion.LookRotation (this.targetPoint - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, speed * Time.deltaTime);
}
void ChangeRotationTarget()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Plane playerPlane = new Plane (Vector3.up, transform.position);
float hitdist = 0.0f;
if (playerPlane.Raycast (ray, out hitdist))
{
this.targetPoint = ray.GetPoint (hitdist);
}
}
So now instead of only doing the rotation while MouseButton(0) is down, we do the rotation continuously in the update and instead only set the target point when we click the mouse.

Categories

Resources