I'm working on a game similar to golf. My situation is this:
I have colliders like martinellas, so their behavior is to bounce ball and keep the same amount of speed.
Well, since I added some abilities, one ability is that my ball transforms into a wheel and goes only in forward direction at higher speed. When it collides with martinellas, it should bounce by Y axis only (in air) and stop movement as well. I managed to do it by freezing the positions.
Looks good for now, but I have a problem: when the ball touches the ground, it collides again, because it goes to the first position of collision. It makes sense.
Now, I need help on how to only bounce in the air, and little bit backwards, so it doesn't collide again (without freezing the positions, I guess).
So, here I added a picture to understand it easier.
1st and 2nd scenario works now.
Now I need the 4th scenario.
The 3rd scenario shows how the ball is dropping by default: it drops down to position of ball in 2nd scenario, which makes collision again. I need the ball to drop down by changed direction, not much, only a little bit to evade the collision.
You can interpolate between y-axis between fixed position.
Vector3 interpolatedPosition = Vector3.Lerp(
new Vector3(transform.position.x, 0, transform.position.z),
new Vector3(transform.position.x, 5, transform.position.z), Time.deltaTime * 5);
transform.position = interpolatedPosition;
Related
I started some programming in Unity just for fun a couple days ago.
So far my game (pretty much top-down shooter) consists of player flying in an asteroid field, in which lurk enemy ships. Player can shoot down asteroids and enemies, and enemy ships have missile turrets that "track" player.
Everything works fine until I decided that enemy ships shouldn't be able to rotate their turrets all the 360-way. Think of it as real-world battleship being unable to turn it's front turret (No.1) 180 degrees behind because turret No.2 is in the way.
Currently code for turret rotation is like this (this is not about making "gradual rotation", setting "rotation speed" or something, so please don't look at that!):
playerTarget = GameObject.FindGameObjectWithTag("Player");
chaseDirection = Quaternion.LookRotation(playerTarget.transform.position - transform.position);
newYaw = Mathf.Clamp(chaseDirection.eulerAngles.y, minYaw, maxYaw);
transform.rotation = Quaternion.Euler(0, newYaw, 0);
That works okay, until player flies behind enemy ship. As soon as player gets into turret's "possible rotation angle", it just snaps past "dead zone" to new direction if I don't turn it gradually with fixed angle, or is still stuck trying to rotate "past limit" until target (player) flies all around enemy ship so the angle to target is small enough for rotation direction to be calculated through "enabled" rotation zone, not through "dead zone".
An important thing is I am not looking for answer "how to make gradual rotation". I am looking about calculating rotation direction!
I thought about coding enemy to start rotating turret in counter-direction as soon as player passes "directly behind" the turret "forward facing" position. But the concept of how to do that eludes me.
Because as soon as turret rotates just a bit from limit, it's able to turn "towards" player again, and gets stuck at limit again.
Edited with the clarification in mind.
You need a function that will tell you if you should rotate clockwise or counter-clockwise, based on the enemy location.
First find the mid point, this will be:
var mid = (minYaw + maxYaw) / 2
In your example this will be 3 o'clock, straight right.
Now, if your current rotation is lower than mid, and the target is higher than mid, than you must rotate clockwise even if it's not the shortest rotation to get there.
If the target rotation is higher than mid, and the target is lower than mid, you must rotate counter-clockwise for the same reason. You may need to adjust for negative degrees.
Please note that this will create a secondary effect, where once the ship passes the half point of the dead zone (say moving from 10 o'clock to 8 o'clock in your example), the turret will start moving as if anticipating the flank. You may want to disable this movement in a special case.
I'll keep the second part of my answer as-is, for future references.
If you want it to move gradually, you need to use deltaTime or fixedDeltaTime in case of a fixed update. You can define how fast it will move by adding a speed property. Try something like this:
void update () {
var playerTarget = GameObject.FindGameObjectWithTag("Player");
var chaseDirection = Quaternion.LookRotation(playerTarget.transform.position - transform.position);
var newYaw = Mathf.Clamp(chaseDirection.eulerAngles.y, minYaw, maxYaw);
var currentRotation = transform.eulerAngles;
var desiredRotation= currentRotation;
var desiredRotation.y = newYaw;
transform.eulerAngles = Vector3.RotateTowards(currentRotation, desiredRotation, Time.deltaTime * RotationSpeed, 0.0f);
}
I'm making a game with unity3D that ball is rolling on the ground.
When I set single large ground block, and using Rigidbody.AddForce() in Unity3D. ball is rolling fine.
But if I set multiple small ground blocks, ball is jumping unexpectly on boundary of blocks. Even block size, positions and intervals are exactly matched.
Can I solve this problem?
(I can't freeze position Y of ball. because ball needs gravity.)
-edited-
Here is my code to move ball by AddForce(). when I clicked.
private void MoveBall(Vector3 pos)
{
Ray HookRay = Camera.main.ScreenPointToRay(pos);
int layerMask = LayerMask.GetMask("Block");
RaycastHit objectHit;
float distance = Mathf.Infinity;
if (Physics.Raycast(HookRay, out objectHit, distance, layerMask))
{
moveTo = objectHit.point;
Vector3 forceValue = moveTo - transform.position;
forceValue.y = 0f;
rb.AddForce( forceValue * charSpeed, ForceMode.Impulse);
}
}
And here is screenshot of Unity3D
I placed 3x1x3 cube blocks and arranged all positions Y to 0.
There are no cracks or gaps on it.
This likely comes from inaccuracies in the physics engine. They are there because the engine tries to cut corners to speed up processing. You can make it cut less counters (at the cost of speed) by following a few steps. First thing to try is to make the rigidbody do collision detection continuous. You can also try turning on interpolation. There are also more advanced ways where you will do physics updates more often than your frame rate. But I would try the simpler options first. They’re often enough.
Go to Edit -> Project Settings -> Physics and play with default contact offset, maybe make it much smaller like 0.00001 and try it. Another way you can freeze the y and then when some condition happens you can unfreeze it again.
I'm a beginner and I'm currently trying to create a 3D Tetris. Since 1-2 Weeks im trying to rotate my Tetromino properly, but it's not working the way I want.
So this is my "T" Tetromino. It's made of 4 Cubes, which are combined with an empty gameobject like this:
When I rotate the "T" gameobject with transform.Rotate(0, 0, -90), optically every cube moves, but not really. There is a blue dot on the first Picture. When i rotate my gameobject, it rotates around this point. After the rotation, every cube gets its new transform.position expect the middle one. Optically it moves one unit, but its transform.position doesn't change.
The same with the other figures. There is always one Cube, which transform.position doesn't update. I kinda know why its position doesn't change, but i still don't know what to do.
I tried many stuff, but i failed. Summarized I want my gameobject to rotate and update its position. Is there a way to do this?
Best regards
at the moment i'm working on a 2D plattformer and the work is going very well. But there is one Problem i can't get rid of.
The player can use a dash, which should move the player very fast in the direction he is looking. My problem is, that the player game object instant appears at the target location... like a teleport.
I'm using the AddForce Function to move the game object. On jumping i'm using AddForce as well and there it works really nice, i get a smooth jump movement.
The only different between dash and jump is that on jump i apply force to the y axis and on dash to the x axis. Changing the amount of force doesn't affect the movement only the distance.
Does anyone have an idea what i'm doing wrong?
// Dash
rigidbody2D.AddForce (new Vector2((dashSpeed * direction), 0));
// Jump
rigidbody2D.AddForce (new Vector2(0, jumpForce));
Best,
Verdemis :)
EDIT: I can not access my project at the moment, but i will try to show you what i have done.
Note: dashSpeed is a float value, at the moment something like 3500
and direction contains 1 or -1, depending on the direction the player is looking. The Dash code is part of the Update method.
// Dash
if(Input.GetKeyDown(dashKey))
rigidbody2D.AddForce (new Vector2((dashSpeed * direction), 0));
What is your direction vector, is it normalized? Since multiplying non-normalized vectors can be rather hazardous. Do you have more of the script to show?
EDIT: You should always do physics things in the FixedUpdate loop(link).
Ok i could solved the problem. My problem was that i only did this AddForce only once. The AddForce code was only executed in a single frame. I added a time which i count down to define how long the dash movement gonna be!
The problem may be that you are using a very big force, I was messing around with some physics today and realized that even a force of 100 almost looks instant. Try making a smaller force number to see if that helps you. I just tested making a smaller number and that does not work.
I have been working on a Unity ping pong game using the Leap Motion. I use rigidbody.MovePosition() to move the paddle. However, when I hit the ball (which uses gravity), the paddle launches it too far. Even when I change the masses of both, it doesn't do anything.
What variable should I change to reduce this energy going into the ball?
From the following link.
"MovePosition will put your object at the target location, no matter what. It may push aside other objects in a realistic way, or may blast them out of the way, or may just pass right through them. But it will gladly move you through a solid wall or a mountain.
If you're using MovePosition on a rigidbody to add from where you currently are, it looks like AddForce. With AddForce, the physics step does all the work: applies your velocity, sees the collision and handles the bounce. With MovePosition, the physics step sees you're mysteriously overlapping a solid object. If it isn't too much, it will bounce you apart."
You won't need to use MovePosition. Instead, you can figure out the direction of the shot (based on the position of the ball relative to the paddle). Then you can add an impulse force in that direction to the ball.
Pseudo-code (from the following link):
Vector3 shootDir = ballPosition - paddlePosition; // Calculate direction of the shot
shootDir.Normalize(); // Normalize the shot vector
ball.AddForce(shootDir * speed, ForceMode.Impulse); //Add impulse force in correct direction.
Credit due to Owen Reynolds and Tim Michels.