Awaken Rigidbody in Unity - c#

Ok - I'm super new at Unity (just learning for fun) and wanted to have an enemy cube fall as the player gets within 15 on the Z. I can get the rigidbody function of the enemy cube to 'sleep' but then when I get within 15 or less, it will not awaken and start to fall. Can you help me with my code? The Debug.Log is telling me what I want as I run it, but the rigidbody is not reactivating on the enemy cube. Sorry if this is a super simple request...just trying to learn!
using UnityEngine;
public class activatefall : MonoBehaviour
{
public Transform Player;
public Rigidbody rbgo;
private float coolnumber;
private float badtogood;
// Update is called once per frame
void FixedUpdate()
{
coolnumber = transform.position.z;
badtogood = coolnumber - Player.position.z;
Debug.Log(badtogood);
if (badtogood < 15f)
{
rbgo.WakeUp();
Debug.Log("Falling!");
}
else
{
rbgo.Sleep();
Debug.Log("Frozen");
}
}
}

If you want a Rigidbody to be stopped and then fall, you can just use rbgo.useGravity = false/true.
There are other ways though, you can play with RigidbodyConstraints, making the Rigidbody freeze in Y axis and then remove this constraint.
If you want to stop a Rigidbody completely after it moves, you can just do rbgo.constraints = RigidbodyConstraints.FreezeAll or rbgo.velocity = Vector3.zero (and then, if you want to disable the gravity, you do rbgo.useGravity = false.
You can also use transform.position and/or transform.Translate if you don't want to deal with the Rigidbody itself.

Related

Collider not working if object is not moving

I tryed to make an elevator and i came around something that i could not explain.
So here is the scenario:
Once i put my object(in this case a cube) on the elevator it will go up and down.
If the object sits out the ride without moving and waits for the next ride, the colliding will stop when the elevator comes back through the ground.
If the object moves while the elevator come's back everything is fine and the object go's for another ride.
Could someone explain to my why this is happening and is there a fix for this ?
The platform is expected to go through the ground and pick up the object once it comes back above ground. (Imagine a not all to sectret elevator)
I alredy tried to add the script DontGoThroughThings.cs. It didnt work either.
Here is a screenshot of the inspectors.
Here is the script i made for the elevator to go up and down.
Elevator.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Elevator: MonoBehaviour {
public float speed;
public float distance;
private bool goingUp;
void Start () {
goingUp = true;
}
void Update () {
var currentPosition = transform.position;
currentPosition.y = goingUpDown(currentPosition.y);
transform.position = currentPosition;
}
private float goingUpDown(float currentPosition)
{
if (goingUp)
currentPosition += speed;
else
currentPosition -= speed;
if (currentPosition > distance / 2)
goingUp = false;
if (currentPosition < -distance / 2)
goingUp = true;
return currentPosition;
}
}
If you need any more information leave a comment. Thank you
You need to add a RigidBody to your elevator object, and then check the "Is Kinematic" option on it.
From the Unity Documentation RigidBody Manual:
Is Kinematic : If enabled, the object will not be driven by the physics engine, and can only be manipulated by its Transform. This is useful for moving platforms or if you want to animate a Rigidbody that has a HingeJoint attached.

Ball object slows down without gravity

I'm making a 2D Block breaker game; the issue is that my ball will slow down after a while, yet there isn't any gravity and the bounciness is at 100% so it should keep all its kinetic energy. I just need the ball to stay at a constant speed.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour {
public Paddle paddle;
private Vector3 paddleToBallVector;
private bool Started = false;
void Start () {
paddleToBallVector = this.transform.position
paddle.transform.position;
print(paddleToBallVector);
//this.GetComponent<Rigidbody2D>().drag = 0f;
}
void FixedUpdate () {
if (!Started) {
this.transform.position = paddle.transform.position + paddleToBallVector;
if (Input.GetMouseButtonDown(0))
{
Debug.Log("mouse clicked, Started = " + Started);
Started = true;
this.GetComponent<Rigidbody2D>().velocity = new Vector2(2f, 10f);
}
}
}
}
The issue isn't in the code - it's in the game Gravity settings. You could solve it in one of two ways:
1) change the gravity scale of the ball - go to the ball game object or Prefab, and look at the RigidBody2D component. In there, you have a field called "Gravity Scale", usually set to 1. Changing it to 0.1 will make your ball light and quick. However, this setup isn't ideal for a game with multiple levels.
2) Change the global gravity in the project settings. Go in the Edit Menu to the Project Settings and in the menu choose Physics2D:
In the panel that is opened you usually have a realistic gravity scale of -9.81. Change it to something like -1.
This will make all the objects in your game light, and lessen the hold of gravity for all levels. In a brick-breaker type game when only the ball is loose and thrown around, it makes the most sense.
If you want the ball to have constant velocity, you could set it each frame in Update
myRigidbody.velocity = speed * (myRigidbody.velocity.normalized);
Where myRigidBody is a private RigidBody declared somewhere in your script, and set in Start() like this
myRigidbody = this.GetComponent<Rigidbody>();
Because you dont want to have to call GetComponent every single frame.
Create a physics material 2D. Keep the bounciness at 1 but reduce the friction to zero. Now attach that material to your Ball Collider. Your ball won't lose any speed when colliding now

making a 2D GameObject react to the position of another 2D GameObject

So, my boss moves in a specific direction when it detects the player. The problem I'm having is how to get the boss to move depending on where the player is within a certain proximity. So if the boss is on the player's left, he'll move to the left. If he's on the player's right, he'll move to the right. But I can't figure out how to make him react based on distance. Right now I'm just doing a Debug.Log to save a few seconds.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class phantom : MonoBehaviour {
private Rigidbody2D rb;
private Animator anim;
public Transform Target;
void Start ()
{
rb = GetComponent<Rigidbody2D> ();
anim = GetComponent<Animator> ();
}
void Update ()
{
if (transform.position.x > Target.position.x ) {
Debug.Log ("left");
}
if (transform.position.x < Target.position.x ) {
Debug.Log ("right");
}
}
}
You could use the Vector3.Distance method to determine the distance between your two object based on thier respective transform. That way, you can modify your boss's behavior according to his proximity to the player. The smaller the magnitude value is, the closer your two transforms are.
Ex:
int distanceYouWant;
if(Vector3.Distance(transform.position, Target.position).magnitude < distanceToDoStuff)
{
Debug.Log("Boss do stuff!");
}
Here is the link to the Unity scripting API doc: https://docs.unity3d.com/ScriptReference/Vector3.Distance.html
Hope this helps!
I figured it out. I just made the function not in Update but with an OnTriggerEnterStay2d (Collider2D other). Then I placed a trigger collider on the same GameObject and only when it detects the Target (the player) does the debug come up.

Killing one Enemy causes every enemy to disappear - C# Unity

I have a problem with a game that I'm creating in Unity. The player controls a character that is getting attacked by a horde of zombies. I've created a spawner for all the zombies and that works great, the only problem is that once the player kills one zombie all the zombies disappear from the gameworld. I've posted the enemy script that is attached to each zombie below. I can't work out why every zombie is destroyed instead of just the one that has been attacked. Any help would be great!
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public static float Damage = 10.0f;
public static float Health = 10.0f;
public Transform target;
public float Speed;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Destroy the enemy if it's health reaches 0
if(Health <= 0){
Destroy(this.gameObject);
Debug.Log ("Enemy Destroyed!");
}
//Constantly move the enemy towards the centre of the gamespace (where the base is)
float step = Speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
The way the scene is set up is that I have an empty game object that contains a series of position objects and a spawner script that places the enemy sprite into the position object. This all seems to work fine but I can't find whats causing them to all disappear.
The problem is that you have declared Health as a static variable. This means Health will have the same value across all of your enemy instances. Declare health like this instead:
public float Health = 10.0f;
This way, each instantiated enemy will be able to have its own unique Health value.

Despite Force Applied, No Movement

This code is for an elevator-type platform, where once the player stands on it, it 'takes' the player up by adding force onto it.
The thing is, while the force is created, the rigidbody (the player) does not move when the elevator moves. The code was written in C#, using Unity 5. In the code, the player is assigned the public 'rb', and contains a rigidbody.
The animation is a simple animation clip that moves the elevator up. Any ideas? Thank you for your time and answers in advance.
The elevator is Kinematic, the Player is not.
using UnityEngine;
using System.Collections;
/*This script activates when the player steps on the elevator, as it takes them up a floor.*/
public class ElevatorMovementScript : MonoBehaviour
{
private bool elevatorUp = false;
public Animation anim;
public int elevatorDelay = 5;
public int force = 800;
public Rigidbody rb;
// Use this for initialization
void Start ()
{
anim = GetComponent<Animation>();
}
// Update is called once per frame
void Update ()
{
}
/*Checks if the player has stepped onto the elevator. If the player has, it waits five seconds, and then pushes the player up.*/
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag == "Player" && !elevatorUp)
{
Invoke("AnimationPlay",elevatorDelay);
elevatorUp = true;
}
}
/*Plays the animation of the player going up. Used for the 'Invoke' method.*/
void AnimationPlay()
{
rb.AddForce(transform.up * force);
Debug.Log (transform.up * force);
anim.Play ("Up");
}
}
It looks like this script is on your elevator's game object, in which case this line:
rb.AddForce(transform.up * force);
Will try to apply a force to the elevator, not the player. You've got to keep track of the player's rigidbody or somehow get it on demand in AnimationPlay.
You said that
the player is assigned the public 'rb'
But rb = GetComponent<Rigidbody>(); will ignore this and use the rigidbody attached to the gameobject that ElevatorMovementScript is attached to.

Categories

Resources