cursors.transform.position = Vector3.MoveTowards(cursors.transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), 10f * Time.deltaTime);
I want to make a cursor that moves smoothly and not instant towards the mouseposition, and for a few seconds, it works, then vanishes within a few seconds, anyone know why this happens ?
I would like to ask you, is your cursor game object a 2D object that you want to move along the screen ( x, y coords only ) or you want to move it in world space ( z axis is included ) ?
Your cursor might be moving through the camera's clipping plane
You could try:
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
cursors.transform.position = Vector3.MoveTowards(cursors.transform.position, mousePos, 10f * Time.deltaTime);
Related
I am trying to rotate a player according to mouse movement. The player's position is set at the mouse position and as the mouse moves the player should rotate on the z-axis to face that direction. Something similar to this.
player.transform.Rotate(new Vector3(0, 0, Input.GetAxis("Mouse Y") + Input.GetAxis("Mouse X")) * Time.fixedDeltaTime * 360);
I tried this but it doesn't stop rotating the character once it reaches the axis and it only rotates in one direction.
UPDATE: I have come up with this. The problem is the opposite axis has to equal to zero for the direction to be correct. Otherwise they don't add up to equal the correct direction.
//Max value to add mouse value to, controls speed of rotation
float maxRotation = 2.5f;
//Adds the value of mouse movement
ver += Input.GetAxisRaw("Mouse Y");
hor += Input.GetAxisRaw("Mouse X");
//Clamps the value to stop rotating forever
ver = Mathf.Clamp(ver,-maxRotation,maxRotation);
hor = Mathf.Clamp(hor,-maxRotation,maxRotation);
//Rotates player
player.transform.rotation = Quaternion.Euler(0,0,((ver + hor) * (90/maxRotation)));
//Player stays at mouse pos
mousePos = new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,Camera.main.ScreenToWorldPoint(Input.mousePosition).y,0);
player.transform.position = mousePos;
Cheers.
First off: I am very new to Unity, as in VERY new.
I want to do the following: I want to rotate a cube around a stationary point (in my case a camera) with a radius that is adjustable in the inspector. The cube should always have its Z-axis oriented towards the camera's position. While the cube is orbiting around the camera, it should additionally follow a sine function to move up and down with a magnitude of 2.
I have some working code, the only problem is an increase in distance over time. The longer the runtime, the higher the distance between the cube and the camera.
Here is what I currently have:
void Awake()
{
cameraPosition = GameObject.FindGameObjectWithTag("MainCamera").transform;
transform.position = new Vector3(x: transform.position.x,
y: transform.position.y,
z: cameraPosition.position.z + radius);
movement = transform.position;
}
I instantiate some variables in the Awake()-method and set the cube's position to where it should be (do you instantiate in Awake()?). I'll use the Vector3 movement later in my code for the "swinging" of the cube.
void Update()
{
transform.LookAt(cameraPosition);
transform.RotateAround(cameraPosition.position, cameraPosition.transform.up, 30 * Time.deltaTime * rotationSpeed);
MoveAndRotate();
}
Here I set the orientation of the cube's z-axis and rotate it around the camera. 30 is just a constant i am using for tests.
void MoveAndRotate()
{
movement += transform.right * Time.deltaTime * movementSpeed;
transform.position = movement + Vector3.up * Mathf.Sin(Time.time * frequency) * magnitude;
}
To be quite frank, I do not understand this bit of code completely. I do however understand that this includes a rotation as it moves the cube along it's x-axis as well as along the world's y-axis. I have yet to get into Vector and matrices, so if you could share your knowledge on that topic as well I'd be grateful for that.
It seems like I have found the solution for my problem, and it is an easy one at that.
First of all we need the initial position of our cube because we need to have access to its original y-coordinate to account for offsets.
So in Awake(), instead of
movement = transform.position;
We simply change it to
initialPosition = transform.position;
To have more readable code.
Next, we change our MoveAndRotate()-method to only be a single line long.
void MoveAndRotate()
{
transform.position = new Vector3(transform.position.x,
Mathf.Sin(Time.time * frequency) * magnitude + initialPosition.y,
transform.position.z);
}
What exactly does that line then? It sets the position of our cube to a new Vector3. This Vector consists of
its current x-value
our newly calculated y-value (our height, if you want to say so) + the offset from our original position
its current z value
With this, the cube will only bop up and down with distancing itself from the camera.
I have also found the reason for the increase in distance: My method of movement does not describe a sphere (which would keep the distance the same no matter how you rotate the cube) but rather a plane. Of course, moving the cube along a plane will automatically increase the distance for some points of the movement.
For instantiating variables in Awake it should be fine, but you could also do it in the Start(){} Method that Unity provides if you wanted to.
For the main problem itself I'm guessing that calling this function every frame is the Problem, because you add on to the position.
movement += transform.right * Time.deltaTime * movementSpeed;
Would be nice if you could try to replace it with this code and see if it helped.
movement = transform.right * Time.deltaTime * movementSpeed;
I am trying to create a 3d game like ketchapp ball race, in which the cube slides along a road, and the left right movement is controlled using touch
The problem I am facing is that the touch senstivity seems to react different on different devices, due to which I am not able to calculate the left-right displacement for all devices.
This is how I am calculating the left-right displacement of the cube:
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition ;
transform.Translate(touchDeltaPosition.x * .1f * Time.deltaTime, 0, 0);
However this is not working properly all device . Any help will be highly appreciated
See this answer: https://stackoverflow.com/a/25740565/10063126
Basically, ScreenToWorldPoint was used.
World position is computed; not screen touch position.
But you have to manually solve for delta position.
Example:
Vector3 currPos = Input.mousePosition;
Vector3 startPos = Camera.main.ScreenToWorldPoint(currPos);
Vector3 endPos = Camera.main.ScreenToWorldPoint(prevPos);
Vector3 deltaPos = endPos - startPos;
transform.Translate(deltaPos.x * sensitivity * Time.deltaTime, 0, 0);
prevPos = currPos;
How about using 2 buttons on your screen one for left control and one for right control and then when the left button is pressed you can give a value to go left and same for right button. This way your ball's movement will be independent from the touched position's X value.
I am trying to archive without success a z-axis rotation movement around a moving object keeping always "looking at front". So it should looks like this:
The closest I got was with:
transform.RotateAround(targetPosition, Vector3.forward, moveSpeed);
But it does not keeps looking "at front".
Could someone give me a hand with this?
Thank you in advance.
Best regards.
If your object ("Lightning Bolt") has no world rotation, i.e. aligned with the world axis as your example image seems to suggest, then the easiest is to simply set the world rotation to the Quaternion Identity:
transform.rotation = Quaternion.identity;
Note that the image wont rotate if its parent object rotates. It will essentially "Billboard" your lightning object. If you want to your lightning bolt to be aligned with a parent object, then try something like:
transform.rotation = transform.parent.rotation;
Fitst store the current rotation, then rotate around point, lastly apply the previous rotation.
var rot = transform.rotation;
transform.RotateAround(targetPosition, Vector3.forward, moveSpeed);
transform.rotation = rot;
A simple solution would just manipulate actual coordinates and ignore rotation ^^ If an object moves and you want it to keep rotating around it, just make it a child object.
This is a 3d solution where we rotate around Y:
void Start() { angle = 0.0f }
void Update() {
angle += speed * Time.deltaTime; //Your starting angle that will be modified every frame
CheckAngle(ref angle);
float x = Mathf.Cos(angle * Mathf.Deg2Rad) * Radius;
float z = Mathf.Sin(angle * Mathf.Deg2Rad) * Radius;
}
static void CheckAngle(ref float Angle) //It should probably return a value by it's name here tho not ref, not sure which is the correct way of doing this
{
if (Angle > 360) //You don't want your angle to go past the boundaries of an INT
Angle = 0;
}
I am developing a 2.5D game. In that game I want my character (which has Rigidbody component attached to) to just move on x and y axises. So I use this code snippet:
private void LockZAxis () {
Vector3 currentPosition = _rigidbody.position;
currentPosition.z = 0;
_rigidbody.position = currentPosition;
}
I call this LockZAxis method in the end of both Update, FixedUpdate and LateUpdate. But it doesn't work. When my character run forward for a while, its z position is still changed.
For additional information, in my code, there are two times I manipulate the position of RegidBody. The first is when my character jump, that time I use this:
jumpVelocityVector = Vector3.up * jumpForceUp + transform.forward * jumpForceForward;
_rigidbody.velocity = jumpVelocityVector;
And each frame when I want my character to move a bit faster, so in the update method, I have this:
void Update () {
Vector3 newPosition = transform.position + transform.forward * speed * Time.deltaTime;
newPosition.z = 0;
_rigidbody.MovePosition (newPosition);
LockZAxis ();
}
A rigidbody is used to simulate physics, by setting the rigidbody's position every frame you're essentially teleporting the character every frame. You can restrict movement in z-axis, this will prevent it to move in z-axis when physics is applied, which is what a rigidbody typically is used for.
Here is how to restrict rigidbody positional change:
If you run your LockZAxis() after you've changed the position it should teleport the object to the z-position of 0 every frame. Please make sure that the z-axis is the correct axis. You can debug this by pausing a running game and manipulating the Transform values to see how each axis moves your Object.
Here is how you can do it with C# Script:
Freeze All Positions
rigidbody.constraints = RigidbodyConstraints.FreezePosition;
Freeze Specific Positions:
rigidbody.constraints = RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionZ;
Unity Documentation
Is physics gravity set to only affect the Y position ?
Physics.gravity = new Vector3(0, -1.0F, 0);
And set these also
rigidbody.angularVelocity = Vector3.zero;
rigidbody.velocity.z=0;
make sure your rigidbody is set to kinematic since you are using Rigidbody.moveposition() and using moveposition() will directly effect velocity internally on a kinematic rigidbody
Try using moveposition() for you jump instead of velocity