transform.position not working properly in Unity - c#

I am making a game in unity and i want to get the position of the player ( witch is a prefab ) so i use the code for the enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyScript : MonoBehaviour
{
public Transform player;
void Start()
{
Debug.Log(player.position.x);
}
}
I have a spawner and here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnEnemies : MonoBehaviour
{
public GameObject enemy;
float randX;
float randY;
Vector2 whereToSpawn;
public float spawnRate = 2f;
float nextSpawn = 0.0f;
void Update()
{
if (Time.time > nextSpawn)
{
nextSpawn = Time.time + spawnRate;
randX = Random.Range(-6.36f, 6.36f);
randY = Random.Range(-4.99f, 4.99f);
whereToSpawn = new Vector2(randX, randY);
Instantiate (enemy, whereToSpawn, Quaternion.identity);
}
}
}
But when i run it, it always gives me (0, 0, 0). Why do i get 0 and how can i fix it ( get the current position of the player )?

Try with
Vector3 position = transform.position;
debug.log(position.x);
you can see more here Transform.position

You Debug.Log() the transform.position only once at the very start when the scene is loaded. Is it possible your object always starts there at 0,0,0 and then moves? If this is the case you are printing it's start position but never updating it. Try printing it on a key press of just every frame by putting it in Update(){}.
If that doesn't work, perhaps your object is nested within another? If so could help narrow down your issue by debug logging both transform.position and transform.localPosition?

Related

GameObject reflecting off another gameObject error

I am new at Unity/c# and I wanted to make a pong game. I made this by watching a tutorial on youtube. There is no "error" except the ball doesn't move after touching the player.
This is ball code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallCode : MonoBehaviour
{
private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Vector2 position = transform.position;
position.x = position.x - 5.8f * Time.deltaTime;
transform.position = position;
}
}
This is ball bounce code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallBounce : MonoBehaviour
{
private Rigidbody2D rb;
Vector3 lastVelocity;
// Start is called before the first frame update
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
lastVelocity = rb.velocity;
}
private void OnCollisionEnter2D(Collision2D coll)
{
var speed = lastVelocity.magnitude;
var direction = Vector3.Reflect(lastVelocity.normalized, coll.contacts[0].normal);
}
}
And this is player code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float moveSpeed = 4.5f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float vertical = Input.GetAxis("Vertical");
Vector2 position = transform.position;
position.y = position.y + moveSpeed * vertical * Time.deltaTime;
transform.position = position;
}
}
When I play the game the ball will collide with player, but it won't ricochet.
Your OnCollisionEnter2D method is not doing anything except set local variables that are quickly discarded. You need to make speed and direction variables of the BallCode or BallBounce class, then set up the BallCode class to use those variables in Update() when determining the motions it makes.
You can try adding a 2D rigid body property to the sphere and removing gravity.
Add a C# script to control the movement of the ball and add a 2D collider to the ball.
//Initial velocity
public float speed = 100f;
void Start()
{
this.GetComponent<Rigidbody2D>().AddForce
(Vector2.right * speed);
}
Add a 2D collider:
Add a 2D physical material to the sphere, so that the ball can bounce.
Modify 2D Physical Material Properties.
Added to the sphere's material.
Add player (Square) and control player movement script.
void Update()
{
// The mouse moves with the player
float y = Camer.main.ScreenToWorldPoint
(Input.mousePosition).y
this.transform.position = new Vector3
(transform.position.x,y,0);
}
Add the wall around the screen and the script Wall to control the randomness of the vertical speed and the direction of the ball when the ball collides with the wall.
public class Wall : MonoBehaviour
{
//Initial velocity
public float speed = 100f;
// Triggered when the collision ends
private void OnCollisionExit(Collision2D collision)
{
int r = 1;
if(Random.Range(0, 2) != -1)
{
r *= -1;
}
//add a vertical force
collision.gameObject.GetComponent<Rigidbody2D>().
AddForce(Vector2.up.*speed*r);
}
}
achieve effect:

Moving Maincamera slowly to another position

I want to move main camera slowly from one point to another point when a button is pressed. This button calls the method which has the code to move the camera.
I have tried using the Lerp method but the camera position is changing so fast that when I click on the button camera directly shifting to a new position. I want the camera to move slowly to a new position.
Below is my code, can anyone please help me with this.
=========================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cameramove : MonoBehaviour
{
public GameObject cam;
Vector3 moveToPosition;// This is where the camera will move after the start
float speed = 2f; // this is the speed at which the camera moves
public void move()
{
//Assigning new position to moveTOPosition
moveToPosition = new Vector3(200f, 400f, -220f);
float step = speed * Time.deltaTime;
cam.transform.position = Vector3.Lerp(cam.transform.position, moveToPosition, step);
cam.transform.position = moveToPosition;
}
}
It's easier to use lerp with frames and you need to use it in an Update function. Try using the example from the Unity docs:
public int interpolationFramesCount = 45; // Number of frames to completely interpolate between the 2 positions
int elapsedFrames = 0;
void Update()
{
float interpolationRatio = (float)elapsedFrames / interpolationFramesCount;
Vector3 interpolatedPosition = Vector3.Lerp(Vector3.up, Vector3.forward, interpolationRatio);
elapsedFrames = (elapsedFrames + 1) % (interpolationFramesCount + 1); // reset elapsedFrames to zero after it reached (interpolationFramesCount + 1)
Debug.DrawLine(Vector3.zero, Vector3.up, Color.green);
Debug.DrawLine(Vector3.zero, Vector3.forward, Color.blue);
Debug.DrawLine(Vector3.zero, interpolatedPosition, Color.yellow);
}
Try using smooth damp.
Here is the new code you should try:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cameramove : MonoBehaviour
{
Vector3 matric;
public GameObject cam;
Vector3 moveToPosition;
float speed = 2f;
bool move_ = false;
void Update(){
if(move_){
//Assigning new position to moveTOPosition
moveToPosition = new Vector3(200f, 400f, -220f);
cam.transform.position =
Vector3.SmoothDamp(cam.transform.position,
moveToPosition,
ref matric, speed);
}
}
public void move()
{
move_ = true;
}
}

2D - Firepoint not rotating consistently to aim at mouse

Followed brackeys tutorial for topdown shooter firing and although its working e.g the firepoint is rotating so it points towards the mouse its not happening consistently meaning it will stay pointed at a single spot for a few seconds before jumping towards the new spot. This delay before jumping to the new spot seems to be increased if i fire. Thanks in advance and sorry if this is a basic mistake as im new to C#
This is the Code i'm using to aim the firepoint.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirepointAim : MonoBehaviour
{
public Rigidbody2D rb;
public Camera cam;
Vector2 mousePos;
// Update is called once per frame 8
void Update(){
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
}
void FixedUpdate(){
Vector2 lookDir = mousePos - rb.position;
float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90;
rb.rotation = angle;
}
}
And this is the code im using to fire.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
public Transform firepoint;
public GameObject fireballPrefab;
public Rigidbody2D playerrb;
public float velocity = 20f;
public float push = 2f;
void Update(){
if(Input.GetButtonDown("Fire1"))
{
shoot();
}
}
void shoot()
{
GameObject shot = Instantiate(fireballPrefab, firepoint.position, firepoint.rotation);
Rigidbody2D rb = shot.GetComponent<Rigidbody2D>();
rb.AddForce(firepoint.up * velocity, ForceMode2D.Impulse);
playerrb.AddForce(firepoint.up * push * -1, ForceMode2D.Impulse);
}
}

Unassigned variable in Unity

I've just started learning Unity 2D with the "How to make a 2D game" course from Brackeys on YouTube about 3 hrs ago. I'm using Unity 2018.4.1f1 on Ubuntu 18.04, and because JS is not supported in my version so I have to use C# instead. But I've encountered this error on the third video: The variable mainCam of GameSetup has not been assigned. This is my code in C#:
GameSetup.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameSetup : MonoBehaviour
{
public Camera mainCam;
public BoxCollider2D topWall, bottomWall, leftWall, rightWall;
public Transform Player1, Player2;
// Start is called before the first frame update
void Start()
{
// topWall = GetComponent<BoxCollider2D>();
// mainCam = GetComponent<Camera>();
// If I uncomment this, there would be a new error: There is no 'Camera' attached to '_GM' game object, but a script is trying to access it.
}
// Update is called once per frame
void Update()
{
// Move each wall to its edge location
topWall.size = new Vector2(mainCam.ScreenToWorldPoint(new Vector3(Screen.width * 2.0f, 0f)).x, 1.0f);
topWall.offset = new Vector2(0f, mainCam.ScreenToWorldPoint(new Vector3(0f, Screen.width, 0f)).y + 0.5f);
}
}
With the help of Google, I've add rb2d.GetComponent<Rigibody2D>() in Start() from the script of the second video under and prevent the error (there are no Start() in the video)
PlayerControls.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
public KeyCode moveUp, moveDown;
public float speed = 10;
private Rigidbody2D rb2d = new Rigidbody2D();
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(moveUp))
{
Vector3 v = rb2d.velocity;
v.y = speed;
rb2d.velocity = v;
// rb2d.velocity.y = speed;
}
else if (Input.GetKey(moveDown))
{
Vector3 v = rb2d.velocity;
v.y = speed * (-1);
rb2d.velocity = v;
}
else
{
Vector3 v = rb2d.velocity;
v.y = 0;
rb2d.velocity = v;
}
}
}
How can I fix the bug in GameSetup.cs ? I've done exactly what said in the video, but only changed the language from JS to C#
Either assign it null:
public Camera mainCam = null;
But you are most likely missing to attach a camera object to it in the Unity3D editor. Check your inspector and make sure that whatever object that is using this script(GameSetup.cs) has a camera object assigned to its public variable.
Should look something like this. You have to drag and drop a camera object to the Gameobject.

Unity: How to make a sprite move using Vector3.Lerp() without StartCoroutine

I want to move a sprite using Vector3.Lerp() without StartCoroutine.
Starting and target points want to set in the script.
I drag & drop the sprite into the Unity Editor and run it.
However, the sprite doesn't move. Thanks.
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class MyScript1 : MonoBehaviour {
public Sprite sprite;
GameObject gameObject;
SpriteRenderer spriteRenderer;
Vector3 startPosition;
Vector3 targetPosition;
void Awake()
{
gameObject = new GameObject();
spriteRenderer = gameObject.AddComponent<SpriteRenderer>();
}
private void Start()
{
spriteRenderer.sprite = sprite;
startPosition = new Vector3(-300, 100, 0);
targetPosition = new Vector3(100, 100, 0);
}
void Update()
{
transform.position = Vector3.Lerp(startPosition, targetPosition , Time.deltaTime*2f);
}
}
Actually it does move but just a little and only once.
The problem is in lerp method itself: Passing Time.deltaTime*2f as the third parameter is wrong.
The third parameter of lerp method decides a point between startPosition and targetPosition and it should be between 0 and 1. it returns startPosition if 0 is passed and in your case it returns a point very very close to startPosition since you passed a very small number compared to the range (0..1)
I suggest you read the unity docs about this method
Something like this will work:
void Update()
{
t += Time.deltaTime*2f;
transform.position = Vector3.Lerp(startPosition, targetPosition , t);
}

Categories