Sorry for the noob question, I am still new to unity.
Currently, I'm creating a 2d game in unity in which I have a game object that should move on the x-axis following the x touch position in a smooth way to create a nice swipe mechanics (taking into account that the object is constantly being influenced by the gravity of the Rigidbody2d).
I already tried doing it with Vector3.MoveTowards(), Rigidbody2D.MovePosition(), and changing the velocity of the Rigidbody2D, but none of those created a smooth movement.
Vector3.MoveTowards():
transform.position = Vector3.MoveTowards(transform.position, new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, transform.position.y, transform.position.z), speed * Time.deltaTime);
Rigidbody2D.MovePosition():
rigidbody2D.MovePosition(new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
transform.position.y, transform.position.z));
Rigidbody2D.velocity
Vector3 mousePositionWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (mousePositionWorld.x < transform.position.x)
{
rigidbody2D.velocity = new Vector2(-speed - -(speed * takeOff),
rigidbody2D.velocity.y)
}
else if (mousePositionWorld.x > transform.position.y)
{
rigidbody2D.velocity = new Vector2(+speed - (speed * takeOff),
rigidbody2D.velocity.y);
}
Am I missing something or is there a better way to achieve this?
I don't know what you mean by smooth, but i think that you can use Lerp function. Here is an example:
https://www.youtube.com/watch?v=d6BPukJ5QkA
is a short video.
Related
Like in previous posts i'm trying to make a game where you land on planets and what not,
for the planet rotation i used a parent "ring" and added a rotating script to it:
void Update()
{
Vector3 rotationfloat = new Vector3(0, 0, 2);
transform.Rotate(rotationfloat * rotateSpeed * Time.deltaTime);
}
Just something like that, rotation is nice and all, but then i have an attractor script that is like a gravitational force,
repel = -1;
if (Vector2.Distance(transform.position, planet.transform.position) <= maxDist && Vector2.Distance(transform.position, planet.transform.position) >= minDist)
{
Vector3 desiredPosition = planet.transform.position;
smoothedPosition = (desiredPosition - transform.position) * -1;
rb.AddForce(smoothedPosition * repel);
smoothedPosition = Vector3.zero;
}
Code like that, but when I try landing my player on the planet it makes the player slide across the planet, I've made it so it has a physics material with high friction, but that doesn't work.
You then land on the bottom of the planet and it pulls you to the planet but bounces you off when you touch it, I've checked the physics material (it has no bounce on it).
Anybody might know what is wrong with it?
If you need any more explanation i will try to give you more
So I tried to use a script from tutorial that Makes a 3d object rotates smoothly to the direction the object is moving towards and when I tried to use it to my 2d sprite it started to rotate really weird 3D rotating, I am really new to unity so please expect any stupid mistakes and here is the script I used:
float horizontalInput = Input.GetAxisRaw("Horizontal");
float verticalInput = Input.GetAxisRaw("Vertical");
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput).normalized;
if (movementDirection != Vector3.zero)
{
Quaternion toRotation = Quaternion.FromToRotation(movementDirection, Vector3.forward);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation,
rotationSpeed * Time.deltaTime);
}
I tried to replace it with Vector3.right but still the same issue, I also tried to replace it with Vector3.up but this weird 3D rotation still exist.
I'm currently working on a school game project where i need to have the player climb walls and pick up stuff. I am currently stuck in figuring out how to make the player rotate perpendicular to where the model's faces are while he/she moves towards a corner of a wall as shown below.
Something like this:
I searched for some methods to achieve this but i haven't found anything concrete so far.
Edit: I tried Reasurria's method and it kinda works.
if (Physics.Raycast (transform.position, -transform.up, out hit) && hit.collider.GetComponent<WallModifier> ()) {
transform.rotation = Quaternion.LookRotation (hit.normal, Vector3.right);
//Physics.gravity = hit.normal * -10.0f;
}
My player does indeed rotate correctly pependicular to the slope/wall but then my camera code completly breaks when trying to actually climb the wall. This shows how it looks like in first person and this shows how it looks like in the scene view.
While very funny, it is not obviously desired to have such effect.
Here is the camera code:
void Update () {
if (Input.GetKeyDown (KeyCode.Escape) || toggle && Input.GetMouseButtonDown (0)) {
toggle = !toggle;
}
if (!toggle && Application.isFocused) {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
var md = new Vector2 (Input.GetAxisRaw ("Mouse X"), Input.GetAxisRaw ("Mouse Y"));
md = Vector2.Scale (md, new Vector2 (sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp (smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp (smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp (mouseLook.y, minClamp, maxClamp);
transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized);
character.transform.localRotation = Quaternion.AngleAxis (mouseLook.x, character.transform.up.normalized);
if (rotateModel && antModel)
antModel.transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized) * Quaternion.Euler (0, 90, 0);
} else {
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
Application.runInBackground = false;
}
}
This code was taken by this person.
Do you mean perpendicular? In other words, rotate along x axis with -90 degree.
transform.Rotate(new Vector3(-90, 0, 0));
If I understand correctly, you may want to use Raycast.normal. So you would raycast from your player position with a direction equal to your player's local Vector3.down (player.transform.up * -1.0f).
You can use Quaternion.LookAt(surfaceNormal) to align your players 'up' vector with the normal of the surface under the player. This may involve some 90 degree offset to make the two 'up' vectors match.
Depending on your goal you may also want to set Physics.gravity to surfaceNormal * -10.0f or implement some custom gravity solution if the new surface will function as ground.
You can add empty GameObject with attached collider, than you can use OnTriggerEnter to rotate your Player. Add flag and on every odd enter rotate in one side and on every even enter rotate to opposite side as shingo said
Example
I'm recreating a movement system from dragon quest heroes rocket slime on the DS. In that game, the player can hold down the A button and stretch their slime main character in a direction. Letting go of A while it's stretched would sling them off in that direction.
Here's a gif of what it looks like:
Notice how he bounces off the walls diagonally. My replication currently looks like this (ignore the buggy animations :P)
It looks good! However, if I were to hit a wall diagonally, I would just move backwards in the opposite direction rather than reflecting off it.
Here's the code for how I handle bouncing off walls.
IEnumerator wallBounce(Vector2 hitVelocity)
{
playerAnimator.enabled = true;
yield return new WaitForSeconds(.3f);
playerAnimator.CrossFade("Walking " + curDirection, 0); // place holder animation
pVelocity = Vector2.Scale(-pVelocity,new Vector2(0.25f,0.25f));
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
curState = state.blasting;
transform.position = Vector3.MoveTowards(transform.position, endPos, 5f * Time.deltaTime);
}
I know about the Vector3.Reflect method in Unity but I'm not really sure how to implement it into my current code.
I seem to have done it.
I get the reflection vector like this:
Vector3 reflectedVelocity = Vector3.Reflect(pVelocity*.5f, foundHit.normal);
And then pass it to wallBounce as the hitVelocity.
StartCoroutine(wallBounce(reflectedVelocity));
I then changed this line:
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
into
endPos = transform.position + hitVelocity;
So I need to solve the following puzzle:
There is a 3D cube with rotation (34,90,23) (or some other random values). I want to rotate around the local y-axis until transform.position.y == 0. In the editor I can just drag-rotate on the y axis until I see 0 as a value in the transform, but how do I do that with code? (You cannot just set y=0, because all the values change when you rotate around the local y-axis)
I am thinking about using transform.RotateAround(transform.position, transform.up, angle), but I don't know how to correctly calculate angle so that after RotateAround() the transform.rotation.y == 0.
And just to specify, I don't want to code the dragging itself, just the result. The rotation should be instant.
Can anyone write a working code for this?
I guess what you are looking for is an "animation" that will affect the transform.localEulerAngles.y value. To achieve this I'd recommend using a coroutine (you can find Unity tutorial here).
It would look like this:
private IEnumerator RotateAroundY(float rotationTime)
{
float timer = 0.0f;
Vector3 startLocalEulerAngles = transform.localEulerAngles;
Vector3 deltaLocalEulerAngles = new Vector3(0.0f, Mathf.DeltaAngle(startLocalEulerAngles.y, 0.0f), 0.0f);
while (timer < rotationTime)
{
timer += Time.deltaTime;
transform.localEulerAngles = startLocalEulerAngles + deltaLocalEulerAngles * (timer / rotationTime);
yield return new WaitForEndOfFrame();
}
transform.localEulerAngles = startLocalEulerAngles + deltaLocalEulerAngles;
}
And you can call it using StartCoroutine(RotateAroundY(4.0f));.
If you're getting into Unity I highly recommend you to familiarize with coroutines :)
EDIT :
Sorry about not noticing you didn't needed an animation: if you simply want to rotate around the local transform.up vector, you can change the transform.localEulerAngles.y value.
You can do it this way transform.localEulerAngles.y = new Vector3(transform.localEulerAngles.x, 0.0f, transform.localEulerAngles.z);
Hope this helps,