So I have assigned a script to a simple ball and tried to attach this code:
private Rigidbody2D rb2D;
Vector2 speed;
void Start()
{
rb2D = gameObject.AddComponent<Rigidbody2D>();
speed = new Vector2(1,0);
}
void FixedUpdate()
{
rb2D.AddForce(speed);
}
And It doesn't work. May I know what I did wrong ? As it seems that addforce doesn't work. And the object with script attached has a rigidbody2d component
Related
[![ hey guys so i need help please! i need my claw hand to be able to grab my object holder(orange thingy next to the red ball. my objectholder has a spring joint already so I want my clawhand to be able to grab it and pull it with the ball. When my hand opens then it shoots. But when I try to grab it, my hand goes right through.
My claw hand has rigidbody,box collider,configuration joint and is animation by this code
public class open2close : MonoBehaviour
{
public float speed;
private Animation anim;
Rigidbody rb;
void Start()
{
anim = gameObject.GetComponent<Animation>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
//********************Open pincher ********************
if (Input.GetKey(KeyCode.X))
{
anim.Play("clawopen");
}
//*******************Close pincher ********************
if (Input.GetKey(KeyCode.Y))
{
anim.Play("clawclose");
}
}
}
as for my object holder it has box collider,spring joint, rigidbody, and rotation constraint. Can someone guide me or help me in what i can do thank you.
It is probably best to not have a collider on the claw hand. This is because you are mixing rigidbodies with animation, which can get messy. I would reccomend keeping everything, excpt for the box collider on the claw hand. Set it to a trigger. You can put booleans in the if statements to open and close the claw. This way, you can set the position of the objectholder to be at the claw (if they are touching).
Change your script to something like
public class open2close : MonoBehaviour
{
public float speed;
private Animation anim;
[SerializeField] bool isClosed;
Rigidbody rb;
void Start()
{
anim = gameObject.GetComponent<Animation>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.X))
{
anim.Play("clawopen");
isClosed = false;
}
if (Input.GetKey(KeyCode.Y))
{
anim.Play("clawclose");
isClosed = true;
}
}
void OnTriggerStay(Collider obj)
{
Rigidbody colRb = obj.attachedRigidbody;
if (colRb != null && isClosed)
{
colRb.position = transform.position;
}
}
}
Let me know if this works and be specific! thanks :)
I am new to Unity and I'm making a stickman game I added a balance script.
But it shows a compiler error "The variable of rb has not been assigned".
Can u please tell me how to assign a variable?
Here's the code-
// Update is called once per frame
void Update()
{
rb.MoveRotation(Mathf.LerpAngle(rb.rotation, targetRotation, force * Time.fixedDeltaTime));
}
Because you didn't to use a Rigidbody you need to get the component from the GameObject and in your case make the actual Rigidbody variable you want to use.
Your code should look like that:
using UnityEngine;
public class Example : MonoBehaviour
{
Rigidbody rb;
void Start()
{
//Fetch the Rigidbody from the GameObject with this script attached
rb= GetComponent<Rigidbody>();
}
void Update()
{
rb.MoveRotation(.....);
}
}
I'm making a game in unity where the user drags to shoot a ball at some objects at a distance. So far I have this DragAndShoot script:
//using System.Collections;
//using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
public class DragAndShoot : MonoBehaviour
{
public Transform prefab;
private Vector3 mousePressDownPos;
private Vector3 mouseReleasePos;
private Rigidbody rb;
private bool isShoot;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnMouseDown()
{
mousePressDownPos = Input.mousePosition;
}
private void OnMouseUp()
{
mouseReleasePos = Input.mousePosition;
Shoot(mouseReleasePos-mousePressDownPos);
}
private float forceMultiplier = 3;
void Shoot(Vector3 Force)
{
if(isShoot)
return;
rb.AddForce(new Vector3(Force.y,Force.x,Force.z) * forceMultiplier);
isShoot = true;
createBall();
}
void createBall(){
Instantiate(prefab, GameObject.Find("SpawnPoint").transform.position, Quaternion.identity);
}
}
As you can see, I made the function createBall() in order to respawn a ball prefab at the position of the game object SpawnPoint. When I run the game, the first ball shoots fine. And another ball respawns.
Issue: when I shoot the second ball and it moves, one more ball seems to have appeared at the second ball somehow, and it moves as well. Not sure why this is happening and how to fix it - can someone pls help? Thanks.
The problem is that you need to Destroy() the game object you threw first. Since you are just bringing the objects back when click down again, here is what you should do:
Make it so that it destroys the old object. Because you just keep instantiating the object, then when you throw it again it throws the old one too. If you understand what I mean, then hopefully, you can turn this into what you want. (It wasn’t exactly clear what your game was; this is what I interpreted)
sorry if this is a really simple question, but I really can't figure it out. I'm making a game in which I'm starting off with a tutorial on movement and combat etc, but when I try to animate my tutorials using the same line of code that worked for my player movement script, it won't work. By "it won't work", I mean that whenever I save my script (called "Next_Script") and go back into Unity, I don't have the option to drag in my Animator component. Again, the answer is probably extremely simple, but I can't figure it out. Thanks. The line of code I'm using is
public Animator animator;
It worked perfectly on another script, so I don't know why it won't here. Here's a photo of my inspector in Unity.
For some reason it keeps changing my unity2d tag to unity 3d. It is 2d
Your script reference is broken so it isn't even recognized by Unity ...
This happens sometimes if you delete or rename or move the script outside of Unity after it was already attached to a GameObject.
First as the warning says make sure there are no compiler errors.
Then first of all drag in your script into the field Script of the missing component. This tells Unity again which script to use for the component it isn't recognizing anymore.
After that you should again see your Animator field where you can drag in your Animator as usual.
So from the comments I know you have compiler errors for your code
public class Next_Script : MonoBehaviour
{
public Animator animator;
public float Yay = 0f;
// Update is called once per frame
void Update()
{
Thread.Sleep(5000);
Yay + 1f;
animator.SetFloat("Next", Yay);
}
}
Here are multiple problems:
You do not want to use Thread.Sleep in Unity! This freezes your entire GUI mainthread!
For calling something repeatedly delayed among a lot other options you can use e.g. InvokeRepeating, a simple timer or a Coroutine (see examples below)
And then Yay + 1f; makes no sense ... you either want to assign this value to something or use Yay++; or Yay+=1
So your code should look like e.g.
public class Next_Script : MonoBehaviour
{
public Animator animator;
public float Yay = 0f;
void Start()
{
InvokeRepeating(nameof(Increase), 5f, 5f);
}
void Increase()
{
Yay += 1f;
animator.SetFloat("Next", Yay);
}
}
Or using a simple timer in Update
public class Next_Script : MonoBehaviour
{
public Animator animator;
public float Yay = 0f;
private float timer;
void Update()
{
timer += Time.deltaTime;
if(timer < 5f) return;
timer = 0;
Yay += 1f;
animator.SetFloat("Next", Yay);
}
}
Or using a Coroutine
public class Next_Script : MonoBehaviour
{
public Animator animator;
public float Yay = 0f;
private float timer;
IEnumerator Start()
{
while (true)
{
yield return new WaitForSeconds(5f);
Yay += 1f;
animator.SetFloat("Next", Yay);
}
}
}
I have looked around the web for answers but can't find a working one.
I have tried changing the code and I am pretty sure it's a very easy noob mistake as this is my first game.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class respawn : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private Transform respawnPoint;
private Rigidbody Rigidbody;
void FixedUpdate()
{
if (player.position == respawnPoint.position);
{
GetComponent<Rigidbody>().velocity = 0;
Rigidbody.angularVelocity = 0;
}
}
private void OnTriggerEnter(Collider other)
{
player.transform.position = respawnPoint.transform.position;
}
}
The very first thing you want to do is to look at the Unity error console. Your code throws multiple errors, they will appear in red. Double-click on an error to be taken to its line in your code.
Also, try get a good editor, like VS Code, as it will help you find issues immediately by adding red wavy underlines. With above two approaches in hand, you will be able to find ~99% of your issues yourself the next time, and then can ask in forums for the remaining 1%.
Let's go through your code step by step:
private Rigidbody Rigidbody;
In Unity you normally want the type in upper case Rigidbody, but the variable name in lowercase rigidbody (even though the C# coding conventions suggest uppercase properties). Either way, don't use the same name as the type, so write:
private Rigidbody rigidbody;
or e.g. (I'm now omitting the default private, though you may also prefer to keep it, and I use a shorter variable name, and clarify its start value):
Rigidbody body = null;
In the following code:
GetComponent<Rigidbody>().velocity = 0;
... you first of all get the rigidbody component again. This isn't needed if you got it once in start (and for repeated usage, can lag), so do it like this:
void Start()
{
rigidbody = GetComponent<Rigidbody>();
}
And secondly, you assign a 0, but you want to assign new Vector3(0f, 0f, 0f), or just
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
Lastly, you write
player.transform.position = respawnPoint.transform.position;
... but player and respawnPoint are already transforms, so you can use the simpler
player.position = respawnPoint.position;
Good luck!
When you enter the Trigger you will be teleported to the respawn position, but you cannot depend on FixedUpdate running on that exact pixel of the respawn position.
The most straigh forward answer is to, well, do the code as you would describe the issue: "When you enter a trigger, set the position to the respawn position and set velocity to 0":
I would change the entire script to:
public class respawn : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private Transform respawnPoint;
private Rigidbody rigidbody;
void Start()
{
rigidbody = GetComponent<Rigidbody>()
}
private void OnTriggerEnter(Collider other)
{
player.position = respawnPoint.position;
rigidbody.velocity = Vector3.zero;
}
}
and don't forget to populate the player and respawnPoint values in the inspector.
Also, keep in mind that the current code is prone to errors, if you have other objects moving around. Right now, if ANY object enters the Trigger the PLAYER position will be reset. You could fix this with check for player
private void OnTriggerEnter(Collider other)
{
if (other.transform == player)
{
player.position = respawnPoint.position;
rigidbody.velocity = Vector3.zero;
}
}