I'm totally newbie with Unity and C# and i try to do a 3D game.
I want to when i press "Qkey", the cube descends in height.
here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ripcube : MonoBehaviour
{
// Start is called before the first frame update
bool isTeleported = false;
// Update is called once per frame
void Update()
{
if (Input.GetKey("a") && !isTeleported)
{
ripcube.transform.position = (-2, -2, -2) ;
}
}
}
And it gives me the error:
(19,13): error CS0120: An object reference is required for the non-static field, method, or property 'Component.transform'
I know than ripcube is my class, but what is my gameobject? i created my cube on the graphics interface..
Thanks for your help
You should go watch some basic videos on youtube on how unity gameobjects work but for now:
You can reference game objects from your code or find them as following:
public class ripcube: MonoBehaviour
{
GameObject myCubeObject;
float speed = 2f;
void Start()
{
myCubeObject = GameObject.Find("YourCubeNameInUnity");
}
void Update()
{
if(Input.GetKey(KeyCode.Q))
{
myCubeObject.transform.Translate(speed * Vector3.down * Time.deltaTime);
}
}
}
Thing you should notice here :
The GameObject is a Unity class that is the base for all the game objects in the scene,
you can find it by its name in the Hierarchy view.
After you find it you can access it in the Update() function and change its transform every frame.
Here I used Translate wich is an addition to the position every frame
you can also use myCubeObject.transform.position += speed * Vector3.down * Time.deltaTime
Be aware that im using a float speed variable that is the speed the cube will go in the desired direction (I used 2 for the value but it can be anything really).
The direction is specified by a vector (Vector3.down). You can change is as you please
Multiplying by Time.deltaTime makes the movement independant on FPS (Frames per second) wich is determined normally bt the machine the game is running on.
bro you can use
transform.position = new Vector3(-2, -2, -2);
instead of
transform.position = (-2, -2, -2) ;
and change
Input.GetKey("a")
to
Input.GetKey(KeyCode.Q)
Related
I am trying to get my Spawner.cs script to work in Unity on a flappy bird game I am making. I am following this tutorial.
For some reason only one set of pipes will cross the screen and none others appear. I am a beginner and appreciate any help in this matter. Here is the code for the Spawner.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spawner : MonoBehaviour
{
public float queueTime = 1.5f;
private float time = 0;
public GameObject ObstaclePipes;
public float height;
void Start () {
GameObject newpipe = Instantiate(ObstaclePipes);
newpipe.transform.position = transform.position + new Vector3(0, Random.Range(-height, height), 0);
}
// Update is called once per frame
void Update()
{
if(time > queueTime)
{
GameObject go = Instantiate(ObstaclePipes);
go.transform.position = transform.position + new Vector3(0, Random.Range(-height, height), 0);
time = 0;
Destroy(go, 10);
}
time += Time.deltaTime;
}
}
Here is the code for the obstacles.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class obstacles : MonoBehaviour
{
// Start is called before the first frame update
public float speed;
// Update is called once per frame
void Update()
{
transform.position += ((Vector3.left * speed) * Time.deltaTime);
}
}
Given that the obstacles are spawning and not visible on the screen, the obstacle sprite renderers are rendered behind the background. This behavior is common when working with 2D games. To solve this, we have to use sorting layers.
Sorting layer allows us to set the render order of sprites. In your case, we have to set the order of sorting layer for your obstacles so that they spawn in front of the background instead of behind it.
Hence in the sprite renderer component of the obstacle, set its Order In Layer to a value more than 0 as 0 is the default value which was the same for both background and obstacle. In our case, let's set it to 1. Now, the obstacles are rendered first, and then the background which lets us see the obstacles on the screen.
I've followed a C# in Unity tutorial to create a simple Space Invaders game. I'm now trying to understand the different functions being used.
There is this class called PlayerController. It also defines a shot gameobject, a field which is then supplied with a bullet prefab:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Transform player;
public float speed;
public float maxBound, minBound;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
// Start is called before the first frame update
void Start()
{
player = GetComponent<Transform> ();
}
// Update is called once per frame
void FixedUpdate()
{
float h = Input.GetAxis ("Horizontal");
if (player.position.x < minBound && h < 0)
h = 0;
else if (player.position.x > maxBound && h > 0)
h = 0;
player.position += Vector3.right * h * speed;
}
void Update()
{
if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
}
}
The bullet gameobject used the class BulletController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletController : MonoBehaviour
{
private Transform bullet;
public float speed;
// Start is called before the first frame update
void Start()
{
bullet = GetComponent<Transform>();
}
void FixedUpdate()
{
bullet.position += Vector3.up * speed;
if (bullet.position.y >= 10)
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Enemy")
{
Destroy(other.gameObject);
Destroy(gameObject);
PlayerScore.playerScore++;
}
else if (other.tag == "Base")
Destroy(gameObject);
}
}
From what I understand, a Transform object has values for position, rotation and scale.
So first, what does declaring x = GetComponent; do?
Second, where does "shotSpawn" takes its values from? From the object to which the code is applied to?
Third, the bullet gets instantiated exactly at the center of the square serving as the player ship's body, but I want it start higher at the y axis so it starts at the end of the cannon shape. It also seems to graphically intersect with the ship's body, so I wanted to move it slightly into the z axis. So how can you write that? I tried adding to the value of shotSpawn.position but it keeps declaring errors.
Thanks in advance.
A GetComponent means basically just grabbing a component of an object. Take a simple example: The Main Camera has a lot of components:
1.1. A Transform component. This component is used, as you understood, to define the position, rotation and scaling of an object
1.2. A Camera component. This has plenty of fields
1.3. A Flare Layer component.
etc.
These components can be grabbed via script. The reason developers use this is for their properties. For example, by saying Transform playerTransformComp = player.GetComponent<Transform>();, you will be able to write playerTransformComp.position. position is a property of objects of type Transform.
I don't think that the GetComponent you saw in the tutorial are useful because every game object has a transform component anyway, so if they declared the player as public GameObject player;, then used player.transform.position instead, it would have been way easier. In fact, I don't think it even makes sense to declare something as Transform, and then grabbing the Transform component. As #BugFinder said in your previous post, the tutorial is pretty bad overall.
shotSpawn takes its values from... itself! It is a public object, so I'm assuming you dragged & dropped the shotSpawn object from the scene into the script's fields. This means that the shotSpawn object from the script is the object you dragged & dropped on the script's fields. You can use all of its features and the dragged & dropped object will be affected. Thus, you can use shotSpawn.position and shotSpawn.rotation. I might be repeating myself here for a little bit, but please notice that shotSpawn is a Transform object, therefore you can use a typical Transform object's properties.
The documentation on Transform.position (as well as the one on Transform.rotation say you have to use Vector3 objects to add or substract values to them.
One would do shotSpawn.position + new Vector3(10f, 5f, 10f).
Naturally, you can also do
value = new Vector3(10f, 5f, 10f);
and then Instantiate(shot, shotSpawn.position + value, shotSpawn.rotation);
Also, please (for the future), try to ask one question per post, otherwise people will ignore your question or even flag it and it will be deleted. I was once like you, so I wouldn't do that, but please take this into consideration when making further posts.
I am having this problem that I don't know how to solve, I have a moving object that return to a position if a condition is verified, but it seems like it is working sometimes, but sometimes it is not ..
Here is my script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingDes : MonoBehaviour {
private float speed = 5f;
Transform trn;
//-37.6914
//62.32123
// Use this for initialization
void Start() {
trn = GetComponent<Transform>();
}
// Update is called once per frame
void Update() {
transform.Translate(Vector3.back * (speed * Time.deltaTime));
if(transform.position.z <= -37.6914){
Vector3 newPosition = new Vector3(17.5f,125.7f,165.32123f);
trn.position = newPosition;
}
}
}
The problem is that I can see in my Unity editor that the position is different from what I have set, and I don't understand from Where those values came from, I did not write them for sure.
Any help would be much appreciated.
You are moving object with transform.Translate every frame, so immediately after setting up new position, your object is moved again. Notice that in your case trn, and transform, refers to the same Transform component.
Why don't you change your trn.position= to transform.position= I don't think you need GetComponent<> for transform component of the current gameObject. Or maybe related to relativeTo parameter of .Translate method.
In short, I have a very simple multiplayer game. It's the Roll A Ball game (Unity3D tutorial). So right now I have the players etc spawning perfectly and everyone is able to control their own balls perfectly fine.
But here's the problem: I've got a default Main Camera. Since it's only the local player itself that needs to see it, I figured there's no point in trying to spawn a seperate camera for each player on the server.
However, to make the camera follow the player, I need to attach it the player gameobject. Obviously I can't attach it to the player prefab as it's a clone the camera needs to follow. But since the player is being spawned by the Network Manager component, I have no idea on how to refer to this clone.
What I've tried myself:
public class CameraController : NetworkManager
{
public GameObject playerPrefab;
public Transform target;
private Vector3 offset;
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
GameObject player = (GameObject)Instantiate(playerPrefab, new Vector3(0, 0.5f, 0), Quaternion.identity);
target = player.transform;
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
}
void Start()
{
offset = transform.position - target.position;
}
void LateUpdate()
{
transform.position = transform.position + offset;
}
}
But this resulted in:
Which I find extremely odd since as you can clearly see, there's no NetworkIdentity component on the NetworkManager object. I've been trying A LOT of things for the past 4 hours now and I just can't do it. So now I'm hoping you guys can help me out.
Edit: This is how the Network Manager normally spawns a player. As you can see, there's no code for it:
I had the same issue and figured out the followig solution. Seems like you already got a solution, but maybe it is interesting to share some possible ways for other people in the same situation.
This is a way to do it without a camera attached to the prefabs.
I'm using a NetworkManager to instantiate Player-prefabs. (Same as you)
I solved the problem of finding references to the clone objects by letting the clones tell the camera, who they are (or which transform belongs to them).
The Player has the following script:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class PlayerController : NetworkBehaviour {
public override void OnStartLocalPlayer()
{
GetComponent<MeshRenderer>().material.color = Color.blue;
Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
}
void Update ()
{
if (!isLocalPlayer)
{
return;
}
var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
var z = Input.GetAxis ("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate (0, x, 0);
transform.Translate (0,0,z);
}
}
On my default main Camera (there is no camera attached to the player prefab, just the default camera) I put the following script on. It takes a target which I initialised with the prefab using the inspector.
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Transform target; //what to follow
public float smoothing = 5f; //camera speed
Vector3 offset;
void Start()
{
offset = transform.position - target.position;
}
void FixedUpdate()
{
Vector3 targetCamPos = target.position + offset;
transform.position = Vector3.Lerp (transform.position, targetCamPos,smoothing * Time.deltaTime);
}
}
After starting the game, each clone tells the camera who he is, so the target changes to the individual clients clone with this line from the Player's Script:
Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
This way you don't need to create one camera per instance of player-prefabs (I'm not sure if this makes big differences in performance) and you don't have to deactivate all cameras which don't belong to your client.
If you host the game in the editor you can see that there is just 1 camera instead of one camera per connected client (like when you attach it to the prefab).
I think this is a good use of this method, you can use it to put things in it, which should be applied to the Local Player only.
public override void OnStartLocalPlayer()
{
}
I tried by starting the game in the editor and in a build and it seems to work well.
I would add a camera to the prefab and then write a player script like this:
using UnityEngine.Networking;
public class Player : NetworkBehaviour
{
public Camera camera;
void Awake()
{
if(!isLocalPlayer)
{
camera.enabled = false;
}
}
}
I've not really worked with networking but what if you do this after you spawn the local player
Camera.main.transfor.SetParent(the transform of the local player here);
As I understand the problem each separate instance of the game has a main camera.
Thanks to Rafiwui's point into the right direction, I've finally managed to get it working. All I had to do was adept his code a bit. The end result was:
public Camera camera;
void Awake()
{
camera.enabled = false;
}
public override void OnStartLocalPlayer()
{
camera.enabled = true;
}
Thanks A LOT to you all for helping me out! This has been quite a day for me.
I'm attempting to learn Unity (so please forgive my newbie-ness). I've set up my project as 2d, got a sprite moving about and I'm trying to get a projectile firing (I appreciate there are MANY SO q's about such, but I just can't get it to work, after trying many solutions). I'm a complete nub when it comes to physics!
Here's my very simple script:
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour {
public Transform mObject;
public Transform mProjectile;
public Vector2 mProjectileSpeed = new Vector2 (10f, 10f);
public Vector2 mSpeed = new Vector2(15, 15);
private Vector2 mMovement;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float inputX = Input.GetAxis("X");
float inputY = Input.GetAxis("Y");
mMovement = new Vector2 (mSpeed.x * inputX, mSpeed.y * inputY);
if (Input.GetButton ("Fire1"))
Shoot ();
}
void Shoot(){
GameObject clone = (GameObject)Instantiate (mProjectile, rigidbody2D.transform.position, Quaternion.identity);
clone.rigidbody2D.velocity = (clone.transform.forward * 1000);
}
void FixedUpdate(){
rigidbody2D.velocity = mMovement;
}
}
And this is what it's doing:
No force is being added to the instantiated object and it shoots out both sides of my sprite, which I just don't understand at all.
I did find a solution on the Unity answers site that said to IgnoreCollider just in case the two box colliders were conflicting results, but it didn't make a difference.
I'm sure I'm doing something completely stupid, but how can I do this?
Many thanks!
Try using Addforce() method,
something like this :
gameObj.rigidbody2D.AddForce(Vector3.up * 10 * Time.deltaTime);
or
gameObj.rigidbody2D.AddForce(transform.forward * 100);
or
gameObj.rigidbody2D.AddForce(Vector3.up * 1000);
See which combination and what values matches your requirement and use accordingly. Hope it helps
As #maZZZu said, Instantiate your projectile sprites ahead of your character so that your character and projectiles may not collide.
Secondly, clone.rigidbody2D.velocity = (clone.transform.forward * 1000); part of your code will only allow the projectile to move in forward direction (x-axis in case to 2D and z-axis in 3D). Try using mMovement instead (if you want it to move in other directions as well). e.g. clone.rigidbody2D.velocity = (mMovement * 1000);