- Home /
Addforce.forward on a sphere object
Hi pros,
short question. I wanna make a simple beat em up on a small planet. When my player hits an enemy the enemy should fly over the planet. Right now i am moving the enemy after a hit with addforce.
collision.gameObject.GetComponent<Rigidbody>().AddForce(transform.forward * attackPower);
My gravity script takes care that the player is not flying to far away from the planet. So far so good,
but i want that the enemy not simply flys straight forward, i want the enemy to crush on the planet from time to time and only "flys" over the surface and not high in the sky.
I tryed adding
collision.gameObject.GetComponent<Rigidbody>().AddForce(-transform.up* attackPower);
but nothing changed. The enemy still not touching the ground and bouncing back.
Any tipps from some experts?
Thx Smokki
I don't completely understand what you're trying to do here. If you want the enemy to bounce, add a physics material. If you want the enemy to go back to the ground, increase the force of gravity. If this doesn't help, please show your gravity script with a little more explanation of what you are wondering about. Hope this helps.
Hi there,
hmm what i want, i want to hit my enemy with a punch and then he should fly backwards, bounces to the ground, flys even more. Perfect would be when the enemy is spining around hisself when he gets hit, too. So that he not just fly in straight line, even more "realistic".
this is my script for the enemy:
public GameObject Planet;
public float speed = 4;
public float JumpHeight = 1.2f;
float gravity = 1000;
bool OnGround = false;
float distanceToGround;
Vector3 Groundnormal;
private Rigidbody rb;
public Transform player;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
enemyHealth = 100;
enemy$$anonymous$$axHealth = enemyHealth;
}
// Update is called once per frame
void Update()
{
//Local Rotation
$$anonymous$$oveToPlayer();
//GroundControl
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(transform.position, -transform.up, out hit, 10))
{
distanceToGround = hit.distance;
Groundnormal = hit.normal;
if (distanceToGround <= 0.2f)
{
OnGround = true;
}
else
{
OnGround = false;
}
}
//GRAVITY and ROTATION
Vector3 gravDirection = (transform.position - Planet.transform.position).normalized;
if (OnGround == false)
{
rb.AddForce(gravDirection * -gravity);
}
//
Quaternion toRotation = Quaternion.FromToRotation(transform.up, Groundnormal) * transform.rotation;
transform.rotation = toRotation;
}
public bool getHit;
public void $$anonymous$$oveToPlayer()
{
transform.position = Vector3.$$anonymous$$oveTowards(transform.position, player.position, 10*Time.deltaTime);
}
public int enemyHealth;
public int enemy$$anonymous$$axHealth;
and this my script for the hit :
public class arm : $$anonymous$$onoBehaviour { // Start is called before the first frame update void Start() {
}
// Update is called once per frame
void Update()
{
}
public float attackPower;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy")
{
collision.gameObject.GetComponent<Rigidbody>().AddForce(transform.forward * attackPower, Force$$anonymous$$ode.Impulse);
}
}
thx for answers so far :)) you guys are great
Answer by lgarczyn · Jan 20, 2020 at 07:13 PM
First, you should use the right ForceMode with AddForce. In this case, for a hit, it should be ForceMode.Impulse
. For gravity, it should be ForceMode.Acceleration
.
This has a very small effect, but it will save you headache. For example, Acceleration doesn't care about the weight of the object, and will pull everyone the same, just like real gravity. It will also multiply the force by Time.fidexDeltaTime so that changing the framerate of the physics engine doesn't change much about the game.
On the other hand, Impulse will be weaker against a heavier object, but will stay the same regardless of the framerate.
Gravity needs to be applied every single frame to work. By adding gravity only when you punched the enemy, you only made your punch weaker, but he will still fly in a straight line.
Thx for the different force types, that is awesome.
i Already added gravity to my enemys with :
if (OnGround == false)
{
rb.AddForce(gravDirection * -gravity, Force$$anonymous$$ode.Acceleration);
}
now with acceleration. It works better now. With the right power and gravity balance the enemy is slicing over the spehere after a hit.
But the effect, that he gets hit , flys, hit the ground, "bounces" a alittle up and flys again seems like the real difficult for me :D
I've noticed a few issues, both are that you should basically never touch the transform of a rigidbody (except for scaling).
For your rotation, get and set rigidbody.rotation ins$$anonymous$$d, or better yet: angularVelocity, but that's a bit more complex.
But your problem is likely that when the monster hits the ground, OnGround is automatically true, and you then use transform to move the enemy.
Ins$$anonymous$$d of doing that, use AddForce or set the velocity towards the player, but also add a stun timer that prevents them from moving when they are hit by the player, or when they hit the ground with a high velocity (using OnCollisionEnter and relativeVelocity).
A timer is a pretty simple concept, just have a float called stunTimer. Every frame, decrement it by Time.fixedDeltaTime, and don't take any action if it is above 0. When you are hit, set it to the stun duration.
Also, to get the enemy spinning, you want AddForceAtPosition
Your answer
Follow this Question
Related Questions
Sphere vs Capsule collider collision resolution 0 Answers
re-orienting velocity 1 Answer
Wrong gravity calculation? 2 Answers
iOS game: Physics with ConstantForce 1 Answer