Unity2d Jumping like teleport - unity3d

I am working on Unity2d Sprite but something is wrong: in my code when I press the jump button my character jump like teleport, it go very fast in the Up direction. The gravity is 9 and my Rigidbody2D mass is 1. My code is this:
if(isGrounded == true && moveH == 0) {
if (Input.GetKeyDown(KeyCode.J)) {
anim.SetBool("str_jump", true);
//rgBody.velocity = new Vector2(0,jumpHeight);
//rgBody.AddForce(Vector2.up * jumpHeight);
transform.position = new Vector2(transform.position.x,
transform.position.y * jumpHeight);
isGrounded = false;
}
}

If your jump is too high, you have to use a variable to modify the height of the jump. In your case, you are using the jumpHeight as the variable to modify the height of your jump.
Decreasing jumpHeight should solve your problem. Note that if jumpHeight is declared as public (public float jumpHeight;), you have to change the variable from the Editor or a function because it will not use the number assigned to it when it was declared. It will use whatever that is assigned to it from the Editor.
For example, when you have public float jumpHeight = 4; but the value is set to 0 in the editor, 0 will be used as the value not 4.
Also you have to use rgBody.AddForce(Vector2.up * jumpHeight);. Uncomment it and then remove the transform.position = new Vector2(transform.position.x,transform.position.y *jumpHeight); line of code.
If this does not solve your problem, then you have to update your question with your complete code.

For a nice jump you could also use rgBody.AddForce((Vector2.up * jumpHeight), ForceMode2D.Impulse); It simulates an impact on your object and you get a nice jump simulation.
Do not forget to declare the public float jumpHeigt = 4f; like "Programmer" said it before.
I hope it will help you.

Simply reducing the jumpHeight value will fix the initial issue of the jump being too high.
However if you want a more realistic 'jump' you may want to utilise Rigidbody2D.velocity simply having rgBody.velocity = new Vector2(rgBody.velocity.x, jumpHeight); should create a nice smooth jump.
If you use the Rigidbody2D.velocity instead of simply changing the transform means that you can alter values such as Gravity Scale and this will make a noticeable difference on the movement of your player. You can play around with different jumpHeight and Gravity Scale values to find what works best for your game.

Use transform.position '+=' instead of just '='. This way you're adding to it's position and not setting it to a certain number(that's why it's teleporting like that). Tho this method only suits horizontal movement in my opinion(if it's a sideview game). For jumping, using AddForce would be way better.

Related

Calculate the force of interaction of objects in UE

I want to calculate the force of the collision. For example, the car is on the bridge, and I want to find
pressure force. In the second case, I have a falling car, and I want to find the force of the impact. Are there any functions for this?
I want to use c ++.
All you do is multiply the Mass and the Speed together
void AMyActor::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
float HitForce = OtherActor->GetVelocity.Size() * OtherComp->GetMass();
UE_LOG(LogTemp, Warning, TEXT(HitForce));
}
HitForce is the variable you're looking for.

Using Time.timeScale to pause causes my player to 'dash' when unpausing, how do I stop this?

I'm moving my player with Input.GetAxis() and AddForce().
When I unpause the game with Time.timeScale = 1f, the player dashes forward at a higher speed (past my speed limit) even with the movement keys unpressed.
How can I stop this from happening?
for restricting speed from exceeding max limit you can use 'normalized'
void FixedUpdate()
{
if(rigidbody.velocity.magnitude > maxSpeed){
rigidbody.velocity = rigidbody.velocity.normalized * maxSpeed;
}
}
also you can use Vector3.ClampMagnitude.
see this https://docs.unity3d.com/ScriptReference/Vector3.ClampMagnitude.html
to be more specific you can share the part of the script.
Sounds like the force is still being applied and added constantly while the game is paused.
You could record the amount of force being applied to the player right before you set Time.timeScale = 0 and when you set Time.timeScale = 1f you could set the force to the recorded force before you paused.

Unity - Looking through the scope of a gun

Right now I have 2 Cameras: the main camera displays the gun at its normal state and a second camera is attached to the gun (the gun is a child of the main camera) and when toggled it looks through the scope of the gun and increases the field of view.
Heres a visual for a better understanding:
Now if I were to just toggle the second camera on and turn the main camera off, this would work splendid, but it's not very ideal. You should only have 1 camera per scene.
So I want to Lerp the position of the camera to look through the scope and manually decrease the fieldofview. So I have written the following script:
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
CameraTransform.position = Vector3.Lerp (
CameraTransform.position,
CameraTransform.position + ZoomedTransform.position,
5f * Time.deltaTime
);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
The problem with this is that it doesn't work: when I hit the zoom button, the camera speeds through the scene at the speed of light and it's hard to tell exactly what is going on.
Could anyone give me some insight as to what I'm doing wrong? I think it is something to do with the parent-child relationship, but even when I've tried using static values, I cannot seem to replicate the correct solution.
Hierarchy:
(This answer operates under the assumption that ZoomedTransform is a relative transformation, and not the absolute position of the camera as suspected by 31eee384's answer.)
I think there are a couple issues with your code. I'll tackle them individually so they're easier to understand, but they both relate to the following line:
CameraTransform.position = Vector3.Lerp (CameraTransform.position, CameraTransform.position + ZoomedTransform.position, 5f * Time.deltaTime);
First, let's look at how you're using Vector3.Lerp(). For the third argument of Vector3.Lerp(), you're supplying 5f * Time.deltaTime. What exactly does this value work out to? Well, the standard framerate is about 60 FPS, so Time.deltaTime = ~1/60. Hence, 5f * Time.deltaTime = 5/60 = ~0.0833.
What is Vector3.Lerp() expecting for the third argument, though? According to the documentation, that third argument should be between 0 and 1, and determines whether the returned Vector3 should be closer to the first or second given Vector3. So yes, 5f * Time.deltaTime falls within this range, but no interpolation will occur - because it will always be around ~0.0833, rather than progressing from 0 to 1 (or 1 to 0). Each frame, you're basically always getting back cameraPos + zoomTransform * 0.0833.
The other notable problem is how you're updating the value of CameraTransform.position every frame, but then using that new (increased) value as an argument for Vector3.Lerp() the next frame. (This is a bit like doing int i = i + 1; in a loop.) This is the reason why your camera is flying across the map so fast. Here is what is happening each frame, using the hypothetical result of your Vector3.Lerp() that I calculated earlier (pseudocode):
// Frame 1
cameraPosFrame_1 = cameraPosFrame_0 + zoomTransform * 0.0833;
// Frame 2
cameraPosFrame_2 = cameraPosFrame_1 + zoomTransform * 0.0833;
// Frame 3
cameraPosFrame_3 = cameraPosFrame_2 + zoomTransform * 0.0833;
// etc...
Every frame, zoomTransform * 0.0833 gets added to the camera's position. Which ends up being a really, really fast, and non-stop increase in value - so your camera flies across the map.
One way to address these problems is to have variables that stores your camera's initial local position, zoom progress, and speed of zoom. This way, we never lose the original position of the camera, and we can both keep track of how far the zoom has progressed and when to stop it.
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private Vector3 startLocalPos;
private float zoomProgress = 0;
private float zoomLength = 2; // Number of seconds zoom will take
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
startLocalPos = CameraTransform.localPosition;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
zoomProgress += Time.deltaTime;
CameraTransform.localPosition = Vector3.Lerp (startLocalPos, startLocalPos + ZoomedTransform.position, zoomProgress / zoomLength);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
Hope this helps! Let me know if you have any questions. This answer does ramble a little, so I hope you don't have any trouble getting the important points from it.
Your lerp target is relative to the camera's current position, so it's constantly moving. This is the target you have:
CameraTransform.position + ZoomedTransform.position
This means that as your camera moves to get closer to this position, the camera's new position causes the destination to change. So your camera keeps moving forever.
Your destination should be ZoomedTransform.position. No addition is necessary because position is in world coordinates. (And when you actually need to convert between spaces, check out TransformPoint and similar methods.)
It has been a while since I have done anything in Unity, but I think it is processing the Lerp function at frame time and not at actual time. You will need to call it in another function that is not being processed at frame time.

Drag sprite in cocos2d for the iPhone - with a max velocity

I'm trying to make a game where the user is supposed to drag a sprite up and down on the screen, avoiding incoming obstacles. The last answer here helped me to drag the sprite around on the screen, but I want to set a maximum speed the sprite can be moved (and hopefully with a natural-looking acceleration/deceleration), so it doesn't get too easy to avoid the objects.
Does anybody know how I can modify the code to achieve this, or is there another way to to it?
Thanks :)
You'll need to maintain a CGPoint destinationPosition variable which is the location of your finger and use an update loop to modify it's position:
-(void) update:(ccTime) dt
{
CGPoint currentPosition = draggableObject.position.x;
if (destination.x != currentPosition.x)
{
currentPosition.x += (destination.x - currentPosition.x) / 5.0f; // This 5.0f is how fast you want the object to move to it's destination
}
if (destination.y != currentPosition.y)
{
currentPosition.y += (destination.y - currentPosition.y) / 5.0f;
}
draggableObject.postion = currentPosition;
}
In the ifs, you might want to check if the objects are close to each other, rather than exactly the same number to allow for rounding errors.
You just need to have an if statement in whatever schedule updater you are using, like time, or touches, or whatever.
I'm presuming you have x/y velocities? Just inside your update statement, wherever your acceleration is -
if(acceleration.x > 20){
acceleration.x = 20;
}
if(acceleration.y > 20){
acceleration.y = 20;
}

How to get MouseScroll Input?

I am trying to make a simple weapon change in Unity3D.
The best way to do this is with the mouse Scroll wheel as far as i can see.
I googled on how to do this and found that i have to use the Input.GetAxis("Mouse ScrollWheel"); I use this piece of code and print it. Still i always get an value of 0.
any ideas? I just need to solve how to get the value first, ill figure out the rest myself.
Code idea:
function Update () {
print(WeaponNumber);
if(Input.GetAxis("Mouse ScrollWheel")){
WeaponNumber += Input.GetAxis("Mouse ScrollWheel");
}
}
Hey Friend,
Instead of Input.GetAxis you may use Input.GetAxisRaw. The value for GetAxis is smoothed and is in range -1 .. 1 , however GetAxisRaw is -1 or 0 or 1. and you may remove the If statement. cause when no scrollwheel happens the value is automatically zero.
So, Input.GetAxis("Mouse ScrollWheel") returns 0 if you didn't scroll, 0.1 if you scroll up and -0.1 if you scrolled down. So solution to this code would be:
function Update() {
if (Input.GetAxis("Mouse ScrollWheel") != 0) {
WeaponNumber += Mathf.FloorToInt(Input.GetAxis("Mouse ScrollWheel") * 10));
}
}
And that will basically increase WeaponNumber if you scrolled up and decrease if you scrolled down