I write character controller script, and implemented moving by changing rigidbody.position, and when my character try move forward close to the wall, he falls a little into incline wall and floor.Character already in another collider ( i held right arrow)
I try make a cast and check if player collider are collide if he moves, but i think that bad resolve my problems , because it create a problems if i want move item by character body and etc.
I think it be possible reslove with unity rigidbody setting or a bit of code
My movement code:
public void Move(Vector2 direction)
{
Vector2 directionAlongSurface = _surfaceSlider.GetDirection(direction.normalized); // It get direction if player try walk on a slope (forward - Vector2.Dot(forward, _normal) * _normal;)
Vector2 offset = directionAlongSurface * (_speed * Time.deltaTime);
//var colliders = Physics2D.BoxCastAll(_boxCollider.transform.position, _boxCollider.size, 90, offset, offset.magnitude,_layerMask);
//if(colliders.Length == 0) //
_rigidbody.position += offset;
}
P.S Character collider a bit goes inside even in a flat wall
a) In your movement code, you are moving the Rigidbody with _rigidbody.position += offset;. This is an incorrect way of moving a physics object. try instead,
rigidbody.MovePosition(rigidbody.position + offset);
b) You might also want to check your Rigidbody settings, the Collision detection modes, to be exact. if you were to use fast moving GameObjects, you'd want Continuous collision detection mode instead of discrete.
Related
now, ive ben searching for I while, and I cant seem to find a simple answer. what is a simple way to make a jump pad that uses a character controller and not a rigidbody? (written in C#) I want my character to get boosted into the air when he collides with a specific game object. the script my character is using already has gravity so all I need is an upward boost. does anyone know how to do this? I dont have any code I dont know where to start, so please help!
Did you try Dotween functions? or did you try to change transform.position in Update using your skills.first I would try Dotween functions like Dojump or DoMove, Secondly I would try this ; transform.position + = Vector3.up * Time.deltaTime;
So, you have a player, he has movement and you want him to jump when he touchs a jump pad. So you need to have a CollisionScript for the player as well as a Impulse on the jump pad. My simplistic way to this, is...
Before you use this script you need to create a tag called probably jumpPad and then add it to your jump pad in the scene.
Then I would do the Collision Script, that will detect the collision when the player collides with the jump pad. And get the impulse towards y-axis on collision.
Collision Script:
public Rigidbody playerRb;
public float jumpForce = 10f;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("jumpPad"))
{
playerRb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
Then you just need to drag the player Rigidbody for the CollisionScript.
It will look like this
in the game that I'm producing, the player can shoot and I'd like to make the projectile rotates continuously when the player shoot it. Each player have an empty gameobject called SpawBala which instantiates the projectile.
I'm using these lines of code to instantiate it, but the rotation is not working:
//instantiates the bullet
GameObject tiro = Instantiate(projetil, SpawBala.transform.position, SpawBala.transform.rotation);
Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
if (SpawBala.tag == "Bala1" && gameManager.playerTurn == 1)
{
BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
BalaRigid.transform.Rotate(new Vector3(Bulletspeed * Time.deltaTime, 0, 0));
gameManager.PontoAcaop1--;
}
How could I solve it?
Your call to Rotate only happens exactly once and rotates the object about a given amount.
Anyway since there is a Rigidbody in play you shouldn't set transforms via the transform component at all because it breaks the physics.
Rather always go through the Rigidbody component.
I actually would not use AddForce and for rotation btw AddTorque when spawning a bullet. You would have to calculate the required forces depending on the bullet's weight in order to get the desired velocity(s).
Instead rather set a fix initial velocity and for the rotation angularVelocity.
Also note that currently you are always shooting in global World-Space Z direction no matter how your SpawnBala object is oriented in space. You should rather use SpawnBala.transform.forward as direction vector:
BalaRigid.velocity = SpawnBala.transform.forward * ProjetilVeloc;
// Note that your variable names are confusing
// You should probably rename it to BulletRotationSpeed e.g.
BalaRigid.angularVelocity = SpawnBala.transform.right * Bulletspeed;
Hey stackoverflow Community,
First of all:
I'm still very new about programming with C# and Unity.
My question:
I'm working on an idea for a Movement of a Cube.
It is planned that the cube will move forward by pressing a key (W-Key). But it shouldn't just move forward. It should jump forward to the next point. So always plus 1 of its axis into which it should go. Accordingly, it is only intended to go forward, right, down, left. He won't be able to jump over behind. You should also see that the cube jumps in the respective direction, so it should not teleport itself. :D
Does anyone have an idea how I can realize this movement?
I am very much looking forward to your ideas.
(Sorry if my English is not so good, my English not the best. ^^)
best regards
xKarToSx
So, in order to understand movement, it's best to first understand Vectors in Unity. Since you want to be moving the cube in the forward direction, I'm going to assume this is a 3D game, in which case you want to use a Vector3.
A Vector3 has three components: X, Y, and Z. Each component is tied to an axis. In simple terms, X is tied to left and right, Y is tied to up and down, and Z is tied to forward and back. So, Vector3 position = new Vector3(0, 1, 2); will be a vector that is 1 unit above and 2 units in front of the starting position.
Assuming you've attached this script to the cube you want to move, you can track its position with transform.position. So, if you want to move the cube one unit forward, your code would look something like this:
if(Input.GetKeyDown(KeyCode.W)) // This code will activate once the user presses W.
{
transform.position += new Vector3(0, 0, 1);
}
That will move the cube one unit forward in the Z direction. However, you don't want it to teleport, you want to see it move, correct? In that case, you want to check out Unity's Vector3.Lerp function. Basically, you would use it to smoothly transition an object between two defined positions. You'll need to implement a timer and a for loop in order to make this work correctly.
So, to summarize, for moving one unit forward in the Z direction, your code would look something like this:
if(Input.GetKeyDown(KeyCode.Z))
{
float startTime = Time.time; //Time.time is the current in-game time when this line is called. You'll want to save this to a variable
float speed = 1.0f; //The speed if something you'll want to define. The higher the speed, the faster the cube will move.
Vector3 startPosition = transform.position; //Save the starting position to a different variable so you can reference it later
Vector3 endPosition = startPosition + Vector3.forward; //Vector3.Forward is equivalent to saying (0, 0, 1);
float length = Vector3.Distance(startPosition, endPosition); //You'll need to know the total distance that the cube will move.
while(transform.position != endPosition) //This loop while keep running until the cube reaches its endpoint
{
float distCovered = (Time.time - startTime) * speed; //subtracting the current time from your start time and multiplying by speed will tell us how far the cube's moved
float fraction = distCovered / length; //This will tell us how far along the cube is in relation to the start and end points.
transform.position = Vector3.Lerp(startPosition, endPosition, fraction); //This line will smoothly transition between the start and end points
}
}
I hope this helps you. This is my first time answering a question so sorry if I got some things wrong/it's not the most optimized. Good Luck!
I'm making an infinite runner game, using an infinite runner engine, which works by making the player/runner stay at its same position while the background elements, platforms and enemies come at the player.
This was working fine until I introduced enemy shooting, where the enemies locate and shoot the player. I'm using the following script that is on the EnemyBullet prefab:
void Start()
{
shooter = GameObject.FindObjectOfType<Player>();
shooterPosition = shooter.transform.position;
direction = (shooterPosition - transform.position).normalized;
}
// Update is called once per frame
void Update()
{
transform.position += direction * speed * Time.deltaTime;
}
This works, but the problem is that it is way too accurate, like even when the player is jumping the bullet prefab tends to guess its position and is shot directly at the player.
I know this is because the player does not actually move and this makes the targeting of the player very easy.
Is there any way to improve this? Or in a way make it more natural?
Thanks
The problem is that in the code
shooter = GameObject.FindObjectOfType<Player>();
shooterPosition = shooter.transform.position;
direction = (shooterPosition - transform.position).normalized;
Since shooter.transform.position is the player's location and transform.position is the bullet's location, then shooterPosition - transform.position is giving you a vector that points directly from the bullet's location to the player's location.
It sounds like what you want to do is add some amount of inaccuracy to the bullet (correct me if I'm wrong). You could use something like this to do that (I'm assuming this is 2D?)
shooter = GameObject.FindObjectOfType<Player>();
shooterPosition = shooter.transform.position;
direction = (shooterPosition - transform.position).normalized;
// Choose a random angle between 0 and maxJitter and rotate the vector that points
// from the bullet to the player around the z-axis by that amount. That will add
// a random amount of inaccuracy to the bullet, within limits given by maxJitter
var rotation = Quaternion.Euler(0, 0, Random.Range(-maxJitter, maxJitter));
direction = (rotation * direction).normalized;
In my 2D side-scrolling game I move my character using the built-in physics engine by manipulating the rigidbody.velocity.
I would like to add some sort of dodge (roll) ability, where the character moves 3 units in its direction.
Here is the code I used:
void FixedUpdate() {
if (Input.GetKeyDown(KeyCode.A) ) {
Vector2 pos = rb.position;
pos.x -= 5;
rb.MovePosition (pos);
}
}
This method works but the character kind of jumps to the position rather than moving to it (Lerping?) and also doesn't detect collisions despite the body type being dynamic.
Then I tried this:
if (Input.GetKeyDown(KeyCode.A)) {
rb.AddForce(new Vector2(-50, 0));
}
I found the AddForce way isn't accurate at all.
Is there a proper way of doing this?
Maybe you could change the Transform.pos inside Vector2.Lerp to make it look smooth? (Sorry, not enough experience with 2D in unity.)
Just increase rigibody.velocity for a set time. Your chararter object could then play a fitting aniamtion. If The player should not be able to cancle midrole jsut block the controls for that time.