load Scene with Script but it turns Black - unity3d

I've done it so far that when my player dies the level is restarted and I've written everything in the script but when I try it and the scene is reloaded everything is somehow extremely dark compared to before, although all settings from the camera etc. are the same and I don't know if I'm doing something wrong or if it's a bug
my Script:
public class GameManager : MonoBehaviour
{
public GameObject enemyPrefab;
// Start is called before the first frame update
void Start()
{
GameObject player = GameObject.Find("Player");
SpawnEnemy();
}
// Update is called once per frame
void Update()
{
RestartGame();
}
void RestartGame()
{
if(GameObject.Find("Player").GetComponent<PlayerMovement>().playerHealth <= 0)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}

You need to bake your lighting inside your scene. Here are instructions on how:
Head to Window > Rendering > Lighting
Press Generate Lighting (Make sure Auto Generate is unselected)
Source

Your code has some trouble. But I'm not going to fix rotation issues. But here your working sample:
public class GameManager : MonoBehaviour {
public GameObject enemyPrefab;
// Start is called before the first frame update
void Start()
{
GameObject player = GameObject.Find("Player");
SpawnEnemy();
}
// Update is called once per frame
void Update()
{
RestartGame();
}
bool navigated = false;
void RestartGame()
{
if (!navigated)
{
if(GameObject.Find("Player").GetComponent<PlayerMovement>().playerHealth <= 0)
{
navigated = true;
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
}

Related

How to destroy instantiated button upon collision exit - Unity 3D

I am a beginner in Unity and I am currently making a simple game. I have a problem where the instantiated Button is not destroyed.
The process of the script is to instantiate a button and destroy it upon collision exit. But when I move out of the object, the object stays and it is not destroyed. i don't know if there is something wrong with the Destroy code of line.
Here is the script for the collision:
using UnityEngine;
using UnityEngine.UI;
public class InteractButtonPosition : MonoBehaviour
{
public Button UI;
private Button uiUse;
private Vector3 offset = new Vector3(0, 0.5f, 0);
// Start is called before the first frame update
void Start()
{
//uiUse = Instantiate(UI, FindObjectOfType<Canvas>().transform).GetComponent<Button>();
}
// Update is called once per frame
void Update()
{
//uiUse.transform.position = Camera.main.WorldToScreenPoint(this.transform.position + offset);
}
private void OnCollisionEnter(Collision collisionInfo)
{
if(collisionInfo.collider.name == "Player")
{
uiUse = Instantiate(UI, FindObjectOfType<Canvas>().transform).GetComponent<Button>();
uiUse.gameObject.SetActive(true);
uiUse.transform.position = Camera.main.WorldToScreenPoint(this.transform.position + offset);
}
}
private void OnCollisionExit(Collision collisionInfo)
{
if(collisionInfo.collider.name == "Player")
{
Destroy(uiUse);
}
}
}
The code does exactly what you have written, which is destroying uiUse which is a Button component. If you go and inspect your game object in the scene, you will see, that indeed, the button component has been destroyed.
What you want to do is to destroy the GameObject the button component is attached to, like: Destroy(uiUse.gameObject)

Player's jumping compromised after reloading the scene in Unity

First of all, please don't get too technical: I've only been studying Unity coding for two months and I'm not a programmer in general! I'm a total beginner! :-)
So, I'm building a game where you control a ball on a treadmill avoiding endless spawning obstacles by shifting left-right and jumping.
I set up a restart function after game over with SceneManager.LoadScene method, it works, but after reloading the jumping function gets compromised: it looks like there's an invisible wall above the player blocking its jumps. And it also looks like it's an "additive" issue: if I die and restart again, the player jumps even less, until it just doesn't jump at all. The other functions seem fine.
Any idea why that happens?
public class PlayerController : MonoBehaviour
//Jump code:
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && isOnLane)
{
Jump();
}
}
void Jump()
{
playerRb.AddForce(Vector3.up * forceMult, ForceMode.Impulse);
isOnLane = false;
}
private void OnCollisionEnter(Collision other)
{
//checks if player is touching the ground
if (other.gameObject.CompareTag("Lane"))
{
isOnLane = true;
}
}
Restart code:
public class GameManager : MonoBehaviour
//restart game by clicking Restart Button
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
Thanks!
The problem is that additive scene loading is being used when there is only a single scene. It would be good to break these up into 2 scenes:
A scene for GameManager & the Player object
A scene for the level itself which is being reloaded
This way the GameManager is not being reloaded and the player is not being reloaded. Upon reload you need to "reset" variables for the player back to 0 and move him to a starting position.
RestartGame needs some logic to reset the player and his physics.
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
playerController.playerRb.velocity = Vector3.zero;
playerController.playerRb.angularVelocity = Vector3.zero;
playerTransform.position = spawnLocation.tranform.position;
}
You probably want to unload the scene, wait for 1 frame, and then load the scene. This way variables in the scene get reset properly.
public void RestartGame()
{
SceneManager.UnloadScene(scene);
playerController.playerRb.isKinematic = true; // Try setting kinematic between scenes
StartCoroutine(RestartLoad());
}
private IEnumerator RestartLoad()
{
yield return new WaitForEndOfFrame();
// Reset the player here
SceneManager.LoadScene(scene);
playerController.playerRb.isKinematic = false; // Player can use physics again
}

How to set the position of a gameobject into initial position after grabbing ended using hand in SteamVR using Unity?

Pretty new to VR.I took a gameobject from an intial position by grabbing.When I grab a helmet and touch my body collider it hides the helmet.So next I may pick glasses and apply it to my body(Hides the GameObject).Next when I put the Incorrect Helmet the first helmet should go back to its initial position and should be seen in the scene.Similarily there are many GameObjects in the scene
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Helmet")
{
HideGameObject();
}
if (other.gameObject.tag == "Glasses")
{
HideGameObject();
}
if (other.gameObject.tag == "EarMuff")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectHelmet")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectGlasses")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectEarMuff")
{
HideGameObject();
sendPickValues.Invoke(2, 0);
}
}
//Another script to set the GameObjects position
public class BackToPosition : MonoBehaviour
{
private Vector3 initialPosition;
private Quaternion initialRotation;
GameObject prevObject;
GameObject currObject;
// Start is called before the first frame update
void Start()
{
initialPosition = transform.position;
initialRotation = transform.rotation;
}
// Update is called once per frame
void Update()
{
}
public void BackToInitialPosition()
{
Debug.Log("Entered");
transform.position = initialPosition;
transform.rotation = initialRotation;
}
}
I am not trying to set the previous grabbed object to initial position.I may select wrong helmet first and pick many other matching gameobjects and later change to correct helmet.At that time first helmet should go to initial position.
This is a script that I use in SteamVR to grab and release a boat's rudder handle but it should be usable for you too:
[RequireComponent(typeof(Interactable))]
public class HandAttacher : MonoBehaviour
{
public UnityEvent OnGrab;
public UnityEvent OnRelease;
public UnityEvent OnHandEnter;
public UnityEvent OnHandLeave;
private Interactable interactable;
void Awake()
{
interactable = GetComponent<Interactable>();
}
/// this magic method is called by hand while hovering
protected virtual void HandHoverUpdate(Hand hand)
{
GrabTypes startingGrabType = hand.GetGrabStarting();
if (interactable.attachedToHand == null && startingGrabType != GrabTypes.None)
{
hand.AttachObject(gameObject, startingGrabType, Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.ParentToHand);
OnGrab?.Invoke();
}
}
protected virtual void OnHandHoverBegin(Hand hand)
{
OnHandEnter?.Invoke();
}
protected virtual void OnHandHoverEnd(Hand hand)
{
OnHandLeave?.Invoke();
}
protected virtual void HandAttachedUpdate(Hand hand)
{
if (hand.IsGrabEnding(gameObject))
{
hand.DetachObject(gameObject);
OnRelease?.Invoke();
}
}
}
Basically it creates Unity Events that you can add Listeners to in the Editor's Inspector window, or in code.
So in your use case, I would add a listener to OnRelease, and reset the GameObject's position and rotation to whatever it was before.
I tried using BackToPosition or something similar in Update comparing the original position to its current to reset the object's position, and the object keeps resetting on a loop instead of resetting to its original position and stopping.

Control object rotation by mouse click in unity

I need help with my project in unity
I want to stop each object by clicking on it.
What I did so far:
all my objects rotate but when I click anywhere they all stop, I need them to stop only if I click on each one.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EarthScript : MonoBehaviour
{
public bool rotateObject = true;
public GameObject MyCenter;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if(rotateObject == true)
{
rotateObject = false;
}
else
{
rotateObject = true;
}
}
if(rotateObject == true)
{
Vector3 axisofRotation = new Vector3(0,1,0);
transform.RotateAround(MyCenter.transform.position,axisofRotation, 30*Time.deltaTime);
transform.Rotate(0,Time.deltaTime*30,0,Space.Self);
}
}
}
Theres two good ways to achieve this. Both ways require you to have a collider attatched to your object.
One is to raycast from the camera, through the cursor, into the scene, to check which object is currently under the cursor.
The second way is using unity's EventSystem. You will need to attach a PhysicsRaycaster on your camera, but then you get callbacks from the event system which simplifies detection (it is handled by Unity so there is less to write)
using UnityEngine;
using UnityEngine.EventSystems;
public class myClass: MonoBehaviour, IPointerClickHandler
{
public GameObject MyCenter;
public void OnPointerClick (PointerEventData e)
{
rotateObject=!rotateObject;
}
void Update()
{
if(rotateObject == true)
{
Vector3 axisofRotation = new Vector3(0,1,0);
transform.RotateAround(MyCenter.transform.position,axisofRotation, 30*Time.deltaTime);
transform.Rotate(0,Time.deltaTime*30,0,Space.Self);
}
}

OnCollisionEnter in unity won't call function

I'm a complete unity novice. I want to make a simple scene where you have three lives and you lose a live if you collide with a cube. This is my script:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Lives : MonoBehaviour {
public Transform player;
public static int lives;
public Image live1;
public Image live2;
public Image live3;
// Use this for initialization
void Start () {
lives = 3;
live1.enabled = true;
live2.enabled = true;
live3.enabled = true;
}
void Update () {
DisplayOfHearts();
}
public static void Damage() {
lives -= 1;
}
public void OnCollisionEnter(Collision col) {
if (col.gameObject.tag == "cube") {
Lives.Damage();
}
}
public void DisplayOfHearts() {
if (lives == 2) {
live3.enabled = false;
}
else if (lives == 1) {
live2.enabled = false;
}
else if (lives == 0) {
live1.enabled = false;
}
}
}
What happens is the player can't move through the cube but the amount of lives stays three. Is there something I'm missing?
The problem is you have attached the script to a wrong game object. The script and the collider must be attached to the same game object.
Unity methods inside a MonoBehaviour script (such as OnEnable, Update, FixedUpdate, Awake, Start, OnTriggerEnter, OnCollisionStay, etc..) only work for the game object which the script is attached to.
If you attach the script to another game object don't expect any of those to work. Update only works while that game object is active. OnCollisionEnter only works when a collision occurs on a collider which is attached directly to that game object. (it doesn't even work when a child has the collider instead of the actual game object where script is attached to)