Make a projectile to rotate - c#

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;

Related

Character goes inside incline wall when moving

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.

How can i get the enemy missile to target the player instead of origin?

My game has a level where enemies fly in and fire missiles at the play, they're supposed to target the players local at the moment they were fired but when they're fired they only hit the player when its moving left to right, when it moves forward the missile just fly right overhead.
void Start() //targeting the player
{
playerManager = GameObject.FindGameObjectWithTag("PlayerManager").transform; //NB: it is tracking wherever the playerManager is placed on the X axis, but NOT the playerManager directly
//target = new Vector3(playerManager.position.x, playerManager.position.y); //this is the original line
// target = new Vector3 (playerManager.transform.position); //this was recommended on unity answers but it returns an error.
rb.velocity = transform.forward * speed; //addition, tells it to shoot forward
}
I want the missiles to keep targeing the player as they move along the z axis.
when the player can only move side to side it works as intended but when they move forward the missiles end up flying over head.
this line: target = new Vector3 (playerManager.transform.position); returns the following error message:
Error CS1729 'Vector3' does not contain a constructor that takes 1 arguments
You want the missiles to consider the player's z position but the "target" Vector3 in your first option is missing the third argument and so it defaults to (x,y,0) rather than (x,y,z). You could do:
target = new Vector3(playerManager.position.x, playerManager.position.y, playerManager.position.z);
or:
target = playerManager.transform.position;
Note that Vector3 is constructed with three floats, not with a Vector3, which is what playerManager.transform.position is. You can skip the constructor and just set the values equal.

How to improve targeting of enemy where the player stays stationary while everything else moves?

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;

Accelerate object towards a certain direction

I am trying to make a game by myself and I encountered a difficulty.
I have this object and I need it to accelerate towards a vector 3 point.
I tried using the Vector3.MoveTowards command, but the object moves with a constant velocity and stops at the destination.
What I need to do is have the object accelerate from 0 velocity towards a vector 3 point and not stop at the point, but continue at the same direction after it went through the point.
Does anyone know how to do this?
Thank you!
Perform these steps in a method that is called in the Update or FixedUpdate method. FixedUpdate is recommended if you are using rigid bodies.
First, you need to find the direction from your position to the point, and define a velocity instance variable in your script if not using Rigid Bodies. If you are using a Rigidbody, use rigidbody.velocity instead. target is the Vector3 position that you want to accelerate towards.
// Use rigidbody.velocity instead of velocity if using a Rigidbody
private Vector3 velocity; // Only if you are NOT using a RigidBody
Vector3 direction = (target - transform.position).normalized;
Then you need to check if we have already passed the target or not. This check makes sure that the velocity remains the same
// If our velocity and the direction point in different directions
// we have already passed the target, return
if(Vector3.Dot(velocity, direction) < 0)
return;
Once we have done this we need to accelerate our Transform or Rigidbody.
// If you do NOT use rigidbodies
// Perform Euler integration
velocity += (accelMagnitude * direction) * Time.deltaTime;
transform.position += velocity * Time.deltaTime;
// If you DO use rigidbodies
// Simply add a force to the rigidbody
// We scale the acceleration by the mass to cancel it out
rigidbody.AddForce(rigidbody.mass * (accelMagnitude * direction));
I recommend that you use a Rigidbody since it makes much more sense when doing something like this.

Set orientation of moving object towards it movement direction without using rigidbody

I have a GameObject (camera) which is moving on the spline (using a library). I want to set its orientation towards its movement. What I mean is, the object should be looking in the direction that it is moving. I tried some things to achieve this, but I was unsuccessful. Here are my attempts:
transform.rotation = Quaternion.LookRotation(transform.position);
I have also tried this
transform.rotation = Quaternion.LookRotation(transform.forward);
Neither transform.position (a point in space) nor transform.forward (the direction an object is already facing) will necessarily give you the direction an object is moving in.
For an object with a RigidBody, you'd access this through the velocity variable - but since it sounds like you're using a proprietary spline library and have no access to the object's actual movement direction, you may need to keep track of it yourself.
The simplest solution (if the library really doesn't provide movement information), is to store the object's present position and previous position each frame, and manually calculating the delta position (aka. The distance travelled between the frames) to find the velocity vector. For example:
public class MovingObject : MonoBehaviour {
private Vector3 prevPosition;
void Start() {
// Starting off last position as current position
prevPosition = transform.position;
}
void Update() {
// Calculate position change between frames
Vector3 deltaPosition = transform.position - prevPosition;
if (deltaPosition != Vector3.zero) {
// Same effect as rotating with quaternions, but simpler to read
transform.forward = deltaPosition;
}
// Recording current position as previous position for next frame
prevPosition = transform.position;
}
}
Hope this helps! Let me know if you have any questions.
Try
transform.rotation = Quaternion.LookRotation(transform.position - currentPosition);
where currentPosition is the position on the spline where your game object is right now (before applying the transformation transform).
Keep in mind that Quaternion.LookRotation() does not expect the position to look at but the direction where to look instead. See the documentation and FAQ.
You are on the right track, but you should use your movement direction: transform.rotation = Quaternion.LookRotation(movementDirection), as transform.forward is already the objects' orientation.
If you do not know/have access to the objects' current movement direction but you know the target position, you can rotate towards the target position: transform.rotation = Quaternion.LookRotation(targetPosition - transform.position)

Categories