public class player_movement : MonoBehaviour
{
// Start is called before the first frame update
public Transform position;
void Start()
{
position = GetComponent<Transform>();
}
how do I acsess the position variable in another script
There is no reason for any of this at all.
Your component player_movement is of type MonoBehaviour which is a Behaviour which is a Component and therefore already has the inherited property transform returning the Transform reference if the GameObject your component is attached to.
So whoever has a reference to your component immediately also has access to its .transform.position anyway.
As to how get that reference, there are thousands of different ways. The most typical ones
public player_movement playerMovement;
simply drag and drop it in vis the Inspector.
On another component attached to the same GameObject use
var playerMovement = GetComponent<player_movement>();
or if there is only one in the scene anyway
var playerMovement = FindObjectOfType<player_movement>();
either way in the end as said you can simply use
var playerTransform = playerMovement.transform;
and do with it whatever you want like accessing its position
var playerPosition = playerTransform.position;
Related
I am trying to create a simple scriptable object for my shoot ability. I have that aspect working, but as I try to set my Transform to my player, it does not update the shoot position. I am very new to C#, and this script isnt complete. I still need to add the functionality to destroy the created objects. Any help would be greatly appreciated. I suspect I need to add an update function but im am not certain how to do this.
using UnityEngine.InputSystem;
using UnityEngine.AI;
using UnityEngine;
namespace EO.ARPGInput
{
[CreateAssetMenu]
public class Shoot : Ability
{
public Transform projectileSpawnPoint;
public GameObject projectilePrefab;
public float bulletSpeed = 10;
public float bulletLife = 3;
public override void Activate(GameObject parent)
{
var projectile = Instantiate(projectilePrefab, projectileSpawnPoint.position, projectileSpawnPoint.rotation);
projectile.GetComponent<Rigidbody>().velocity = projectileSpawnPoint.forward * bulletSpeed;
Destroy(projectile, bulletLife);
void OnCollisionEnter(Collision collision)
{
Destroy(projectile);
}
}
}
}
I'm still new to Unity and coding also, so take my advice with a load of salt :P.
It may be best to have a transform on your character (say just past the barrel of the player's gun) that you can put as the projectileSpawnPoint. In your code the projectileSpawnPoint is never set. Your first line of code in the "Activate" method should be something like:
public override void Activate(GameObject parent)
{
projectileSpawnPoint = playerGunBarrelTransform.transform.position;
var projectile = Instantiate(projectilePrefab, projectileSpawnPoint.position, projectileSpawnPoint.rotation);
projectile.GetComponent<Rigidbody>().velocity = projectileSpawnPoint.forward * bulletSpeed;
Destroy(projectile, bulletLife);
For destroying the projectile afterward you can keep it as you have it in OnCollision. howeer, with bullets in particular, since they tend to be instantiated A LOT and then destroyed afterward it would be best to use an object pooler for them to instantiate several of them on start and then disable and enable them as needed so you can resuse them instead of making new ones every time.
you have to create a new script that derives from Monobehaviour for your projectiles. attach that script to the projectile prefab and place the OnCollisionEnter method in that script. now your projectiles should get destroyed when touching another collider. make sure that there is a rigidbody component attached to the projectile.
I am trying to assign ScriptManager to ObjectManager, and used the line :
ObjectManager = GameObject.Find("ScriptManager");
I have checked multiple times to make sure "ScriptManager" is spelt correct, Ive even tried copy pasting the name straight from Unity.
I recieve this error when running:
"UnassignedReferenceException: The variable ObjectManager of Mining has not been assigned.
You probably need to assign the ObjectManager variable of the Mining script in the inspector.
UnityEngine.GameObject.GetComponent[T] () (at <3be1a7ff939c43f181c0a10b5a0189ac>:0)
Mining.Sell () (at Assets/Mining.cs:49)"
I sadly cant assign the variable straight from the inspector, because the object with the code attached is loaded using a Prefab.
here is the full code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Mining : MonoBehaviour
{
public GameObject ObjectManager;
public Text WorkerCountText;
public float MiningSpeed;
public float WorkersInMine;
public float MiningMultiplyer;
public Collider2D collider;
public GameObject DropDown;
private float WorkerCount;
private float MineWorth;
private float Cash;
// Start is called before the first frame update
void Start()
{
ObjectManager = GameObject.Find("ScriptManager");
collider = GetComponent<Collider2D>();
DropDown.SetActive(false);
}
// Update is called once per frame
void Update()
{
Cash = ObjectManager.GetComponent<GenerateItems>().Money;
WorkerCount = ObjectManager.GetComponent<GenerateItems>().Workers;
MineWorth = ObjectManager.GetComponent<GenerateItems>().MineCost;
WorkerCountText.text = "Workers:" + WorkerCount;
}
public void Sell()
{
ObjectManager.GetComponent<GenerateItems>().Money = Cash + MineWorth;
Object.Destroy (this);
}
}
I would change the way how you assign the ScriptManager to ObjectManager. The function Find() is not very reliable and in case if anything changes in hierarchy or in the name of the GameObject, the function will not find the desired GameObject.
There are multiple ways how you can assign the GameObject to the ObjectManager, including more reliable function FindObjectOfType(), or simply creating variable:
public GameObject objectManager;
and dragging your ObjectManager from the hierarchy into the inspector in the ScriptManager GameObject.
Note: If you want to use any function of the ObjectManager you would need to get that component in the Start function of the ScriptManager.
Try using Object.FindObjectOfType
https://docs.unity3d.com/ScriptReference/Object.FindObjectOfType.html
I have discovered how to fix it!
For anyone wondering, the object this is attacked to is a prefab. And is only loaded once the player purchases the item. Meaning it is not loaded when Start() is executed. Moving the line into Sell() , Add() , and remove assigns it when the buttons are clicked. This fixed the error. Thank you to everyone who tried to help, I am now also using FindGameOBjectWithTag instead of Find to make sure it always works
I use the following script to copy the transform of a gameObject.
public Transform alignment;
void Update()
{
DontDestroyOnLoad(transform.gameObject);
transform.position = new Vector3(alignment.position.x, alignment.position.y, alignment.position.z);
float y = alignment.transform.localRotation.eulerAngles.y;
float x = alignment.transform.localRotation.eulerAngles.x;
float z = alignment.transform.localRotation.eulerAngles.z;
transform.localEulerAngles = new Vector3(x, y, z);
}
I want to acces this transform in other scenes (apply it to gameObjects).
How can I reach the transforms, that are in DontDestroyOnLoad?
First of all, don't use DontDestroyOnLoad in your update function. Use it in your Start or Awake funciton.
Secondly you can access your Non-Destroyed object like you would any other object.
Only differences between the two is that the Non-Destroyed stays in the scene when changing scenes.
Here are some ways to access it:
var obj = GameObject.Find("My Non Destroyed Object Name");
Or my personal favorite, if the object is used for scoring or settings I'll create a new gameobject and add the following script to it:
public class GameManager : MonoDevelop {
/* These are all script on the same gameobject that is not being destroyed */
public static Settings settings;
public static PlayerMananger playerMananger;
public static UIManager uiManager;
void Start() {
DontDestroyOnLoad(this.gameobject);
// Get the components
settings = GetComponent<Settings>();
playerMananger = GetComponent<PlayerMananger>();
uiManager = GetComponent<UIManager>();
}
}
Now I can create a script from anywhere and I can access all these Manager and setting files simply using:
var settings = GameManager.settings;
You need to give alignment as parameter to the DontDestroyOnLoad method, not transform.gameObject.
DontDestroyOnLoad(alignment.gameObject);
Also, you don't need to call this method inside Update(). Just calling it once it enough. You can call it inside Start(), like this:
void Start()
{
DontDestroyOnLoad(alignment.gameObject);
}
Now your alignment gameobject will still be accessible when you change scenes. If you want to access it from other gameobjects in the new scene, you might want to give it a tag or make it a singleton.
please help me how to get the value of "currentPeople.timeCount;"
for example i have a script:
public class BuildingPlacement : MonoBehaviour
{
public GameObject currentPeople;public int DelayTime;private int timeCount;
}
if i want to say that
DelayTime = currentPeople.timeCount;
i try this code below and it says nullreferenceexception object reference not set to an instance of an object:
DelayTime = (BuildingPlacement)currentPeople.GetComponent(typeof(BuildingPlacement).timeCount);
How do I get the value of currentPeople.timeCount ? is it possible?
You can't add a variable to a GameObject as mentioned in your original question. It is very likely you want to add the script to the GameObject which also makes the timeCount variable available to that GameObject.
If that's the case then select the currentPeople GameObject and drag the BuildingPlacement script to it in the Editor. This is called attaching script to a GameObject. You can also do this via code with:
currentPeople.AddComponent<BuildingPlacement>();
To access the timeCount variable that is in the BuildingPlacement script which is attached to the currentPeople GameObject:
int value = currentPeople.GetComponent<BuildingPlacement>().timeCount;
It seems like you are lacking the basic knowledge of Unity. You can start from here.
I'm trying to use C# to disable and enable the MeshRender component in Unity3d however I am getting the following error,
error CS0120: An object reference is required to access non-static member `UnityEngine.GameObject.GetComponent(System.Type)'
The line of code I am using is below. I'm using this in the same function.
MeshRenderer showZone = GameObject.GetComponent<MeshRenderer>();
Also I'm posting here rather than Unity Answers as I get a far faster response here and it's always useful information regardless of the outcome.
You're having trouble with several problems. First, you are trying to use GetComponent<> on a class instead of an instance of an object. This leads directly to your second problem. After searching for a specific GameObject you're not using the result and you're trying to disable the renderer of the GameObject containing the script. Third, C# is case-sensitive, Renderer is a class while renderer is a reference to an instance of Renderer attached to the GameObject
This code snippet combines everything: find the GameObject and disable its renderer
GameObject go = GameObject.FindWithTag("zone1");
if (go != null) { // the result could be null if no matching GameObject is found
go.renderer.enabled = false;
}
You could use go.GetComponent<MeshRenderer>().enabled = false; instead of go.renderer. enabled = false; But by using renderer you don't need to know what kind of renderer is used by the GameObject. It could be a MeshRenderer or a SpriteRenderer for example, renderer always points to the renderer used by the GameObject, if there exists one.
My friend. Just try use lowercase gameObject instead of GameObject and renderer instead of Renderer
The main problem that you try access Static class variable, using the name of class instead of class instance.
Class names here are GameObject and Renderer
And instances are gameObject and renderer
MeshRenderer showZone = GetComponent<MeshRenderer>();
delete the 'GameObject.'
GameObject is a type. What you want is in an instance of a gameObject to call GetcComponent on. Thats what the error is about.
Which for note, this:
MeshRenderer showZone = GetComponent<MeshRenderer>();
is the exact same as this:
MeshRenderer showZone = this.GetComponent<MeshRenderer>();
You are calling GetComponent on the GameObject instance of which the script is attached to.
your code should look like this:
MeshRenderer showZone = GetComponent<MeshRenderer>();
Like others already wrote, you need to get an instantiated GameObject. You call the base class GameObject where only static functions can be called which do not need a GameObject in the SceneView.
gameObject IS AN instance.You get the instance of the GameObject the Monobehaviour is added to. Calling the function GetComponent without any object is the same as:
this
gameObject
GameObject IS NO instance.
Be careful at the first letter!
Look documentation:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void Example() {
renderer.enabled = false;
}
}
Link: http://docs.unity3d.com/ScriptReference/Renderer-enabled.html
Changing of programming languages upper-right.
2 ways you can solve the Problem either. You add the word static to the method that is calling your statement.
ex :
public static GetTheMesh(){}
I do not recommend on doing this cause. If you have other calls inside the method that needs to access Instance, this will cause you trouble.
Second way of fixing it is make a pointer or reference first before getting the component. Or use the GameObject.Find <= which is slow if.
showZone = GameObject.Find("TheGameObjectName").GetComponent<MeshRenderer>();
If you want to disable the renderer on this gameObject then use:
this.GetComponent<Renderer>().enabled = false;
If it's not this gameObject then use:
GameObject.FindGameObjectWithTag("your_tag").GetComponent<Renderer>().enabled = false;
Or you could give the object manually:
public GameObject go;
go.GetComponent<Renderer>().enabled = false;
https://docs.unity3d.com/ScriptReference/Renderer-enabled.html
you can use two types of peace of code for access MeshRenderer enable and disable
1> create GetMeshRenderer script (script name as you want) attached to empty game-object into the scene and assign Cube or sphere or any 3d object as u want to enable and disable.
************************************** Code ***************************
using UnityEngine;
using System.Collections;
public class GetMeshRenderer : MonoBehaviour
{
public MeshRenderer ShowZone;
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if(Input.GetKey(KeyCode.Y))
{
ShowZone.enabled = true;
}
if(Input.GetKey(KeyCode.N))
{
ShowZone.enabled = false;
}
}
}
2>
attach below peace of code script to any 3d object like sphere ,cube
*************************** code ***************************
using UnityEngine;
using System.Collections;
public class GetMeshRenderer : MonoBehaviour
{
private MeshRenderer ShowZone;
// Use this for initialization
void Start ()
{
ShowZone = gameObject.GetComponent<MeshRenderer> ();
}
// Update is called once per frame
void Update ()
{
if(Input.GetKey(KeyCode.Y))
{
ShowZone.enabled = true;
}
if(Input.GetKey(KeyCode.N))
{
ShowZone.enabled = false;
}
}
}
Your problem is that you are using GameObject which is just a class that "describes" what it is. What you want, if this script is attached to the GameObject who's mesh renderer you want, is gameObject with a lowercase "g."
If you want to get the mesh renderer of another GameObject, you can find it by name with GameObject.Find("zone1"); (note the uppercase "G" in that one,) or you can give it a tag and find it with GameObject.FindGameObjectWithTag("zone1");
(You may or may not already know that but it doesn't hurt to provide the information.)
Edit:
Your other problem is that you must use renderer instead of Renderer because, like the GameObject "Renderer" with a capital "R" references a class, instead of a specific object.
the problem is GameObject is different from gameobject Gameobject is a class and gameobject is a instance of current gameobject or gameobject in which the script is attached
Replace the line
MeshRenderer showZone = GameObject.GetComponent<MeshRenderer>();
with
MeshRenderer showZone = gameobject.GetComponent<MeshRenderer>();
I think this will do,
Also note that in your Error statement ,it is saying that GameObject is a Class or a data type not an object
Do you see the gears? Yes? Click it and click remove component.
You can use the declaration:
other.gameobject.GetComponent< MeshRenderer>().Setactive (false);
One Line Reference...after the condition is fulfilled..
For more precise help regarding MeshRender, see the Unity Documentations..
I had same issue with my declaration and i just fixed it by changing "G" to "g" in gameObject and i declared it in Start so it is like...
MeshRenderer showZone = gameObject.GetComponent();