rigidbody tab not showing in unity - c#

For some reason, the tab in my unity script for rigid body isn't showing up, and nothing's working.
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public Rigidbody rb;
// Start is called before the first frame update
void Start ()
{
Rigidbody.AddForce(0, 200, 500);
}
// Update is called once per frame
void Update()
{
}
}
This is very confusing for me, any help?
Btw, I get this error:
"Assets/PlayerMovement.cs(12,9) error CS0120: An object refrence is required for the non-static field, method, or propererty 'Rigidbody.AddForce(float, float, float)'

You made a typo. Right now you are refering to Rigidbody insted of the variable name you defined called rb.
So you would need to write this instead:
rb.AddForce(0, 200, 500);

Try:
[SerializeField] public Rigidbody rb;

Since you put RigidBody, the class, it thinks you are trying to use a static method, which is not what you want to do. AddForce is not a static method, you need to call in on the instance of the RigidBody you created i.e. rb.

Related

I can't assign script from another object. Is there smth wrong?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorRangeController : MonoBehaviour
{
[SerializeField] PlayerController PlayerController; // It has to be script
[SerializeField] GameObject Player; // no problem with assigning this
[SerializeField] Transform playerTransform;
[SerializeField] Vector3 playerPos;
[SerializeField] bool canGo;
[SerializeField] GameObject meteor;
// Start is called before the first frame update
void Start()
{
playerTransform = Player.GetComponent<Transform>();
PlayerController= Player.GetComponent<PlayerController>(); //*The Problem Is Here*
//PlayerController Cannot Be Assigned
}
// Update is called once per frame
void Update()
{
print(PlayerController.IdleTime); //to test it I printed
playerPos = Player.transform.position;
//I tried to take idle time from Player controller here.
if (PlayerController.IdleTime > 2)
{
canGo = true;
}
else
{
canGo = false;
}
if (canGo == true)
{
transform.position = new Vector3(playerPos.x, playerPos.y, playerPos.z);
gameObject.SetActive(true);
Invoke("SetActiveFalse",2f);
}
}
void SetActiveFalse()
{
gameObject.SetActive(false);
meteor.SetActive(true);
Invoke("MeteorSetActiveFalse", 2f);
}
void MeteorSetActiveFalse()
{
meteor.SetActive(false);
}
}
I can't assign it.
I researched it but I couldn't find anything different.
I know it's a very easy question, also I assigned game object player, in it there is a script named PlayerController, and there is a variable named idle time please help me
Okay, that's my first try to answer on topic on Stack Overflow, so hope you will be patient to my mistakes.
Can you say, are you sure, that Player object has a PlayerController script on him?
I think you must use
var isControlSetted = Player.TryGetComponent<PlayerController>(out PlayerController);
instead of:
PlayerController= Player.GetComponent<PlayerController>();
Why? So, that can answer on question №1 and after it you can control the logic of working with it when (use AddComponent for example or throw an exception)
3. Okay, even that can't fix your problem if PlayerController setted on inheritor or ancestor of Player gameobject in gameobject hierarchy
I hope I helped you
Edited:
Okay, I was asked to make answer some clearly, so...
First of all, can you show PlayerController script, pls?
Secondary, why I'm asking to use TryGetComponent instead of GetComponent bcs as I commented below getting null value is not a good practice, but if you want - use it.
Let's look on script more closly
I refactored this pls look
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorRangeController
: MonoBehaviour
{
[SerializeField] PlayerController playerController;
[SerializeField] GameObject playerObject;
[SerializeField] Transform playerTransform;
// [SerializeField] Vector3 playerPos; we don't need this
// [SerializeField] bool canGo; and this
[SerializeField] GameObject meteorObject;
/// <summary>
/// Method that called once we use this or Awake for init our fields/props
/// </summary>
void Start()
{
playerTransform = playerObject.GetComponent<Transform>(); // there no need to use TryGetComponent bcs Transform is req. for every GO/MB
playerController= playerObject.GetComponent<PlayerController>(); // there you could use TryGC, but if you use RequireComponentAttribute that's ok
}
/// <summary>
/// Method that's calls every frame
/// </summary>
void Update()
{
if (playerController.IdleTime <= 2)
return;
transform.position = playerTransform.position;// i really can't understand what hepenning after this so i stop
gameObject.SetActive(true);
Invoke(nameof(SetActiveFalse),2f);
}
void SetActiveFalse()
{
gameObject.SetActive(false);
meteorObject.SetActive(true);
Invoke(nameof(MeteorSetActiveFalse), 2f);
}
void MeteorSetActiveFalse()
{
meteorObject.SetActive(false);
}
}
So, afterwards GO.GetComponent can return null only if the requested GO did not have a Monobehaviour script.
You can check similar question there https://forum.unity.com/threads/getcomponent-doesnt-works.516839/

I don't know how to communicate with other scripts

I have a Player script. I have the variables on there
public class Player : MonoBehaviour
{
float horimove;
Rigidbody rb;
public float speed;
public GameObject thrown;
public bool win;
On my other script (I'm making a game where you instantiate spheres into a hole and win.)
public class spheresciprt : MonoBehaviour
{
public Player pscript;
public GameObject player;
// Start is called before the first frame update
void Start()
{
player = GameObject.Find("Player");
pscript = player.GetComponent<Player>();
}
private void OnTriggerEnter(Collider other)
{
if (gameObject.CompareTag("win"))
{
pscript.win = true;
}
}
However pscript.win doesn't change. The bool always stays false but I want the player to win after the sphere hits the trigger in the hole I want it to go to. I tried different computers. The same thing happened in different games I think so I'm probably just missing something.
First of all, make sure that the collision is detected. You can easily do something like
void OnTriggerEnter()
{
Debug.Log("Pass1");
if (gameObject.CompareTag("win"))
{
Debug.Log("Hey, it worked!");
}
}
in the OnTriggerEnter to check that.
If the collision is NOT detected, make sure there are colliders on all the affected GameObjects, as well as a RigidBody component on the sphere. Also, make sure that the collider is marked as Trigger. If you still have an issue with that, we will need to see your inspector to figure it out.
If the collision IS detected... Well, start by making sure that you have assigned the proper tag on the hole. Then, make sure that the player GameObject is actually called "Player" (since you are trying to find it by name) and that it has the script you are trying to get on the object you actually find (and not on one of its children). I hope that works, because I can't see anything else seriously flawed at your code.
Have you tried to change
if (gameObject.CompareTag("win"))
to
if (collider.gameObject.CompareTag("win"))
or just add the rigidbody to both player and other object.
does the other object have "win" tag?
Here is your script:
public class spheresciprt : MonoBehaviour
{
public Player pscript;
public GameObject player;
// Start is called before the first frame update
void Start()
{
player = GameObject.Find("Player");
pscript = player.GetComponent<Player>();
}
private void OnTriggerEnter(Collider other)
{
if (gameObject.CompareTag("win"))
{
pscript.win = true;
}
}
}
It sets pscript to the current values in Player script. This is the problem, because it is setting a variable to the current values, and you want access to the component. You could change this by, just replace all of the pscript variables with player.GetComponent<Player>(). There are other ways of doing this. You could, at the end of OnTriggerEnter, add this:
void OnTriggerEnter(Collider other)
{
...
player.GetComponent<Player>() = pscript;
}
In both of these solutions you fix it. In one, you re-apply the variable. In the other, you are changing the component directly. Which is what you want, because you have pscript as an instance of player script, not the player script that is attached to player.

I dont get why unity gives a compile error here

I'm trying to change the text of a TMPro text box, but unity reports at 20,79 I need a }. I put in the bracket and 11 errors pop up. debug pls? I don't know much c# myself so I can't do it myself. pls, help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class tetxmeshpro : MonoBehaviour
{ int previoushealth = 100;
private TextMeshProUGUI textMesH;
// Start is called before the first frame update
void Start()
{
var Player; GameObject;
textMesH = GetComponent<TextMeshProGUI> ();
}
// Update is called once per frame
void Update()
{
if ((Player.GetComponent(playerScript).Health)) not == previoushealth;)
{
previoushealth = Player.GetComponent(playerScript).Health;
textMesH = previoushealth;
}
}
}
What exactly is
var Player; GameObject;
supposed to do? ;)
It seems you rather mean
GameObject Player;
Either way the Player is not a field so later in Update you don't have access to it either. You probably rather wanted a
[SerializeField] private GameObject Player;
on class level so you can reference your object in it. Or even better give it the correct type right away:
[SerializeField] private playerscript player;
This way you don't need the GetComponent later.
What is this
if ((Player.GetComponent(playerScript).Health)) not == previoushealth;)
This is c# not some Shell/Dos script -> use != and not not ==. Also if conditions don't end with a ; and there is a ) too much. And also GetComponent either is generic, then it is GetComponent<T>() or you pass in a type but then you have to cast it like ((T)GetComponent(typeof(T))).
If something it should rather simply be
if (Player.GetComponent<playerScript>().Health != previoushealth)
Your class should rather look like
public class tetxmeshpro : MonoBehaviour
{
int previoushealth = 100;
// Link these via the Inspector using drag&drop
[SerializeField] private TextMeshProUGUI _textMesH;
[SerializeField] private playerscript _player;
// Start is called before the first frame update
private void Start()
{
if(!_textMesH) _textMesH = GetComponent<TextMeshProGUI>();
}
private void Update()
{
if (_player.Health != previoushealth)
{
previoushealth = _player.Health;
textMesH = previoushealth;
}
}
}
Though, note that naming your class textmeshpro a) might lead to confusions with the existing TextMeshPro and also doesn't at all reflect the purpose of that class. I would suggest something like e.g. HealthDisplay or anything similar meaningful.

OnTriggerEnter() is called right on the start

I'm making some sort of a Evolution simualtor game. I have a script that is supposed to destroy the GameObject it's attached to when a creature's CapsuleCollider Triggers the OnTriggerEnter().
I have a problem that even tho the Creature's collider isn't even close to the Food, it still destroys the GameObject.
My script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FoodEat : MonoBehaviour
{
public GameObject FoodGO;
public Rigidbody FoodRB;
private void OnTriggerEnter(Collider Creature)
{
Destroy(FoodGO);
}
void Start()
{
FoodRB = GetComponent<Rigidbody>();
FoodGO = FoodRB.gameObject;
}
void Update()
{
Rigidbody[] allRigidBodies = (Rigidbody[])FindObjectsOfType(typeof(Rigidbody));
foreach (Rigidbody body in allRigidBodies)
{
if (body.gameObject.layer == 10)
{
OnTriggerEnter(body.gameObject.GetComponent<CapsuleCollider>());
}
}
}
}
OnTriggerEnter is a monobehaviour lifecycle method. You should not call it from your own code; it will automatically be called when it detects collisions.
Furthermore, the logic in your code right now seems to be incorrect, it is...
"Every frame, loop through all rigidbodies in the scene and if 1 is found on layer 10, destroy the FoodGO"
Simply remove your entire Update method and put an if in your Collision method, and it should work:
[RequireComponent(typeof(Rigidbody), typeof(Collider))]
public class FoodEat : MonoBehaviour
{
private void OnTriggerEnter(collider other)
{
Debug.Log(other.gameObject.name + " on layer " + other.gameObject.layer);
if (other.gameObject.layer == 10)
Destroy(this.gameObject);
}
}
A few noteworthy edits of your code:
I removed FoodGO, since it's the GameObject this script is attached to, you can access it by just writing gameObject or this.gameObject.
I remove the Rigidbody reference since it is not used anymore, and thus the entire Start() method.
Since this code requires a Rigidbody and a Collider to work, I added a [RequireComponent] attribute in the top, which will make Unity tell you if you forgot to add those components on the object you attach this script to.
I added a Debug.Log that prints the name & the layer on the creature that collides with the food, so you can debug and make sure it is working as expected

Referencing a non static member with an instantiated object

I want this class to render a grid each time it is instantiated, but I am getting the error, error
CS0120: An object reference is required to access non-static member
`UnityEngine.GameObject.GetComponent(System.Type)'
So I instantiate an object of Renderer called Rend and set that equal to the non-static member but I am still getting the error? Any help would be greatly appreciated as I have researched for several hours and still can't figure this out.
using UnityEngine;
using System.Collections;
public class SetGrid : MonoBehaviour {
public int x = 1;
public int y = 1;
void Start()
{
Renderer Rend = GameObject.GetComponent<Renderer>().material.mainTextureScale = new Vector2 (x, y);
}
}
I am assuming this script is part of your grid game object which also has a component of type Renderer.
The correct syntax to scale the texture of the Renderer is following:
public class SetGrid : MonoBehaviour {
public int x = 1;
public int y = 1;
void Start()
{
// Get a reference to the Renderer component of the game object.
Renderer rend = GetComponent<Renderer>();
// Scale the texture.
rend.material.mainTextureScale = new Vector2 (x, y);
}
}
The error message was thrown because you tried to call GetComponent on a type of GameObject and not an instance of GameObject. The script itself is already in the context of a GameObject meaning that you can just access a component with GetComponent from a non-static method.
The problem is not with the Rend object, it's caused by the fact that the GetComponent method is non-static. That means you need to instantiate a GameObject object and use that one to call GetComponent.
Change GameObject.GetComponent to gameObject.GetComponent, so that you're referencing the gameObject that this MonoBehaviour script belongs to.
Or you can even not use gameObject.GetComponent and just use GetComponent by itself.
See the MonoBehaviour inherited members for details.

Categories

Resources