Sprite object disappears from the game tab after repositioning with script - c#

I'm new to Unity so this can be an amateur mistake.
I'm trying to create a simple game that moves a simple sprite circle to a random position upon receiving touch input.
the program works well in Scene tab, but the circle fully disappears in game tab and the connected remote device after receiving touch input.
Here's the script I have connected to my sprite circle Object :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
private Touch theTouch;
private Camera cam;
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
}
// Update is called once per frame
void Update()
{
if (Input.touchCount > 0)
{
theTouch = Input.GetTouch(0);
if (theTouch.phase == TouchPhase.Ended)
{
MoveToRandomePosition();
}
}
}
// Random Movement
void MoveToRandomePosition()
{
var position = cam.ScreenToWorldPoint(new Vector2(Random.Range(0, Screen.width), Random.Range(0, Screen.height)));
transform.position = position;
}
}

You may wanna check the Z coord of your camera and circle. If you're spawning it behind the camera, it wont render.
You could do something like position.z = 0 if your cam pos is at the default -10.

Related

Show UI in front of player Unity VR

I am trying to show a UI always in front of the player, and facing it, in a Unity3D VR project. I am using Unity 2021.3.5f1.
I have a simple UI: a Canvas, with a Panel and two TextMeshPro inside it. The Canvas is child of an empty GameObject, with a script in it that manages the UI. The hierarchy is as follows:
My aim is to always show the UI in front of the player, facing the player itself. For this reason I wrote this script:
using UnityEngine;
namespace UI
{
public class KpPanelManager : MonoBehaviour
{
[SerializeField] private Transform playerHead;
[SerializeField] private float spawnDistance = 2f;
[SerializeField] private float yOffset = 0f;
[SerializeField] private GameObject panel;
private Vector3 _playerHeadForward;
private void Awake()
{
_playerHeadForward = playerHead.forward;
}
private void Update()
{
// show the panel in front of the player
var position = playerHead.position;
panel.transform.position = position + new Vector3(_playerHeadForward.x, yOffset, _playerHeadForward.z).normalized * spawnDistance;
// rotate the panel to face the player frame by frame
panel.transform.LookAt(new Vector3(position.x, panel.transform.position.y, position.z));
panel.transform.forward *= -1;
}
}
}
However, it does not work properly: it is correctly in front of the player, but it does not follow the player's camera itself when it moves. In the Unity editor I am referencing the Canvas that contains my UI as the panel GameObject in script, and the MainCamera of the XROrigin as the playerHead Transform in the script.
Can anyone help me?
You could use Transform's TransformPoint() to covert position from local to world space
Something like following would work for your case
Vector3 offset = new Vector3(0,0,2); // 2 units in front of camera
panel.transform.position = playerHead.TransformPoint(offset);

Struggling to create a trajectory prediction in Unity with 2D physics simulation

I have a 2D brick breaker style game in Unity where you get to choose the angle of your shot before each turn with the mouse. I'd like to show an accurate trajectory prediction of what a ball will do while the player is aiming, up to maybe 200 frames of ball movement (for now). This involves potentially bouncing off the top, left, and right walls, and any bricks.
I'm using a physics simulation and line renderer to accomplish this but can't get it to work correctly.
It's supposed to copy the gun, walls, and bricks into a virtual Scene, launch a ball in the angle the player is aiming, simulate 200 frames of movement, and plot those in a line renderer.
Here is an abridged version of the game code, reduced to just focus on the aiming and physics simulation for the 1st turn. When I run it, it simply plots the 200 points of the line renderer in the same coordinates as the gun.
What am I doing wrong? Thank you!
using UnityEngine;
using UnityEngine.SceneManagement;
public class Aim3 : MonoBehaviour
{
private Vector3 gunPosScreenV3, aimPointScreenV3,
aimPointWorldV3, aimDirectionV3;
private Vector2 ballDirection, ballVelocity;
[SerializeField] private GameObject gun, walls, bricks;
Camera cam;
LineRenderer lr;
// For Physics Scene
private int maxPhysicsFrameIterations = 200;
private Scene simulationScene;
private PhysicsScene2D physicsScene;
[SerializeField] private GameObject ballPrefab;
private GameObject ghostObj;
void Start()
{
lr = GetComponent<LineRenderer>();
lr.enabled = true;
cam = Camera.main;
CreatePhysicsScene();
}
void Update()
{
DrawTrajectory();
}
// This is run once to create a duplicate of the game board for the physics simulation
private void CreatePhysicsScene()
{
simulationScene = SceneManager.CreateScene("Simulation", new CreateSceneParameters(LocalPhysicsMode.Physics2D));
physicsScene = simulationScene.GetPhysicsScene2D();
// Copy the gun to the simulated scene
ghostObj = Instantiate(gun.gameObject, gun.transform.position, gun.transform.rotation);
ghostObj.GetComponent<SpriteRenderer>().enabled = false;
SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
// Copy all the bricks to the simulated scene. These are stored under a parent Game Object that
// is attached in the editor
foreach (Transform obj in bricks.transform)
{
ghostObj = Instantiate(obj.gameObject, obj.position, obj.rotation);
ghostObj.GetComponent<SpriteRenderer>().enabled = false;
SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
}
// Copy the top, left, and right walls to the simulated scene. These are invisible and don't have sprites.
// These are stored under a parent Game Object that is attached in the editor
foreach (Transform obj in walls.transform)
{
ghostObj = Instantiate(obj.gameObject, obj.position, obj.rotation);
SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
}
} // CreatePhysicsScene
private void DrawTrajectory()
{
// Get the starting Screen position of the gun from the World position
gunPosScreenV3 = cam.WorldToScreenPoint(gun.transform.position);
gunPosScreenV3.z = 1;
// Get position of mouse in screen units
aimPointScreenV3 = Input.mousePosition;
// Get the position of the mouse in world units for aiming
aimPointWorldV3 = cam.ScreenToWorldPoint(aimPointScreenV3);
aimPointWorldV3.z = 1;
// Calculate the normalized direction of the aim point compared to the gun
aimDirectionV3 = (aimPointScreenV3 - gunPosScreenV3).normalized;
Physics2D.simulationMode = SimulationMode2D.Script;
// Instantiate the ball prefab for the simulation
ghostObj = Instantiate(ballPrefab, gun.transform.position, Quaternion.identity);
// Assign the ball's velocity
ballDirection = new Vector2(aimDirectionV3.x, aimDirectionV3.y);
ballVelocity = ballDirection * 20f;
ghostObj.GetComponent<Rigidbody2D>().velocity = ballVelocity;
SceneManager.MoveGameObjectToScene(ghostObj.gameObject, simulationScene);
lr.positionCount = maxPhysicsFrameIterations;
for (var i = 0; i < maxPhysicsFrameIterations; i++)
{
physicsScene.Simulate(Time.fixedDeltaTime);
//Physics2D.Simulate(Time.fixedDeltaTime);
lr.SetPosition(i, ghostObj.transform.position);
}
Destroy(ghostObj);
Physics2D.simulationMode = SimulationMode2D.Update;
} // DrawTrajectory
}
You use aimPointScreenV3 but it appears to never be initialized/calculated.
Found the answer. Just needed to add the velocity to the ball after moving it to the simulated scene.
SceneManager.MoveGameObjectToScene(ghostObj.gameObject, simulationScene);
ghostObj.GetComponent<Rigidbody2D>().velocity = ballVelocity;

How to make Camera follow only the horizontal movement (x axis) of the player?

I am a super newbie in Unity and am learning by making my first game. I want the camera to follow the player, but only in the X axis. I had earlier made the camera a child of the player, but that didn't work as I wanted. So I whipped up a C# script to follow the player, as given below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cameraFollow : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position = new Vector3(GameObject.Find("robot_body").transform.position.x, 0f, 0f);
}
}
However, this is showing only the blue background when run. Am I doing something wrong?
By setting your z position to 0 your camera probably ends up to close to everything in order to render it.
Try to not overwrite y and z with 0 but rather keep the current values:
// If possible rather already reference this via the Inspector!
[SerializeField] private GameObject robot;
private void Start()
{
// As fallback get it only ONCE
if(!robot) robot = GameObject.Find("robot_body");
}
void Update()
{
// get the current position
var position = transform.position;
// overwrite only the X component
position.x = robot.transform.position.x;
// assign the new position back
transform.position = position;
}

UNITY PREFABS DOESN'T SHOW UP IN GAME TAB

As you can see in the screenshoot I can't see prefabs in the game tab but only in the editor. I have made a simple function for shooting(not finished yet), it works fine, it spawns the prefabs but i can't see them in the game tab, I have already tried changing the Sorting Layer, move the camera, change Z position but nothing appen.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttack : MonoBehaviour
{
[SerializeField]
float delayBetweenShots = 0.4f;
float timePassedSinceLast = 0f;
// Start is called before the first frame update
void Start()
{
timePassedSinceLast = delayBetweenShots;
}
// Update is called once per frame
void Update()
{
Aiming();
Shooting();
}
void Aiming()
{
var objectPos = Camera.main.WorldToScreenPoint(transform.position);
var dir = Input.mousePosition - objectPos;
transform.rotation = Quaternion.Euler(new Vector3(0,0,Mathf.Atan2(-dir.x, dir.y) * Mathf.Rad2Deg));
}
void Shooting()
{
if(Input.GetMouseButton(0) && timePassedSinceLast >= delayBetweenShots)
{
GameObject bullet = (GameObject)Instantiate(Resources.Load("bullet"), transform.position, transform.rotation);
timePassedSinceLast = 0f;
}
else
{
timePassedSinceLast += Time.deltaTime;
}
}
}
The prefabs get instantiated correctly. As others suggested as well, the best way to find "lost" objects in your game is to shoot some stuff, pause the game, go into scene view, turn on 3D mode and double click one of the prefabs in the hierarchy. The camera will take you straight to your object.

raycast not responding past a certain angle

I have made a game using the unity asset First Person Controller to allow player movement and for them to look around. I have put a cross hair in where a ray cast shoots through and instantiates a bullet. There are no problems with the bullet fire above a certain angle. The bullets follow the cross hair and shoot right in the center but if I look down too far then they no longer shoot where the cross hair is and instead just shoot straight out of the camera.
I think that the capsule that the first person controller makes may be the problem as I cannot find anything in my code.
LINK TO VIDEO: https://youtu.be/zf2EuL7e_i4
Bullet Listener.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletListener : MonoBehaviour {
public Camera mainCamera;
public BulletContoller bulletPrefab;
public GameObject cursor;
private Vector3 cursorPosition;
void Update () {
if (Input.GetMouseButtonDown (0)) {
cursorPosition = cursor.transform.position;
//create ray from camera to mousePosition
Ray ray = mainCamera.ScreenPointToRay (cursorPosition);
//Create bullet from the prefab
BulletContoller newBullet = Instantiate (bulletPrefab.gameObject).GetComponent<BulletContoller> ();
//Make the new bullet start at camera
newBullet.transform.position = mainCamera.transform.position;
//set bullet direction
newBullet.SetDirection (ray.direction);
//Create Bullet Sound
AudioSource audio = GetComponent<AudioSource>();
audio.Play ();
}
}
}
Bullet Controller.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletContoller : MonoBehaviour {
Rigidbody rb;
public float bulletForce;
bool firstTime = false;
Vector3 direction;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody> ();
}
public void SetDirection (Vector3 dir) {
direction = dir;
firstTime = true;
}
void OnCollisionEnter (Collision col) {
//code for when bullet hits something
if (col.gameObject.name == "Target") {
this.gameObject.name = "Hit";
}
}
void FixedUpdate () {
if (firstTime) {
rb.AddForce (direction * bulletForce);
firstTime = false;
}
}
}
You may be right, it can be the capsule from the controller the problem, do this:
Create 2 layers named Player and Bullets.
Place the PlayerController in the layer Player.
Place the Bullet in the layer Bullets.
Go to Edit -> Project Settings -> Physics and in the Layer Collision Matrix make sure the Player layer and the Bullets layer don't collide with each other.

Categories