Hi I am creating a hyper casual game with unity, but I have encountered a problem with the swerve control (I have also seen many git hubs but even these do not work perfectly)
I've put this in my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private float lastframeposx;
private float movefactorx;
public float MoveFactorX => movefactorx;
public Camera m_MainCam;
private float speed = 2.0f;
[SerializeField]
GameObject character;
[SerializeField] private float swerveSpeed = 0.5f;
[SerializeField] private float maxSwerveAmount = 1f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += Vector3.forward * speed * Time.deltaTime;
Cammina();
/*Vector3 destra = Camera.main.ScreenToWorldPointt(Input.touches[i].position);
transform.position += Vector3.zero destra;*/
}
void Cammina()
{
if(Input.GetMouseButtonDown(0))
{
lastframeposx = Input.mousePosition.x;
float swerveAmount = Time.deltaTime * swerveSpeed * MoveFactorX;
swerveAmount = Mathf.Clamp(swerveAmount, -maxSwerveAmount, maxSwerveAmount);
transform.Translate(swerveAmount, 0, 0);
}
else if (Input.GetMouseButton(0))
{
movefactorx = Input.mousePosition.x - lastframeposx;
lastframeposx = Input.mousePosition.x;
float swerveAmount = Time.deltaTime * swerveSpeed * MoveFactorX;
swerveAmount = Mathf.Clamp(swerveAmount, -maxSwerveAmount, maxSwerveAmount);
transform.Translate(swerveAmount, 0, 0);
}
else if(Input.GetMouseButtonUp(0))
{
movefactorx = 0f;
float swerveAmount = Time.deltaTime * swerveSpeed * MoveFactorX;
swerveAmount = Mathf.Clamp(swerveAmount, -maxSwerveAmount, maxSwerveAmount);
transform.Translate(swerveAmount, 0, 0);
}
}
/*void vaidoveschiacciato()
{
if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
if(hit.collider != null)
{
transform.position += hit.collider.GetComponent<Transform.position> * speed * Time.deltaTime;
}
}
}
}*/
}
1 Problem: he don't go when the finger is
2 Problem: How do I eliminate the movement from right to left (Without making it go out of the path)
(Langauge: C#)
The problem: When you swerve, it swerves just in the direction, there is no limits on how far it goes.
How I would fix this: I would put the movement to change it through a function. This could clamp it, so the higher the distance to the center of the track, the less it swerves. Or, you can altogether check if the distance is a maximum and then stop swerving.
Note: you can use other functions to do this (they just have to flatten out the larger the input).
Smooth, good looking bell curve way
For example you could use a bell curve. Look one up if you've never seen one before. It is at it's highest possible output of one, at a zero input. When it gets hiher or lower, it outputs lower to zero.
the simplest equation is y = i-(x2). The lower i is (above 1), the wider the curve, or the larger the output is for a larger input. I made a graph here.
x can be the distance to the center of the track, so you should adjust i, so the maximum distance from the track is flat.
This output is what you should change swerveAmount to.
The flatter parts of the graoh is how much you will swerve when you are that distance from the center (x axis)
Alternatively
You could just check the distance, and if it passes a certain distance don't translate it.
Let me know in the omments if there are any problems! :)
Related
I have managed to go backwards and forwards with my kart in Unity. But when it comes to turning, it becomes a real challenge and I am unable to turn my vehicle smoothly with my a & d keys.
Please help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KartController : MonoBehaviour
{
private Rigidbody rb;
// adding a speed variable
public float speed = 3.0f;
// adding a brake variable
public float BrakeSpeed = 1.0f;
// adding a rotation position variable
// Start is called before
void Start()
{
// refering to the game object component/class
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
// adding movement for forward
if (Input.GetKey(KeyCode.W))
{
rb.velocity = new Vector3(speed * -2, 0, 0);
}
// adding movement for backward
if (Input.GetKeyDown(KeyCode.S))
{
rb.velocity = new Vector3(speed * 2, 0, 0);
}
// adding movement for rotation
float rotation_speed = 10f;
if (Input.GetButtonDown("Horizontal"))
{
transform.Rotate(0.0f, -Input.GetAxis("Horizontal") * rotation_speed, 0.0f);
}
Debug.Log(rotation_speed);
}
}
You've got a few different options and you are mixing a few things up.
Your Kart is a Rigidbody with a physics simulation. To move it forward or backwards you are setting the Karts velocity. If an object has a velocity in the physics simulation it will try to move because in the simulation the standard physics formula are solved. I.e. distance moved = velocity * time
For rotation the same concepts apply. There is the angular velocity of a rigidbody. If an object has angular velocity it tries to rotate accordingly.
With transform Rotate you are setting the rotation of the object directly. You are basically skipping the physics simulation. This is good if you want to for example reset your kart orientation and position at the start of the race but is less suited to control your Kart in the simulation.
You could directly set rb.angularVelocity similar how you set the Karts directional velocity.
Depending on the type of game and the realism you might want to look into controlling the acceleration instead of the velocity. Or even wheelcollider... (https://docs.unity3d.com/Manual/WheelColliderTutorial.html)
You can try the following code to select the car, I hope it can help you, thank you
private float y;
//vehicle control speed parameters
private float speedOne = 0f; //Vehicle real-time speed
private float speedMax = 120f; //The maximum speed of the vehicle
private float speedMin = -20f; //The minimum speed of the vehicle (the maximum speed of reversing)
private float speedUpA = 2f; //Vehicle acceleration acceleration (A key control)
private float speedDownS = 4f; //Vehicle deceleration acceleration (S key control)
private float speedTend = 0.5f; //Acceleration when no operation real-time speed tends to 0
private float speedBack = 1f; //Vehicle reversing acceleration
// Update is called once per frame
void Update()
{
//mouse hide
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
//Press the W key and the speed does not reach the maximum, then the speed increases
if (Input.GetKey(KeyCode.W) && speedOne < speedMax)
{
speedOne = speedOne + Time.deltaTime * speedUpA;
}
//Press the S key and the speed does not reach zero, then the speed is reduced
if (Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedDownS;
}
// No speed operation is performed and the speed is greater than the minimum speed, then the slow operation
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedTend;
}
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne < 0f)
{
speedOne = speedOne + Time.deltaTime * speedTend;
}
//When the S key is pressed and the speed does not reach the maximum reversing speed, and the vehicle is in a state where the vehicle can be reversed, the vehicle reverses
if (Input.GetKey(KeyCode.S) && speedOne > speedMin && speedOne<=0)
{
speedOne = speedOne - Time.deltaTime * speedBack;
}
/// press space, the car stops
if (Input.GetKey(KeyCode.Space) && speedOne != 0)
{
speedOne = Mathf.Lerp(speedOne, 0, 0.4f);
if (speedOne < 5) speedOne = 0;
}
transform.Translate(Vector3.forward * speedOne * Time.deltaTime);
//Use A and D to control the left and right rotation of the object
if(speedOne>1f||speedOne<-1f)
{
y = Input.GetAxis("Horizontal") * 60f * Time.deltaTime;
transform.Rotate(0, y, 0);
}
/* if (transform.eulerAngles.z != 0)
{
transform.eulerAngles = new Vector3(transform.eulerAngles.x, t
ransform.eulerAngles.y, 0);
}*/
}
I've been recently working on a project using Unity Engine that involves a sort of Top-Down, 3rd person view, and I have been having trouble with the character movement.
I want to implement a way for the player to move throughout the map using either WASD movement, Click-to-Move movement, or Drag-to-Move movement, allowing them to use either of these freely and at any time, yet I have not yet found a way of doing this, since the methods end up cancelling each other out, leading the Player Character to awkward movement and to getting stuck in place.
Is there any way of achieving this? If so, any tips/suggestions would be greatly appreciated. Please keep in mind I am a complete beginner when it comes to both Unity and C#, so I might not grasp some core concepts yet.
I have attached my PlayerMovement C# code below.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(test))]
public class PlayerMovement : MonoBehaviour
{
private test _input;
//click2move
private NavMeshAgent agent;
//x
[SerializeField]
private bool RotateTowardMouse;
[SerializeField]
private float MovementSpeed;
[SerializeField]
private float RotationSpeed;
[SerializeField]
private Camera Camera;
void Start()
{
//c2m
agent = GetComponent<NavMeshAgent>();
//x
}
private void Awake()
{
_input = GetComponent<test>();
}
// Update is called once per frame
void Update()
{
var targetVector = new Vector3(_input.InputVector.x, 0, _input.InputVector.y);
var movementVector = MoveTowardTarget(targetVector);
agent.autoBraking = true;
if (!RotateTowardMouse)
{
RotateTowardMovementVector(movementVector);
}
if (RotateTowardMouse)
{
RotateFromMouseVector();
}
//c2m
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (Input.GetMouseButtonDown(0))
{
agent.SetDestination(hit.point);
}
}
else
{
if (agent.remainingDistance < 1)
{
agent.ResetPath();
}
}
}
private void RotateFromMouseVector()
{
Ray ray = Camera.ScreenPointToRay(_input.MousePosition);
if (Physics.Raycast(ray, out RaycastHit hitInfo, maxDistance: 300f))
{
var target = hitInfo.point;
target.y = transform.position.y;
transform.LookAt(target);
}
}
private Vector3 MoveTowardTarget(Vector3 targetVector)
{
var speed = MovementSpeed * Time.deltaTime;
// transform.Translate(targetVector * (MovementSpeed * Time.deltaTime)); Demonstrate why this doesn't work
//transform.Translate(targetVector * (MovementSpeed * Time.deltaTime), Camera.gameObject.transform);
targetVector = Quaternion.Euler(0, Camera.gameObject.transform.rotation.eulerAngles.y, 0) * targetVector;
var targetPosition = transform.position + targetVector * speed;
transform.position = targetPosition;
return targetVector;
}
private void RotateTowardMovementVector(Vector3 movementDirection)
{
if (movementDirection.magnitude == 0) { return; }
var rotation = Quaternion.LookRotation(movementDirection);
transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation, RotationSpeed);
}
}
I would highly recommend that you use the Unity Input System. It can automate switching between input devices and decouple your code from any specific controls. It might be a bit overwhelming if you have limited experience with C#, but there is a vast library of tutorial videos and written guides you can rely on.
The PlayerInput component is what detects when different input devices are added or removed and switches to the first valid control scheme. When a user activates the inputs required to trigger something in your game, that is represented as an Action. A set of callbacks for that action are called depending on the states of the input: started, performed, and canceled. These are where you hook up your character controller to the input and run any extra logic necessary to turn an input into movement. The Input System also has a feature called interactions that will probably be useful, especially for drag-to-move controls.
Good luck! If you'd like me to explain something further or point you to a good tutorial, feel free to tag me in a comment.
First create a Capsule in the scene, drag the main camera to its object, hang the script under the Capsule object, WASD controls the movement direction, the space moves up along the Y axis, and the F moves down along the Y axis, thank you
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCam : MonoBehaviour
{
private Vector3 m_camRot;
private Transform m_camTransform;//Camera Transform
private Transform m_transform;//Camera parent object Transform
public float m_movSpeed=10;//Movement factor
public float m_rotateSpeed=1;//Rotation factor
private void Start()
{
m_camTransform = Camera.main.transform;
m_transform = GetComponent<Transform>();
}
private void Update()
{
Control();
}
void Control()
{
if (Input.GetMouseButton(0))
{
//Get the mouse movement distance
float rh = Input.GetAxis("Mouse X");
float rv = Input.GetAxis("Mouse Y");
// rotate the camera
m_camRot.x -= rv * m_rotateSpeed;
m_camRot.y += rh*m_rotateSpeed;
}
m_camTransform.eulerAngles = m_camRot;
// Make the main character face in the same direction as the camera
Vector3 camrot = m_camTransform.eulerAngles;
camrot.x = 0; camrot.z = 0;
m_transform.eulerAngles = camrot;
// Define 3 values to control movement
float xm = 0, ym = 0, zm = 0;
//Press W on the keyboard to move up
if (Input.GetKey(KeyCode.W))
{
zm += m_movSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.S))//Press keyboard S to move down
{
zm -= m_movSpeed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A))//Press keyboard A to move left
{
xm -= m_movSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.D))//Press keyboard D to move right
{
xm += m_movSpeed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.Space) && m_transform.position.y <= 3)
{
ym+=m_movSpeed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.F) && m_transform.position.y >= 1)
{
ym -= m_movSpeed * Time.deltaTime;
}
m_transform.Translate(new Vector3(xm,ym,zm),Space.Self);
}
}
I've been trying to realistically reflect a 3d sphere on the walls of a box for a while now in Unity. For some reason, the reflection is generally correct, but when the ball hits a wall in certain directions, the reflection is incorrect.
To illustrate what happens to the ball upon hitting a wall: T = top wall, R = right wall, L = left wall, and B = bottom wall. Let r = the ball comes/goes to the right, l = for the left, and s = the ball stops/slows down significantly. The instructions below take this format: Xyz, where X = the wall the ball is about to hit, y = the ball's initial direction, z = the reflection. The game has a top-down perspective, and the instructions are based on the wall's perspective. I'm also new to C#, so the code is potentially eye burning.
Instructions: Tll, Trl; Bll, Brl; Rls or after hitting another wall Rlr, Rrl; Lls or after hitting another wall Llr, Lrl
Generally, when the ball stops, it jumps in the air. I wonder if this is because the angle reflects along the wrong axis, but why would this only sometimes happen? Also, when only one key is held, the ball bounces back and forth until it leaves the arena. I know about discrete and continuous hit detection, and the setting is on discrete, but the walls generally contain the ball well enough, with this case being the exception.
What I tried:
Figuring out how to use Vector3.Reflect. I do not understand what variables this function should contain and how to apply this to my code. I did look at the Unity Documentation page for help, but it did not answer my question.
Changing the negative signs, as the angle has to be a reflection on the y-axis, and this does change how the reflections work, but does not solve the problem. The current way the negatives are ordered are the most ideal I found.
Giving the ball a physics material for bounciness.
Adding a small number to the denominator in the arctan equation to help prevent a division by zero. This did not help at all.
Creating different equations (basically changing the negatives) for varying combinations of positive and negative accelerations. Since there is a certain positive or negative acceleration associated with each button press (see Movement script), and there seems to be an issue with said signs, I wondered if associating each acceleration with its own set of equations could solve the problem. It did not work.
Checked if the walls were at different angles.
Deleting the variables xA and yA, or placing them in different spots.
Experimented with finding the speed of the object, but had no idea how to implement it.
The code for the Movement script for the player named Controller:
public class Movement : MonoBehaviour
{
public static float xAcceleration = 0.0f;
public static float yAcceleration = 0.0f;
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.W)) //If the key W is pressed:
{
Vector3 position = this.transform.position; //Variable position is set to transform the players placement in the game.
if (yAcceleration >= -5 && yAcceleration <= 5) //If the y vector of the acceleration is >= -5 and <= 5:
{
yAcceleration = yAcceleration + 0.01f; //The y vector of the acceleration increases by 0.01 as long as the key W is pressed.
}
position.z = position.z + (0.1f * yAcceleration); //The position of the object on the z-axis (pretend it is the y-axis in the game world) is transformed by its original position plus its speed times its yAcceleration.
this.transform.position = position; //The gameObject is now transformed to a position equal to the variable position by the z-axis.
}
else //If the key W is let go of:
{
Vector3 position = this.transform.position;
position.z = position.z + (0.1f * yAcceleration);
this.transform.position = position; //The position of the gameObject continues to update, but its acceleration does not change. Basically, it continues to move forward.
}
//The rest of the code is very similar to the above, but I included it just in case there was something wrong.
if (Input.GetKey(KeyCode.S))
{
Vector3 position = this.transform.position;
if (yAcceleration >= -5 && yAcceleration <= 5)
{
yAcceleration = (yAcceleration) - 0.01f;
}
position.z = position.z + (0.1f * yAcceleration);
this.transform.position = position;
}
else
{
Vector3 position = this.transform.position;
position.z = position.z + (0.1f * yAcceleration);
this.transform.position = position;
}
if (Input.GetKey(KeyCode.A))
{
Vector3 position = this.transform.position;
if (xAcceleration >= -5 && xAcceleration <= 5)
{
xAcceleration = (xAcceleration) - 0.01f;
}
position.x = position.x + (0.1f * xAcceleration);
this.transform.position = position;
}
else
{
Vector3 position = this.transform.position;
position.x = position.x + (0.1f * xAcceleration);
this.transform.position = position;
}
if (Input.GetKey(KeyCode.D))
{
Vector3 position = this.transform.position;
if (xAcceleration >= -5 && xAcceleration <= 5)
{
xAcceleration = (xAcceleration) + 0.01f;
}
position.x = position.x + (0.1f * xAcceleration);
this.transform.position = position;
}
else
{
Vector3 position = this.transform.position;
position.x = position.x + (0.1f * xAcceleration);
this.transform.position = position;
}
}
}
This is the code for the collider and reflection:
public class Collider : MonoBehaviour
{
public float xA;
public float yA;
void OnCollisionEnter(Collision collision) //If a gameObject enters the collision of another object, this immediately happens once.
{
if (gameObject.tag == "Boundary") //If the gameObject has a tag named Boundary:
{
yA = -Movement.yAcceleration; //yA stores the value of yAcceleration after being called from script Movement as a negative. Its a reflection.
Movement.xAcceleration = (Movement.xAcceleration * -Mathf.Atan(yA / Movement.xAcceleration)); //xAcceleration is changed based on this equation: A * artan(A_y / A_x). The 0.000001 was here, adding to A_x to help prevent a 0 as the denominator.
xA = Movement.xAcceleration; //This is declared now...
Movement.yAcceleration = (Movement.yAcceleration * Mathf.Atan(Movement.yAcceleration / xA)); //This uses xA because Movement.xAcceleration is changed, and the yAcceleration calculation is based on the xAcceleration prior the collision.
}
}
void OnCollisionStay(Collision collision)
{
if (gameObject.tag == "Boundary")
{
yA = Movement.yAcceleration; //The same thing happens as before.
Movement.xAcceleration = (Movement.xAcceleration * -Mathf.Atan(yA / Movement.xAcceleration));
xA = Movement.xAcceleration;
Movement.yAcceleration = (Movement.yAcceleration * Mathf.Atan(Movement.yAcceleration / xA));
Movement.xAcceleration = -Movement.xAcceleration / 2; //On collision, the ball is reflected across the x-axis at half its speed.
Movement.yAcceleration = Movement.yAcceleration / 2; //yAcceleration is half its original value.
}
}
}
The picture below is the game setup. I apologize that it is a link; I do not have enough Reputation to merit a loaded image on this page. Also, if anything is unclear, please message me.
https://i.stack.imgur.com/VREV4.png
I would really appreciate the help. Thanks!
One very important note here: As soon as there is any Rigidbody involved you do not want to set any values through the .transform - This breaks the physics and collision detection!
Your Movement should rather alter the behavior of the Rigidbody e.g. by simply changing its Rigibody.velocity
I would then also place the collision check directly into the balls's component and check whether you hit a wall ("Boundary")
Then another note: Your code is currently frame-rate dependent. It means that if your target device runs with only 30 frames per second you will add 0.3 per second to the acceleration. If you run however on a more powerful device that manages to run with 200 frames per second then you add 2 per second.
You should rather define the de/increase per second and multiply it by Time.deltaTime
All together maybe something like this
public class Movement : MonoBehaviour
{
// Adjust these settings via the Inspector
[SerializeField] private float _maxMoveSpeed = 5f;
[SerializeField] private float _speedIncreasePerSecond = 1f;
// Already reference this via the Inspector
[SerializeField] private Rigidbody _rigidbody;
private void Awake()
{
if(!_rigidbody) _rigidbody = GetComponent<Rigidbody>();
}
// Get User Input in Update
private void Update()
{
var velocity = _rigidbody.velocity;
velocity.y = 0;
if (Input.GetKey(KeyCode.W) && velocity.z < _maxMoveSpeed)
{
velocity.z += _speedIncreasePerSecond * Time.deltaTime;
}
if (Input.GetKey(KeyCode.S) && velocity.z > -_maxMoveSpeed)
{
velocity.z -= _speedIncreasePerSecond * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A) && velocity.x > -_maxMoveSpeed)
{
velocity.x -= _speedIncreasePerSecond * Time.deltaTime;
}
if (Input.GetKey(KeyCode.D) && velocity.x < _maxMoveSpeed)
{
velocity.x += _speedIncreasePerSecond * Time.deltaTime;
}
// clamp to the max speed in case you move diagonal
if(velocity.magnitude > _maxMoveSpeed)
{
velocity = velocity.normalized * _maxMoveSpeed;
}
_rigidbody.velocity = velocity;
}
}
And then finally simply add a PhysicsMaterial with desired settings to the walls and ball.
I used Friction = 0f and Bounciness = 0.7f for ball and walls. For slow movements you also might want/have to adjust the Bounce Threshold in the Project's Physics Settings otherwise there will be no bouncing if the velocity is smaller then 2 by default.
This depends a bit on your definition of "realistic". I disabled gravity so the ball also has no rotation and angular friction:
I'm writing movement for my space game and spaceship object (player) with mouse cursor.
Currently have following code:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class Move : MonoBehaviour {
public float speed = 1.5f;
public float rotationSpeed = 90f;
public float rotPrecision = 0.1f;
public float movePrecision = 0.1f;
private Vector3 pos;
private Quaternion qTo;
void Start () {
pos = transform.position;
qTo = transform.rotation;
}
void Update () {
if (!EventSystem.current.IsPointerOverGameObject())
{
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
{
pos = Input.mousePosition;
pos.z = transform.position.z - Camera.main.transform.position.z;
pos = Camera.main.ScreenToWorldPoint(pos);
}
var dir = pos - transform.position;
qTo = Quaternion.LookRotation(Vector3.forward, pos - transform.position);
if (Quaternion.Angle(transform.rotation, qTo) >= rotPrecision) //just set your own precision
transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, Time.deltaTime * rotationSpeed);
if (Vector3.Distance(transform.position, pos) > movePrecision) // 0.1f
transform.Translate(Vector3.up * speed * Time.deltaTime);
}
}
}
But there i have the problem with the movement precision and rotation when the point is too close to player (have infinite loop).
The idea of this movement system described with the following image:
(Player actor is green, path is gray, and destination point is red).
I hope that somebody could help me w/ that.
Thank you!
If I understand your question correctly, the problem is that the player's movement never stops as the code can't reach a finishing point.
To solve this you can add an acceptable precision margin.
So calculate if the difference between the rotation you wish or the movement you wish, and the players actual rotation/position, is less than a given variable, for example less than 0.05%.
That way you could allow the program to know that if it's just within 0.05% precision, then it's okay for it to stop moving.
Otherwise, if the program never reaches a complete and perfect rotation and position, it will continue to adjust endlessly due to slight mathematical imprecision in the calculations and movement pattern.
I want to change the position of the object to the position of the mouse, moving slowly from first to second position.
My object is moving slowly to the random direction which appears to be connected with lower-left corner. When I go higher than the corner my object is moving upwards, same with left and right.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rocket : MonoBehaviour
{
public float speed = 10f;
private Vector3 shippos;
void Start()
{
shippos = transform.position;
}
void FixedUpdate()
{
if (Input.mousePosition.x > shippos.x)
shippos.x=shippos.x+speed*Time.deltaTime;
if (Input.mousePosition.x < shippos.x)
shippos.x=shippos.x-speed*Time.deltaTime;
if (Input.mousePosition.y > shippos.y)
shippos.y=shippos.y+speed*Time.deltaTime;
if (Input.mousePosition.y < shippos.y)
shippos.y=shippos.y-speed*Time.deltaTime;
transform.position = shippos;
}
}
The mouse position is returned in screenspace coordinates. What you need to do is convert this to world coordinates so that they are compared in the same coordinate space as the transform (shippos).
void FixedUpdate()
{
if (Camera.main.ScreenToWorldPoint(Input.mousePosition).x > shippos.x)
shippos.x = shippos.x + speed * Time.deltaTime;
if (Camera.main.ScreenToWorldPoint(Input.mousePosition).x < shippos.x)
shippos.x = shippos.x - speed * Time.deltaTime;
if (Camera.main.ScreenToWorldPoint(Input.mousePosition).y > shippos.y)
shippos.y = shippos.y + speed * Time.deltaTime;
if (Camera.main.ScreenToWorldPoint(Input.mousePosition).y < shippos.y)
shippos.y = shippos.y - speed * Time.deltaTime;
transform.position = shippos;
}
If I did not misunderstand, you want to change your player's position straight to the point of mouse's position and looking towards mouse.
void Update() {
Transform target = mousePosition; //get your mouse position per frame
Vector3 relativePos = target.position - transform.position; //create a vector3 between them
Quaternion rotation = Quaternion.LookRotation(relativePos); //then give a rotation your player towards this vector.
transform.rotation = rotation; //and apply it.
}
Taken from here: http://answers.unity3d.com/questions/633873/how-to-make-an-object-move-towards-the-mouse-point.html
public float moveSpeed = 2.0; // Units per second
void Update () {
var targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos.z = transform.position.z;
transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime);
}
May not be accurate C#, but you get the idea.
i guess you are doing wrong , because wile you have Mathf.Lerp you Dont need to go as that clumsy way
Here is a video tutorial from youtube for mathf.lerp
and here is the base code:
someValue = Mathf.Lerp(initialValue , finalValue , Time.deltaTime * smoothness);
just take a look to the youtube link you will definitely get the idea!
AS A SIDE NOTE
you dont need to do alot of stuff to decrease your game performance! be careful about this kinda coding!